[llvm] b39deda - ValueTracking: Handle nofpclass in computeKnownFPClass
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 16 20:14:49 PDT 2023
Author: Matt Arsenault
Date: 2023-03-16T23:14:40-04:00
New Revision: b39deda3e1b3617650964de8a134ca828c1a2451
URL: https://github.com/llvm/llvm-project/commit/b39deda3e1b3617650964de8a134ca828c1a2451
DIFF: https://github.com/llvm/llvm-project/commit/b39deda3e1b3617650964de8a134ca828c1a2451.diff
LOG: ValueTracking: Handle nofpclass in computeKnownFPClass
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/unittests/Analysis/ValueTrackingTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 970218ac770d..affb70968591 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4148,26 +4148,31 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
return;
}
- const Operator *Op = dyn_cast<Operator>(V);
- if (!Op)
- return;
-
FPClassTest KnownNotFromFlags = fcNone;
- if (const FPMathOperator *FPOp = dyn_cast<FPMathOperator>(Op)) {
+ if (const auto *CB = dyn_cast<CallBase>(V))
+ KnownNotFromFlags |= CB->getRetNoFPClass();
+ else if (const auto *Arg = dyn_cast<Argument>(V))
+ KnownNotFromFlags |= Arg->getNoFPClass();
+
+ const Operator *Op = dyn_cast<Operator>(V);
+ if (const FPMathOperator *FPOp = dyn_cast_or_null<FPMathOperator>(Op)) {
if (FPOp->hasNoNaNs())
KnownNotFromFlags |= fcNan;
if (FPOp->hasNoInfs())
KnownNotFromFlags |= fcInf;
-
- // We no longer need to find out about these bits from inputs if we can
- // assume this from flags.
- InterestedClasses &= ~KnownNotFromFlags;
}
+ // We no longer need to find out about these bits from inputs if we can
+ // assume this from flags/attributes.
+ InterestedClasses &= ~KnownNotFromFlags;
+
auto ClearClassesFromFlags = make_scope_exit([=, &Known] {
Known.knownNot(KnownNotFromFlags);
});
+ if (!Op)
+ return;
+
// All recursive calls that increase depth must come after this.
if (Depth == MaxAnalysisRecursionDepth)
return;
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 02116271e5ee..4e6b1ef0c93b 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1351,6 +1351,83 @@ TEST_F(ComputeKnownFPClassTest, SelectNNaNNInf) {
expectKnownFPClass(~(fcNan | fcInf), std::nullopt);
}
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgUnionAll) {
+ parseAssembly(
+ "define float @test(i1 %cond, float nofpclass(snan ninf nsub pzero pnorm) %arg0, float nofpclass(qnan nnorm nzero psub pinf) %arg1) {\n"
+ " %A = select i1 %cond, float %arg0, float %arg1"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(fcAllFlags, std::nullopt);
+}
+
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoNan) {
+ parseAssembly(
+ "define float @test(i1 %cond, float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {\n"
+ " %A = select i1 %cond, float %arg0, float %arg1"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~fcNan, std::nullopt);
+}
+
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoPInf) {
+ parseAssembly(
+ "define float @test(i1 %cond, float nofpclass(inf) %arg0, float nofpclass(pinf) %arg1) {\n"
+ " %A = select i1 %cond, float %arg0, float %arg1"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~fcPosInf, std::nullopt);
+}
+
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoNInf) {
+ parseAssembly(
+ "define float @test(i1 %cond, float nofpclass(ninf) %arg0, float nofpclass(inf) %arg1) {\n"
+ " %A = select i1 %cond, float %arg0, float %arg1"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~fcNegInf, std::nullopt);
+}
+
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoNan) {
+ parseAssembly(
+ "declare float @func()\n"
+ "define float @test() {\n"
+ " %A = call nofpclass(nan) float @func()\n"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~fcNan, std::nullopt);
+}
+
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoZeros) {
+ parseAssembly(
+ "declare float @func()\n"
+ "define float @test() {\n"
+ " %A = call nofpclass(zero) float @func()\n"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~fcZero, std::nullopt);
+}
+
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassDeclarationNoNan) {
+ parseAssembly(
+ "declare nofpclass(nan) float @no_nans()\n"
+ "define float @test() {\n"
+ " %A = call float @no_nans()\n"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~fcNan, std::nullopt);
+}
+
+// Check nofpclass + ninf works on a callsite
+TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoZerosNInfFlags) {
+ parseAssembly(
+ "declare float @func()\n"
+ "define float @test() {\n"
+ " %A = call ninf nofpclass(zero) float @func()\n"
+ " ret float %A\n"
+ "}\n");
+ expectKnownFPClass(~(fcZero | fcInf), std::nullopt);
+}
+
TEST_F(ComputeKnownFPClassTest, FNegNInf) {
parseAssembly(
"define float @test(float %arg) {\n"
More information about the llvm-commits
mailing list