[llvm] 0561ff6 - [LVI] Add support for trunc nuw range. (#154021)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 17 11:24:12 PDT 2025


Author: Andreas Jonson
Date: 2025-08-17T20:24:09+02:00
New Revision: 0561ff6a12e1219af0ea6146c62233b18b82475b

URL: https://github.com/llvm/llvm-project/commit/0561ff6a12e1219af0ea6146c62233b18b82475b
DIFF: https://github.com/llvm/llvm-project/commit/0561ff6a12e1219af0ea6146c62233b18b82475b.diff

LOG: [LVI] Add support for trunc nuw range. (#154021)

Proof: https://alive2.llvm.org/ce/z/a5Yjb8

Added: 
    

Modified: 
    llvm/lib/Analysis/LazyValueInfo.cpp
    llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll

Removed: 
    


################################################################################
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
+}


        


More information about the llvm-commits mailing list