[GISel] KnownFPClass ValueTracking fix handling of vectors (#143372)

This commit is contained in:
Tim Gymnich
2025-06-12 14:43:40 +02:00
committed by GitHub
parent b979311842
commit 5aed4800f3
2 changed files with 129 additions and 26 deletions

View File

@@ -1046,7 +1046,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
//
if ((Known.KnownFPClasses & fcZero) != fcNone &&
!Known.isKnownNeverSubnormal()) {
DenormalMode Mode = MF->getDenormalMode(getFltSemanticForLLT(DstTy));
DenormalMode Mode =
MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
if (Mode != DenormalMode::getIEEE())
Known.KnownFPClasses |= fcZero;
}
@@ -1108,8 +1109,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
// If the parent function flushes denormals, the canonical output cannot
// be a denormal.
LLT Ty = MRI.getType(Val);
const fltSemantics &FPType = getFltSemanticForLLT(Ty.getScalarType());
LLT Ty = MRI.getType(Val).getScalarType();
const fltSemantics &FPType = getFltSemanticForLLT(Ty);
DenormalMode DenormMode = MF->getDenormalMode(FPType);
if (DenormMode == DenormalMode::getIEEE()) {
if (KnownSrc.isKnownNever(fcPosZero))
@@ -1219,8 +1220,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
Known.knownNot(fcNan);
LLT Ty = MRI.getType(Val);
const fltSemantics &FltSem = getFltSemanticForLLT(Ty.getScalarType());
LLT Ty = MRI.getType(Val).getScalarType();
const fltSemantics &FltSem = getFltSemanticForLLT(Ty);
DenormalMode Mode = MF->getDenormalMode(FltSem);
if (KnownSrc.isKnownNeverLogicalZero(Mode))
@@ -1338,19 +1339,19 @@ void GISelValueTracking::computeKnownFPClass(Register R,
Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
// (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
if ((KnownLHS.isKnownNeverLogicalNegZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy))) ||
KnownRHS.isKnownNeverLogicalNegZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
if ((KnownLHS.isKnownNeverLogicalNegZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType()))) ||
KnownRHS.isKnownNeverLogicalNegZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType())))) &&
// Make sure output negative denormal can't flush to -0
outputDenormalIsIEEEOrPosZero(*MF, DstTy))
Known.knownNot(fcNegZero);
} else {
// Only fsub -0, +0 can return -0
if ((KnownLHS.isKnownNeverLogicalNegZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy))) ||
KnownRHS.isKnownNeverLogicalPosZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
if ((KnownLHS.isKnownNeverLogicalNegZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType()))) ||
KnownRHS.isKnownNeverLogicalPosZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType())))) &&
// Make sure output negative denormal can't flush to -0
outputDenormalIsIEEEOrPosZero(*MF, DstTy))
Known.knownNot(fcNegZero);
@@ -1396,11 +1397,11 @@ void GISelValueTracking::computeKnownFPClass(Register R,
}
if ((KnownRHS.isKnownNeverInfinity() ||
KnownLHS.isKnownNeverLogicalZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
KnownLHS.isKnownNeverLogicalZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType())))) &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverLogicalZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))))
MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))))
Known.knownNot(fcNan);
break;
@@ -1452,10 +1453,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverInfinity()) &&
((KnownLHS.isKnownNeverLogicalZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) ||
(KnownRHS.isKnownNeverLogicalZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))))) {
((KnownLHS.isKnownNeverLogicalZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType())))) ||
(KnownRHS.isKnownNeverLogicalZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType())))))) {
Known.knownNot(fcNan);
}
@@ -1468,8 +1469,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
// Inf REM x and x REM 0 produce NaN.
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
KnownLHS.isKnownNeverInfinity() &&
KnownRHS.isKnownNeverLogicalZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) {
KnownRHS.isKnownNeverLogicalZero(MF->getDenormalMode(
getFltSemanticForLLT(DstTy.getScalarType())))) {
Known.knownNot(fcNan);
}
@@ -1494,10 +1495,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
// Infinity, nan and zero propagate from source.
computeKnownFPClass(R, DemandedElts, InterestedClasses, Known, Depth + 1);
LLT DstTy = MRI.getType(Dst);
const fltSemantics &DstSem = getFltSemanticForLLT(DstTy.getScalarType());
LLT SrcTy = MRI.getType(Src);
const fltSemantics &SrcSem = getFltSemanticForLLT(SrcTy.getScalarType());
LLT DstTy = MRI.getType(Dst).getScalarType();
const fltSemantics &DstSem = getFltSemanticForLLT(DstTy);
LLT SrcTy = MRI.getType(Src).getScalarType();
const fltSemantics &SrcSem = getFltSemanticForLLT(SrcTy);
// All subnormal inputs should be in the normal range in the result type.
if (APFloat::isRepresentableAsNormalIn(SrcSem, DstSem)) {
@@ -1690,6 +1691,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
}
case TargetOpcode::COPY: {
Register Src = MI.getOperand(1).getReg();
if (!Src.isVirtual())
return;
computeKnownFPClass(Src, DemandedElts, InterestedClasses, Known, Depth + 1);
break;
}

