diff options
author | Nikita Popov <npopov@redhat.com> | 2023-08-29 14:43:44 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2023-08-29 14:48:33 +0200 |
commit | 4dd392fcd7847ef73233cd2f24623064ebc90a16 (patch) | |
tree | 37c38496005e88e2e52deb516a8c401bb6e89783 /llvm/lib/IR/ConstantRange.cpp | |
parent | 498b59e01133bed16c72dd939a9daa8ae1f359e4 (diff) | |
download | llvm-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.cpp | 7 |
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())) |