-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[LVI] Add support for trunc nuw range. #154021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: Andreas Jonson (andjo403) ChangesProof: https://alive2.llvm.org/ce/z/a5Yjb8 same type of change as in SCCP Full diff: https://github.com/llvm/llvm-project/pull/154021.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 922f25de54e9d..c7b0ca97a8e43 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -927,8 +927,13 @@ LazyValueInfoImpl::solveBlockValueCast(CastInst *CI, BasicBlock *BB) {
// NOTE: We're currently limited by the set of operations that ConstantRange
// can evaluate symbolically. Enhancing that set will allows us to analyze
// more definitions.
- return ValueLatticeElement::getRange(LHSRange.castOp(CI->getOpcode(),
- ResultBitWidth));
+ ConstantRange Res = ConstantRange::getEmpty(ResultBitWidth);
+ if (auto *Trunc = dyn_cast<TruncInst>(CI))
+ Res = LHSRange.truncate(ResultBitWidth, Trunc->getNoWrapKind());
+ else
+ Res = LHSRange.castOp(CI->getOpcode(), ResultBitWidth);
+
+ return ValueLatticeElement::getRange(Res);
}
std::optional<ValueLatticeElement>
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll b/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll
index 9b6604298840d..42a89ab0dbc03 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll
@@ -106,3 +106,43 @@ define i1 @overdefined_range_negative(i8 %A, i8 %B) {
%trunc = trunc i8 %xor to i1
ret i1 %trunc
}
+
+define i1 @trunc_nuw_infere_false_for_icmp_ne_1(i8 %x) {
+; CHECK-LABEL: define i1 @trunc_nuw_infere_false_for_icmp_ne_1(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[X]], 1
+; CHECK-NEXT: br i1 [[ICMP]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]]
+; CHECK: [[IFTRUE]]:
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[X]] to i1
+; CHECK-NEXT: ret i1 false
+; CHECK: [[IFFALSE]]:
+; CHECK-NEXT: ret i1 true
+;
+ %icmp = icmp ne i8 %x, 1
+ br i1 %icmp, label %iftrue, label %iffalse
+iftrue:
+ %trunc = trunc nuw i8 %x to i1
+ ret i1 %trunc
+iffalse:
+ ret i1 true
+}
+
+define i1 @neg_trunc_do_not_infere_false_for_icmp_ne_1(i8 %x) {
+; CHECK-LABEL: define i1 @neg_trunc_do_not_infere_false_for_icmp_ne_1(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[X]], 1
+; CHECK-NEXT: br i1 [[ICMP]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]]
+; CHECK: [[IFTRUE]]:
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: ret i1 [[TRUNC]]
+; CHECK: [[IFFALSE]]:
+; CHECK-NEXT: ret i1 true
+;
+ %icmp = icmp ne i8 %x, 1
+ br i1 %icmp, label %iftrue, label %iffalse
+iftrue:
+ %trunc = trunc i8 %x to i1
+ ret i1 %trunc
+iffalse:
+ ret i1 true
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you!
Proof: https://alive2.llvm.org/ce/z/a5Yjb8
same type of change as in SCCP