View File

@@ -96,6 +96,104 @@ TEST_F(AArch64GISelMITest, TestFPClassCstVecNegZero) {
EXPECT_EQ(true, Known.SignBit);
}
TEST_F(AArch64GISelMITest, TestFPClassCstZeroFPExt) {
StringRef MIRString = R"(
%c0:_(s32) = G_FCONSTANT float 0.0
%ext:_(s64) = nnan ninf G_FPEXT %c0
%copy_vector:_(s64) = COPY %ext
)";
setUp(MIRString);
if (!TM)
GTEST_SKIP();
Register CopyReg = Copies[Copies.size() - 1];
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
Register SrcReg = FinalCopy->getOperand(1).getReg();
GISelValueTracking Info(*MF);
KnownFPClass Known = Info.computeKnownFPClass(SrcReg);
EXPECT_EQ(fcZero | fcNormal, Known.KnownFPClasses);
EXPECT_EQ(std::nullopt, Known.SignBit);
}
TEST_F(AArch64GISelMITest, TestFPClassCstVecZeroFPExt) {
StringRef MIRString = R"(
%c0:_(s32) = G_FCONSTANT float 0.0
%c1:_(s32) = G_FCONSTANT float 0.0
%c2:_(s32) = G_FCONSTANT float 0.0
%vector:_(<3 x s32>) = G_BUILD_VECTOR %c0, %c1, %c2
%ext:_(<3 x s64>) = nnan ninf G_FPEXT %vector
%copy_vector:_(<3 x s64>) = COPY %ext
)";
setUp(MIRString);
if (!TM)
GTEST_SKIP();
Register CopyReg = Copies[Copies.size() - 1];
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
Register SrcReg = FinalCopy->getOperand(1).getReg();
GISelValueTracking Info(*MF);
KnownFPClass Known = Info.computeKnownFPClass(SrcReg);
EXPECT_EQ(fcZero | fcNormal, Known.KnownFPClasses);
EXPECT_EQ(std::nullopt, Known.SignBit);
}
TEST_F(AArch64GISelMITest, TestFPClassCstZeroFPTrunc) {
StringRef MIRString = R"(
%c0:_(s64) = G_FCONSTANT double 0.0
%trunc:_(s32) = nnan ninf G_FPTRUNC %c0
%copy_vector:_(s32) = COPY %trunc
)";
setUp(MIRString);
if (!TM)
GTEST_SKIP();
Register CopyReg = Copies[Copies.size() - 1];
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
Register SrcReg = FinalCopy->getOperand(1).getReg();
GISelValueTracking Info(*MF);
KnownFPClass Known = Info.computeKnownFPClass(SrcReg);
EXPECT_EQ(fcZero | fcPosSubnormal | fcPosNormal, Known.KnownFPClasses);
EXPECT_EQ(false, Known.SignBit);
}
TEST_F(AArch64GISelMITest, TestFPClassCstVecZeroFPTrunc) {
StringRef MIRString = R"(
%c0:_(s64) = G_FCONSTANT double 0.0
%c1:_(s64) = G_FCONSTANT double 0.0
%c2:_(s64) = G_FCONSTANT double 0.0
%vector:_(<3 x s64>) = G_BUILD_VECTOR %c0, %c1, %c2
%trunc:_(<3 x s32>) = nnan ninf G_FPTRUNC %vector
%copy_vector:_(<3 x s32>) = COPY %trunc
)";
setUp(MIRString);
if (!TM)
GTEST_SKIP();
Register CopyReg = Copies[Copies.size() - 1];
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
Register SrcReg = FinalCopy->getOperand(1).getReg();
GISelValueTracking Info(*MF);
KnownFPClass Known = Info.computeKnownFPClass(SrcReg);
EXPECT_EQ(fcZero | fcPosSubnormal | fcPosNormal, Known.KnownFPClasses);
EXPECT_EQ(false, Known.SignBit);
}
TEST_F(AArch64GISelMITest, TestFPClassSelectPos0) {
StringRef MIRString = R"(
%ptr:_(p0) = G_IMPLICIT_DEF