[llvm] 7cf567d - [ConstantRange] Calculate precise range for multiply by -1
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 23 03:17:55 PDT 2023
Author: Nikita Popov
Date: 2023-06-23T12:17:48+02:00
New Revision: 7cf567d46121f4aa8f659554b5e8584cd0fac056
URL: https://github.com/llvm/llvm-project/commit/7cf567d46121f4aa8f659554b5e8584cd0fac056
DIFF: https://github.com/llvm/llvm-project/commit/7cf567d46121f4aa8f659554b5e8584cd0fac056.diff
LOG: [ConstantRange] Calculate precise range for multiply by -1
These are pretty common in SCEV, so make sure we get a precise
result by mapping to the sub() operation.
Added:
Modified:
llvm/lib/IR/ConstantRange.cpp
llvm/unittests/IR/ConstantRangeTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 74cc09705f883..e9344a8815c08 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -1095,6 +1095,20 @@ ConstantRange::multiply(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())
return getEmpty();
+ if (const APInt *C = getSingleElement()) {
+ if (C->isOne())
+ return Other;
+ if (C->isAllOnes())
+ return ConstantRange(APInt::getZero(getBitWidth())).sub(Other);
+ }
+
+ if (const APInt *C = Other.getSingleElement()) {
+ if (C->isOne())
+ return *this;
+ if (C->isAllOnes())
+ return ConstantRange(APInt::getZero(getBitWidth())).sub(*this);
+ }
+
// Multiplication is signedness-independent. However
diff erent ranges can be
// obtained depending on how the input ranges are treated. These
diff erent
// ranges are all conservatively correct, but one might be better than the
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp
index f4052838c434c..38d1119e7f85b 100644
--- a/llvm/unittests/IR/ConstantRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantRangeTest.cpp
@@ -997,6 +997,26 @@ TEST_F(ConstantRangeTest, Multiply) {
EXPECT_EQ(ConstantRange(APInt(8, -2)).multiply(
ConstantRange(APInt(8, 0), APInt(8, 2))),
ConstantRange(APInt(8, -2), APInt(8, 1)));
+
+ // Multiplication by -1 should give precise results.
+ EXPECT_EQ(ConstantRange(APInt(8, 3), APInt(8, -11))
+ .multiply(ConstantRange(APInt(8, -1))),
+ ConstantRange(APInt(8, 12), APInt(8, -2)));
+ EXPECT_EQ(ConstantRange(APInt(8, -1))
+ .multiply(ConstantRange(APInt(8, 3), APInt(8, -11))),
+ ConstantRange(APInt(8, 12), APInt(8, -2)));
+
+ TestBinaryOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.multiply(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1 * N2;
+ },
+ PreferSmallest,
+ [](const ConstantRange &, const ConstantRange &) {
+ return false; // Check correctness only.
+ });
}
TEST_F(ConstantRangeTest, smul_fast) {
More information about the llvm-commits
mailing list