From a3a253d3c7780977077dd46493917b1949c0166d Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 8 Oct 2024 15:55:10 +0800 Subject: [PATCH] [ConstantFPRange] Implement `ConstantFPRange::makeExactFCmpRegion` (#111490) Note: The current implementation doesn't return optimal result for `fcmp one/une x, +/-inf` since we don't handle this case in https://github.com/llvm/llvm-project/pull/110891. Maybe we can make it optimal after seeing some real-world cases. --- llvm/lib/IR/ConstantFPRange.cpp | 5 ++++- llvm/unittests/IR/ConstantFPRangeTest.cpp | 24 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/llvm/lib/IR/ConstantFPRange.cpp b/llvm/lib/IR/ConstantFPRange.cpp index d3c89daa9ce148..75091881285248 100644 --- a/llvm/lib/IR/ConstantFPRange.cpp +++ b/llvm/lib/IR/ConstantFPRange.cpp @@ -268,7 +268,10 @@ ConstantFPRange::makeSatisfyingFCmpRegion(FCmpInst::Predicate Pred, std::optional ConstantFPRange::makeExactFCmpRegion(FCmpInst::Predicate Pred, const APFloat &Other) { - return std::nullopt; + if ((Pred == FCmpInst::FCMP_UNE || Pred == FCmpInst::FCMP_ONE) && + !Other.isNaN()) + return std::nullopt; + return makeSatisfyingFCmpRegion(Pred, ConstantFPRange(Other)); } bool ConstantFPRange::fcmp(FCmpInst::Predicate Pred, diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp index 3ce64c64447e21..255f62d77b748d 100644 --- a/llvm/unittests/IR/ConstantFPRangeTest.cpp +++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp @@ -743,4 +743,28 @@ TEST_F(ConstantFPRangeTest, fcmp) { } } +TEST_F(ConstantFPRangeTest, makeExactFCmpRegion) { + for (auto Pred : FCmpInst::predicates()) { + EnumerateValuesInConstantFPRange( + ConstantFPRange::getFull(APFloat::Float8E4M3()), + [Pred](const APFloat &V) { + std::optional Res = + ConstantFPRange::makeExactFCmpRegion(Pred, V); + ConstantFPRange Allowed = + ConstantFPRange::makeAllowedFCmpRegion(Pred, ConstantFPRange(V)); + ConstantFPRange Satisfying = + ConstantFPRange::makeSatisfyingFCmpRegion(Pred, + ConstantFPRange(V)); + if (Allowed == Satisfying) + EXPECT_EQ(Res, Allowed) << "Wrong result for makeExactFCmpRegion(" + << Pred << ", " << V << ")."; + else + EXPECT_FALSE(Res.has_value()) + << "Wrong result for makeExactFCmpRegion(" << Pred << ", " << V + << ")."; + }, + /*IgnoreNaNPayload=*/true); + } +} + } // anonymous namespace