[llvm] [GISel] KnownFPClass ValueTracking fix handling of vectors (PR #143372)
Tim Gymnich via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 05:05:15 PDT 2025
https://github.com/tgymnich updated https://github.com/llvm/llvm-project/pull/143372
>From 57f5935e18903989f830d4bc9481c74c0ababca4 Mon Sep 17 00:00:00 2001
From: Tim Gymnich <tim at gymni.ch>
Date: Fri, 23 May 2025 14:47:18 +0000
Subject: [PATCH 1/3] guard against non-virtual registers
---
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 42 +++++++++++--------
1 file changed, 24 insertions(+), 18 deletions(-)
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)) {
>From 29c524319893a82280fadad7d34660ba4b40ca8f Mon Sep 17 00:00:00 2001
From: Tim Gymnich <tim at gymni.ch>
Date: Mon, 9 Jun 2025 11:54:04 +0000
Subject: [PATCH 2/3] test fpext / fptrunc of scalars and vectors
---
.../CodeGen/GlobalISel/KnownFPClassTest.cpp | 98 +++++++++++++++++++
1 file changed, 98 insertions(+)
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
>From 950aef6b9d05459bffb1b9e1c70fc4aeeff3f535 Mon Sep 17 00:00:00 2001
From: Tim Gymnich <tim at gymni.ch>
Date: Mon, 9 Jun 2025 12:04:54 +0000
Subject: [PATCH 3/3] move register kind check to COPY
---
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 45 +++++++++----------
1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 10d6a3af78720..1286af864fb3f 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -715,9 +715,6 @@ 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);
@@ -761,9 +758,6 @@ 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);
@@ -1052,7 +1046,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
//
if ((Known.KnownFPClasses & fcZero) != fcNone &&
!Known.isKnownNeverSubnormal()) {
- DenormalMode Mode = MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
+ DenormalMode Mode =
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
if (Mode != DenormalMode::getIEEE())
Known.KnownFPClasses |= fcZero;
}
@@ -1344,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.getScalarType()))) ||
- KnownRHS.isKnownNeverLogicalNegZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) &&
+ 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.getScalarType()))) ||
- KnownRHS.isKnownNeverLogicalPosZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) &&
+ 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);
@@ -1402,8 +1397,8 @@ void GISelValueTracking::computeKnownFPClass(Register R,
}
if ((KnownRHS.isKnownNeverInfinity() ||
- KnownLHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) &&
+ KnownLHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverLogicalZero(
MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))))
@@ -1458,10 +1453,10 @@ void GISelValueTracking::computeKnownFPClass(Register R,
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
(KnownLHS.isKnownNeverInfinity() ||
KnownRHS.isKnownNeverInfinity()) &&
- ((KnownLHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))) ||
- (KnownRHS.isKnownNeverLogicalZero(
- MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType())))))) {
+ ((KnownLHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) ||
+ (KnownRHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))))) {
Known.knownNot(fcNan);
}
@@ -1474,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.getScalarType())))) {
+ KnownRHS.isKnownNeverLogicalZero(MF->getDenormalMode(
+ getFltSemanticForLLT(DstTy.getScalarType())))) {
Known.knownNot(fcNan);
}
@@ -1696,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;
}
More information about the llvm-commits
mailing list