From 011b0df1960106037e377c4ac3e83106df78b293 Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sun, 17 Aug 2025 16:34:13 +0200 Subject: [PATCH 1/2] [LVI] Add test for trunc nuw range. (NFC) --- .../CorrelatedValuePropagation/trunc.ll | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll b/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll index 9b6604298840d..2d3c7aa59649e 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 [[TRUNC]] +; 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 +} From 5584630ff3aad05ec3188b1b8d364f4c1fd5971b Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sun, 17 Aug 2025 16:35:59 +0200 Subject: [PATCH 2/2] [LVI] Add support for trunc nuw range. --- llvm/lib/Analysis/LazyValueInfo.cpp | 9 +++++++-- llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) 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(CI)) + Res = LHSRange.truncate(ResultBitWidth, Trunc->getNoWrapKind()); + else + Res = LHSRange.castOp(CI->getOpcode(), ResultBitWidth); + + return ValueLatticeElement::getRange(Res); } std::optional diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll b/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll index 2d3c7aa59649e..42a89ab0dbc03 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/trunc.ll @@ -114,7 +114,7 @@ define i1 @trunc_nuw_infere_false_for_icmp_ne_1(i8 %x) { ; CHECK-NEXT: br i1 [[ICMP]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]] ; CHECK: [[IFTRUE]]: ; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[X]] to i1 -; CHECK-NEXT: ret i1 [[TRUNC]] +; CHECK-NEXT: ret i1 false ; CHECK: [[IFFALSE]]: ; CHECK-NEXT: ret i1 true ;