-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[GISel] KnownFPClass ValueTracking fix handling of vectors #143372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Member
tgymnich
commented
Jun 9, 2025
- fix handling of vectors
- abort analysis on physical registers
- add some more tests
@llvm/pr-subscribers-llvm-globalisel Author: Tim Gymnich (tgymnich) Changes
Full diff: https://github.com/llvm/llvm-project/pull/143372.diff 2 Files Affected:
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
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
arsenm
reviewed
Jun 9, 2025
gentle ping @arsenm |
950aef6
to
7c2c03d
Compare
arsenm
approved these changes
Jun 12, 2025
tomtor
pushed a commit
to tomtor/llvm-project
that referenced
this pull request
Jun 14, 2025
akuhlens
pushed a commit
to akuhlens/llvm-project
that referenced
this pull request
Jun 24, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.