-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ConstantFPRange] Add support for fneg/fabs #162690
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
Conversation
@llvm/pr-subscribers-llvm-ir Author: Yingwei Zheng (dtcxzyw) ChangesThis patch adds support for fneg/fabs operations. For other bit manipulation operations (select/copysign), we don't need new APIs. Full diff: https://github.com/llvm/llvm-project/pull/162690.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/ConstantFPRange.h b/llvm/include/llvm/IR/ConstantFPRange.h
index 930c6f98c033f..4a54caa87eaca 100644
--- a/llvm/include/llvm/IR/ConstantFPRange.h
+++ b/llvm/include/llvm/IR/ConstantFPRange.h
@@ -200,6 +200,12 @@ class [[nodiscard]] ConstantFPRange {
/// with another range. The resultant range is guaranteed to include the
/// elements of both sets, but may contain more.
LLVM_ABI ConstantFPRange unionWith(const ConstantFPRange &CR) const;
+
+ /// Calculate absolute value range.
+ LLVM_ABI ConstantFPRange abs() const;
+
+ /// Calculate range of negated values.
+ LLVM_ABI ConstantFPRange negate() const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const ConstantFPRange &CR) {
diff --git a/llvm/lib/IR/ConstantFPRange.cpp b/llvm/lib/IR/ConstantFPRange.cpp
index 7509188128524..969af9798bf06 100644
--- a/llvm/lib/IR/ConstantFPRange.cpp
+++ b/llvm/lib/IR/ConstantFPRange.cpp
@@ -391,3 +391,23 @@ ConstantFPRange ConstantFPRange::unionWith(const ConstantFPRange &CR) const {
return ConstantFPRange(minnum(Lower, CR.Lower), maxnum(Upper, CR.Upper),
MayBeQNaN | CR.MayBeQNaN, MayBeSNaN | CR.MayBeSNaN);
}
+
+ConstantFPRange ConstantFPRange::abs() const {
+ if (isEmptySet())
+ return *this;
+ // Check if the range is all non-negative or all non-positive.
+ if (Lower.isNegative() == Upper.isNegative()) {
+ if (Lower.isNegative())
+ return negate();
+ return *this;
+ }
+ // The range contains both positive and negative values.
+ APFloat NewLower = APFloat::getZero(getSemantics());
+ APFloat NewUpper = maxnum(-Lower, Upper);
+ return ConstantFPRange(std::move(NewLower), std::move(NewUpper), MayBeQNaN,
+ MayBeSNaN);
+}
+
+ConstantFPRange ConstantFPRange::negate() const {
+ return ConstantFPRange(-Upper, -Lower, MayBeQNaN, MayBeSNaN);
+}
diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp
index 255f62d77b748..1384b68707577 100644
--- a/llvm/unittests/IR/ConstantFPRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp
@@ -767,4 +767,37 @@ TEST_F(ConstantFPRangeTest, makeExactFCmpRegion) {
}
}
+TEST_F(ConstantFPRangeTest, abs) {
+ EXPECT_EQ(Full.abs(),
+ ConstantFPRange(APFloat::getZero(Sem, /*Negative=*/false),
+ APFloat::getInf(Sem, /*Negative=*/false),
+ /*MayBeQNaN=*/true,
+ /*MayBeSNaN=*/true));
+ EXPECT_EQ(Empty.abs(), Empty);
+ EXPECT_EQ(Zero.abs(), PosZero);
+ EXPECT_EQ(PosInf.abs(), PosInf);
+ EXPECT_EQ(NegInf.abs(), PosInf);
+ EXPECT_EQ(Some.abs(), SomePos);
+ EXPECT_EQ(SomeNeg.abs(), SomePos);
+ EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(-2.0), APFloat(3.0)).abs(),
+ ConstantFPRange::getNonNaN(APFloat(0.0), APFloat(3.0)));
+ EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(-3.0), APFloat(2.0)).abs(),
+ ConstantFPRange::getNonNaN(APFloat(0.0), APFloat(3.0)));
+}
+
+TEST_F(ConstantFPRangeTest, negate) {
+ EXPECT_EQ(Full.negate(), Full);
+ EXPECT_EQ(Empty.negate(), Empty);
+ EXPECT_EQ(Zero.negate(), Zero);
+ EXPECT_EQ(PosInf.negate(), NegInf);
+ EXPECT_EQ(NegInf.negate(), PosInf);
+ EXPECT_EQ(Some.negate(), Some);
+ EXPECT_EQ(SomePos.negate(), SomeNeg);
+ EXPECT_EQ(SomeNeg.negate(), SomePos);
+ EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(-2.0), APFloat(3.0)).negate(),
+ ConstantFPRange::getNonNaN(APFloat(-3.0), APFloat(2.0)));
+ EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(-3.0), APFloat(2.0)).negate(),
+ ConstantFPRange::getNonNaN(APFloat(-2.0), APFloat(3.0)));
+}
+
} // anonymous namespace
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/138/builds/20228 Here is the relevant piece of the build log for the reference
|
if (Lower.isNegative() == Upper.isNegative()) { | ||
if (Lower.isNegative()) | ||
return negate(); | ||
return *this; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simpler:
if (Lower.isNegative() == Upper.isNegative()) { | |
if (Lower.isNegative()) | |
return negate(); | |
return *this; | |
} | |
if (!Lower.isNegative()) | |
return *this; | |
if (Upper.isNegative()) | |
return negate(); |
This patch adds support for fneg/fabs operations. For other bit manipulation operations (select/copysign), we don't need new APIs.