[llvm] [GISel] KnownFPClass ValueTracking fix handling of vectors (PR #143372)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 04:57:02 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Tim Gymnich (tgymnich)
<details>
<summary>Changes</summary>
- fix handling of vectors
- abort analysis on physical registers
- add some more tests
---
Full diff: https://github.com/llvm/llvm-project/pull/143372.diff
2 Files Affected:
- (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+24-18)
- (modified) llvm/unittests/CodeGen/GlobalISel/KnownFPClassTest.cpp (+98)
``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 6650ad25bed04..10d6a3af78720 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -715,6 +715,9 @@ static bool outputDenormalIsIEEEOrPosZero(const MachineFunction &MF, LLT Ty) {
void GISelValueTracking::computeKnownFPClass(Register R, KnownFPClass &Known,
FPClassTest InterestedClasses,
unsigned Depth) {
+ if (!R.isVirtual())
+ return;
+
LLT Ty = MRI.getType(R);
APInt DemandedElts =
Ty.isFixedVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1);
@@ -758,6 +761,9 @@ void GISelValueTracking::computeKnownFPClass(Register R,
assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ if (!R.isVirtual())
+ return;
+
MachineInstr &MI = *MRI.getVRegDef(R);
unsigned Opcode = MI.getOpcode();
LLT DstTy = MRI.getType(R);
@@ -1046,7 +1052,7 @@ 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 +1114,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 +1225,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))
@@ -1339,18 +1345,18 @@ void GISelValueTracking::computeKnownFPClass(Register R,
// (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
if ((KnownLHS.isKnownNeverLogicalNegZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy))) ||
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()))) ||
KnownRHS.isKnownNeverLogicalNegZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
+ 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))) ||
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()))) ||
KnownRHS.isKnownNeverLogicalPosZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) &&
// Make sure output negative denormal can't flush to -0
outputDenormalIsIEEEOrPosZero(*MF, DstTy))
Known.knownNot(fcNegZero);
@@ -1397,10 +1403,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if ((KnownRHS.isKnownNeverInfinity() ||
KnownLHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) &&
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))))
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))))
Known.knownNot(fcNan);
break;
@@ -1453,9 +1459,9 @@ void GISelValueTracking::computeKnownFPClass(Register R,
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverInfinity()) &&
((KnownLHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) ||
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) ||
(KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))))) {
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))))) {
Known.knownNot(fcNan);
}
@@ -1469,7 +1475,7 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
KnownLHS.isKnownNeverInfinity() &&
KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy)))) {
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) {
Known.knownNot(fcNan);
}
@@ -1494,10 +1500,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)) {
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/143372
More information about the llvm-commits
mailing list