diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index 6650ad25bed04..1286af864fb3f 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -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; } diff --git a/llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp index 6ee571804e69f..040f0cfc92076 100644 --- a/llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp @@ -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