diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2023-04-09 07:20:25 -0400 |
---|---|---|
committer | Matt Arsenault <arsenm2@gmail.com> | 2023-04-19 20:11:33 -0400 |
commit | f6d79ad9eba4815ed4381106333e0e285f89ad02 (patch) | |
tree | 8e5caefca9231876cf20e7914f87453f29c804a4 | |
parent | 66a06e285b83063ff96ce6ad21e60de4acaa884d (diff) | |
download | llvm-f6d79ad9eba4815ed4381106333e0e285f89ad02.zip llvm-f6d79ad9eba4815ed4381106333e0e285f89ad02.tar.gz llvm-f6d79ad9eba4815ed4381106333e0e285f89ad02.tar.bz2 |
ValueTracking: Implement computeKnownFPClass for fdiv for nan handling
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 34 | ||||
-rw-r--r-- | llvm/test/Transforms/Attributor/nofpclass-fdiv.ll | 30 |
2 files changed, 49 insertions, 15 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 058abc5..db16c0c 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4628,6 +4628,40 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, break; } + case Instruction::FDiv: { + const bool WantNan = (InterestedClasses & fcNan) != fcNone; + if (!WantNan) + break; + + // TODO: FRem + KnownFPClass KnownLHS, KnownRHS; + + computeKnownFPClass(Op->getOperand(1), DemandedElts, + fcNan | fcInf | fcZero | fcSubnormal, KnownRHS, + Depth + 1, Q, TLI); + + bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN() || + KnownRHS.isKnownNeverInfinity() || + KnownRHS.isKnownNeverZero(); + + if (KnowSomethingUseful) { + computeKnownFPClass(Op->getOperand(0), DemandedElts, + fcNan | fcInf | fcZero, KnownLHS, Depth + 1, Q, TLI); + } + + const Function *F = cast<Instruction>(Op)->getFunction(); + + // Only 0/0, Inf/Inf, Inf REM x and x REM 0 produce NaN. + // TODO: Track sign bit. + if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() && + (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) && + (KnownLHS.isKnownNeverLogicalZero(*F, Op->getType()) || + KnownRHS.isKnownNeverLogicalZero(*F, Op->getType()))) { + Known.knownNot(fcNan); + } + + break; + } case Instruction::FPTrunc: { if ((InterestedClasses & fcNan) == fcNone) break; diff --git a/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll b/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll index 8a31181..999a236 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll @@ -52,7 +52,7 @@ define float @ret_fdiv_ieee_all__nonan_noinf_nozero(float %arg0, float nofpclass } define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan(float nofpclass(nan inf zero) %arg0, float nofpclass(nan) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero__nonan ; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -62,7 +62,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan(float nofpclass(nan inf ze } define float @ret_fdiv_ieee_nonan__nonan_noinf_nozero(float nofpclass(nan) %arg0, float nofpclass(nan inf zero) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan__nonan_noinf_nozero +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan__nonan_noinf_nozero ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -72,7 +72,7 @@ define float @ret_fdiv_ieee_nonan__nonan_noinf_nozero(float nofpclass(nan) %arg0 } define float @ret_fdiv_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero) %arg0, float nofpclass(nan inf) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_nozero__nonan_noinf +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_nozero__nonan_noinf ; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -82,7 +82,7 @@ define float @ret_fdiv_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero) } define float @ret_fdiv_ieee_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan zero) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf__nonan_nozero +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf__nonan_nozero ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -112,7 +112,7 @@ define float @ret_fdiv_daz_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %a } define float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf(float nofpclass(nan zero sub) %arg0, float nofpclass(nan inf) %arg1) #1 { -; CHECK-LABEL: define float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf ; CHECK-SAME: (float nofpclass(nan zero sub) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -122,7 +122,7 @@ define float @ret_fdiv_daz_nonan_nozero_nosub__nonan_noinf(float nofpclass(nan z } define float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub(float nofpclass(nan inf) %arg0, float nofpclass(nan zero sub) %arg1) #1 { -; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero sub) [[ARG1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -142,7 +142,7 @@ define float @ret_fdiv_ieee_nonan_noinf__nonan_noinf(float nofpclass(nan) %arg0, } define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero ; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -192,7 +192,7 @@ define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noinf(float nofpclass } define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf ; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -202,7 +202,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_noinf(float nofpclas } define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan inf zero) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -232,7 +232,7 @@ define float @ret_fdiv_ieee_nonan_noinf_noposzero__nonan_noinf_noinf(float nofpc } define float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #0 { -; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub ; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -243,7 +243,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(f ; Denormal mode doesn't matter because sources are nofpclass(sub) define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #1 { -; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub ; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -253,7 +253,7 @@ define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(fl } define float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #2 { -; CHECK-LABEL: define float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub ; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -263,7 +263,7 @@ define float @ret_fdiv_dapz_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(f } define float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero sub) %arg1) #3 { -; CHECK-LABEL: define float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosub ; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -274,7 +274,7 @@ define float @ret_fdiv_dynamic_nonan_noinf_nozero_nosub__nonan_noinf_nozero_nosu ; Missing no-subnormal on lhs define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero sub) %arg1) #1 { -; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub ; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero sub) [[ARG1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] @@ -285,7 +285,7 @@ define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero_nosub(float no ; Missing no-subnormal on lhs define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero(float nofpclass(nan inf zero sub) %arg0, float nofpclass(nan inf zero) %arg1) #1 { -; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero +; CHECK-LABEL: define nofpclass(nan) float @ret_fdiv_daz_nonan_noinf_nozero_nosub__nonan_noinf_nozero ; CHECK-SAME: (float nofpclass(nan inf zero sub) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]] ; CHECK-NEXT: ret float [[FDIV]] |