aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-08-29 14:43:44 +0200
committerNikita Popov <npopov@redhat.com>2023-08-29 14:48:33 +0200
commit4dd392fcd7847ef73233cd2f24623064ebc90a16 (patch)
tree37c38496005e88e2e52deb516a8c401bb6e89783 /llvm/lib/IR/ConstantRange.cpp
parent498b59e01133bed16c72dd939a9daa8ae1f359e4 (diff)
downloadllvm-4dd392fcd7847ef73233cd2f24623064ebc90a16.zip
llvm-4dd392fcd7847ef73233cd2f24623064ebc90a16.tar.gz
llvm-4dd392fcd7847ef73233cd2f24623064ebc90a16.tar.bz2
[ConstantRange] Make shl() for negative LHS more precise
This differs from the positive case in that shifting by a larger amount makes the result smaller, not larger.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp7
1 files changed, 7 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index e9344a8..d22d56e 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -1477,6 +1477,13 @@ ConstantRange::shl(const ConstantRange &Other) const {
}
APInt OtherMax = Other.getUnsignedMax();
+ if (isAllNegative() && OtherMax.ule(Min.countl_one())) {
+ // For negative numbers, if the shift does not overflow in a signed sense,
+ // a larger shift will make the number smaller.
+ Max <<= Other.getUnsignedMin();
+ Min <<= OtherMax;
+ return ConstantRange::getNonEmpty(std::move(Min), std::move(Max) + 1);
+ }
// There's overflow!
if (OtherMax.ugt(Max.countl_zero()))