[llvm] [ConstantFPRange][UnitTest] Ignore NaN payloads when enumerating values in a range (PR #111083)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 3 19:30:31 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
NaN payloads can be ignored because they are unrelated with ConstantFPRange (except the conversion from ConstantFPRange to KnownBits). This patch just enumerates `+/-[S/Q]NaN` to avoid enumerating 32 NaN values in all ranges which contain NaN values.
Addresses comment https://github.com/llvm/llvm-project/pull/110082#issuecomment-2392037204.
---
Full diff: https://github.com/llvm/llvm-project/pull/111083.diff
1 Files Affected:
- (modified) llvm/unittests/IR/ConstantFPRangeTest.cpp (+85-24)
``````````diff
diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp
index 17a08207fe1ba0..158d08f9b77a0a 100644
--- a/llvm/unittests/IR/ConstantFPRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp
@@ -150,26 +150,80 @@ static void EnumerateTwoInterestingConstantFPRanges(Fn TestFn,
template <typename Fn>
static void EnumerateValuesInConstantFPRange(const ConstantFPRange &CR,
- Fn TestFn) {
+ Fn TestFn, bool IgnoreNaNPayload) {
const fltSemantics &Sem = CR.getSemantics();
- unsigned Bits = APFloat::semanticsSizeInBits(Sem);
- assert(Bits < 32 && "Too many bits");
- for (unsigned I = 0, E = (1U << Bits) - 1; I != E; ++I) {
- APFloat V(Sem, APInt(Bits, I));
- if (CR.contains(V))
- TestFn(V);
+ if (IgnoreNaNPayload) {
+ if (CR.containsSNaN()) {
+ TestFn(APFloat::getSNaN(Sem, false));
+ TestFn(APFloat::getSNaN(Sem, true));
+ }
+ if (CR.containsQNaN()) {
+ TestFn(APFloat::getQNaN(Sem, false));
+ TestFn(APFloat::getQNaN(Sem, true));
+ }
+ if (CR.isNaNOnly())
+ return;
+ APFloat Lower = CR.getLower();
+ const APFloat &Upper = CR.getUpper();
+ auto Next = [&](APFloat &V) {
+ if (V.bitwiseIsEqual(Upper))
+ return false;
+ strictNext(V);
+ return true;
+ };
+ do
+ TestFn(Lower);
+ while (Next(Lower));
+ } else {
+ unsigned Bits = APFloat::semanticsSizeInBits(Sem);
+ assert(Bits < 32 && "Too many bits");
+ for (unsigned I = 0, E = (1U << Bits) - 1; I != E; ++I) {
+ APFloat V(Sem, APInt(Bits, I));
+ if (CR.contains(V))
+ TestFn(V);
+ }
}
}
template <typename Fn>
-static bool AnyOfValueInConstantFPRange(const ConstantFPRange &CR, Fn TestFn) {
+static bool AnyOfValueInConstantFPRange(const ConstantFPRange &CR, Fn TestFn,
+ bool IgnoreNaNPayload) {
const fltSemantics &Sem = CR.getSemantics();
- unsigned Bits = APFloat::semanticsSizeInBits(Sem);
- assert(Bits < 32 && "Too many bits");
- for (unsigned I = 0, E = (1U << Bits) - 1; I != E; ++I) {
- APFloat V(Sem, APInt(Bits, I));
- if (CR.contains(V) && TestFn(V))
+ if (IgnoreNaNPayload) {
+ if (CR.containsSNaN()) {
+ if (TestFn(APFloat::getSNaN(Sem, false)))
+ return true;
+ if (TestFn(APFloat::getSNaN(Sem, true)))
+ return true;
+ }
+ if (CR.containsQNaN()) {
+ if (TestFn(APFloat::getQNaN(Sem, false)))
+ return true;
+ if (TestFn(APFloat::getQNaN(Sem, true)))
+ return true;
+ }
+ if (CR.isNaNOnly())
+ return false;
+ APFloat Lower = CR.getLower();
+ const APFloat &Upper = CR.getUpper();
+ auto Next = [&](APFloat &V) {
+ if (V.bitwiseIsEqual(Upper))
+ return false;
+ strictNext(V);
return true;
+ };
+ do {
+ if (TestFn(Lower))
+ return true;
+ } while (Next(Lower));
+ } else {
+ unsigned Bits = APFloat::semanticsSizeInBits(Sem);
+ assert(Bits < 32 && "Too many bits");
+ for (unsigned I = 0, E = (1U << Bits) - 1; I != E; ++I) {
+ APFloat V(Sem, APInt(Bits, I));
+ if (CR.contains(V) && TestFn(V))
+ return true;
+ }
}
return false;
}
@@ -385,13 +439,16 @@ TEST_F(ConstantFPRangeTest, FPClassify) {
[](const ConstantFPRange &CR) {
unsigned Mask = fcNone;
bool HasPos = false, HasNeg = false;
- EnumerateValuesInConstantFPRange(CR, [&](const APFloat &V) {
- Mask |= V.classify();
- if (V.isNegative())
- HasNeg = true;
- else
- HasPos = true;
- });
+ EnumerateValuesInConstantFPRange(
+ CR,
+ [&](const APFloat &V) {
+ Mask |= V.classify();
+ if (V.isNegative())
+ HasNeg = true;
+ else
+ HasPos = true;
+ },
+ /*IgnoreNaNPayload=*/true);
std::optional<bool> SignBit = std::nullopt;
if (HasPos != HasNeg)
@@ -453,11 +510,15 @@ TEST_F(ConstantFPRangeTest, makeAllowedFCmpRegion) {
EnumerateValuesInConstantFPRange(
ConstantFPRange::getFull(CR.getSemantics()),
[&](const APFloat &V) {
- if (AnyOfValueInConstantFPRange(CR, [&](const APFloat &U) {
- return FCmpInst::compare(V, U, Pred);
- }))
+ if (AnyOfValueInConstantFPRange(
+ CR,
+ [&](const APFloat &U) {
+ return FCmpInst::compare(V, U, Pred);
+ },
+ /*IgnoreNaNPayload=*/true))
Optimal = Optimal.unionWith(ConstantFPRange(V));
- });
+ },
+ /*IgnoreNaNPayload=*/true);
EXPECT_TRUE(Res.contains(Optimal))
<< "Wrong result for makeAllowedFCmpRegion(" << Pred << ", " << CR
``````````
</details>
https://github.com/llvm/llvm-project/pull/111083
More information about the llvm-commits
mailing list