[llvm] [LVI] Add support for trunc nuw range. (PR #154021)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 17 08:06:17 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Andreas Jonson (andjo403)
<details>
<summary>Changes</summary>
Proof: https://alive2.llvm.org/ce/z/a5Yjb8
same type of change as in [SCCP](https://github.com/llvm/llvm-project/pull/152990)
---
Full diff: https://github.com/llvm/llvm-project/pull/154021.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/LazyValueInfo.cpp (+7-2)
- (modified) llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll (+40)
``````````diff
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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/154021
More information about the llvm-commits
mailing list