diff options
author | Nikita Popov <npopov@redhat.com> | 2023-06-23 12:15:02 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2023-06-23 12:17:48 +0200 |
commit | 7cf567d46121f4aa8f659554b5e8584cd0fac056 (patch) | |
tree | 901efb30a2c2bb9366264d1e6aacbe575a5157bc /llvm/lib/IR/ConstantRange.cpp | |
parent | 04a8070b46da2bcd47d0a134922409dc16bb9d57 (diff) | |
download | llvm-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.cpp | 14 |
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 |