aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-06-23 12:15:02 +0200
committerNikita Popov <npopov@redhat.com>2023-06-23 12:17:48 +0200
commit7cf567d46121f4aa8f659554b5e8584cd0fac056 (patch)
tree901efb30a2c2bb9366264d1e6aacbe575a5157bc /llvm/lib/IR/ConstantRange.cpp
parent04a8070b46da2bcd47d0a134922409dc16bb9d57 (diff)
downloadllvm-7cf567d46121f4aa8f659554b5e8584cd0fac056.zip
llvm-7cf567d46121f4aa8f659554b5e8584cd0fac056.tar.gz
llvm-7cf567d46121f4aa8f659554b5e8584cd0fac056.tar.bz2
[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.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 74cc097..e9344a8 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 different ranges can be
// obtained depending on how the input ranges are treated. These different
// ranges are all conservatively correct, but one might be better than the