[GISel] KnownFPClass ValueTracking fix handling of vectors (#143372)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user