aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-08-02 00:03:44 +0800
committerGitHub <noreply@github.com>2024-08-02 00:03:44 +0800
commit1a5d8926c5f9c1e75a285e122cf6cad0191a41b5 (patch)
tree2e7b2381bd333c5695174970c86f84b0d206dfea /llvm/lib/IR/ConstantRange.cpp
parentb5fc083dc30994f8d4f43ba6064d7b27467352c0 (diff)
downloadllvm-1a5d8926c5f9c1e75a285e122cf6cad0191a41b5.zip
llvm-1a5d8926c5f9c1e75a285e122cf6cad0191a41b5.tar.gz
llvm-1a5d8926c5f9c1e75a285e122cf6cad0191a41b5.tar.bz2
[ConstantRange] Add support for `shlWithNoWrap` (#100594)
This patch adds initial support for `ConstantRange:: shlWithNoWrap` to fold https://github.com/dtcxzyw/llvm-tools/issues/22. However, this patch cannot fix the original issue. Improvements will be submitted in subsequent patches.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 6068540..50b211a 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -988,6 +988,8 @@ ConstantRange ConstantRange::overflowingBinaryOp(Instruction::BinaryOps BinOp,
return subWithNoWrap(Other, NoWrapKind);
case Instruction::Mul:
return multiplyWithNoWrap(Other, NoWrapKind);
+ case Instruction::Shl:
+ return shlWithNoWrap(Other, NoWrapKind);
default:
// Don't know about this Overflowing Binary Operation.
// Conservatively fallback to plain binop handling.
@@ -1615,6 +1617,23 @@ ConstantRange::shl(const ConstantRange &Other) const {
return ConstantRange::getNonEmpty(std::move(Min), std::move(Max) + 1);
}
+ConstantRange ConstantRange::shlWithNoWrap(const ConstantRange &Other,
+ unsigned NoWrapKind,
+ PreferredRangeType RangeType) const {
+ if (isEmptySet() || Other.isEmptySet())
+ return getEmpty();
+
+ ConstantRange Result = shl(Other);
+
+ if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap)
+ Result = Result.intersectWith(sshl_sat(Other), RangeType);
+
+ if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap)
+ Result = Result.intersectWith(ushl_sat(Other), RangeType);
+
+ return Result;
+}
+
ConstantRange
ConstantRange::lshr(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())