[llvm] 49144f7 - [InstCombine] Improve range computation in `foldICmpAddConstant` (#155096)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 23 23:32:24 PDT 2025
Author: Yingwei Zheng
Date: 2025-08-24T14:32:21+08:00
New Revision: 49144f7e491b76dba903d9c7e0a7e54a2073d95d
URL: https://github.com/llvm/llvm-project/commit/49144f7e491b76dba903d9c7e0a7e54a2073d95d
DIFF: https://github.com/llvm/llvm-project/commit/49144f7e491b76dba903d9c7e0a7e54a2073d95d.diff
LOG: [InstCombine] Improve range computation in `foldICmpAddConstant` (#155096)
Address comment
https://github.com/llvm/llvm-project/pull/110511#discussion_r1788946221.
Added:
Modified:
llvm/include/llvm/IR/ConstantRange.h
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-add.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/ConstantRange.h b/llvm/include/llvm/IR/ConstantRange.h
index 4b2fda364fdf4..f4d4f1f555fa4 100644
--- a/llvm/include/llvm/IR/ConstantRange.h
+++ b/llvm/include/llvm/IR/ConstantRange.h
@@ -381,6 +381,7 @@ class [[nodiscard]] ConstantRange {
/// strictly smaller than the current type. The returned range will
/// correspond to the possible range of values if the source range had been
/// truncated to the specified type with wrap type \p NoWrapKind.
+ /// Note that the result of trunc nuw is exact.
LLVM_ABI ConstantRange truncate(uint32_t BitWidth,
unsigned NoWrapKind = 0) const;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 2386e7ad47fb7..3a8e043038153 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3320,20 +3320,18 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
Type *NewCmpTy = V->getType();
unsigned NewCmpBW = NewCmpTy->getScalarSizeInBits();
if (shouldChangeType(Ty, NewCmpTy)) {
- if (CR.getActiveBits() <= NewCmpBW) {
- ConstantRange SrcCR = CR.truncate(NewCmpBW);
- CmpInst::Predicate EquivPred;
- APInt EquivInt;
- APInt EquivOffset;
-
- SrcCR.getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
- return new ICmpInst(
- EquivPred,
- EquivOffset.isZero()
- ? V
- : Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
- ConstantInt::get(NewCmpTy, EquivInt));
- }
+ ConstantRange SrcCR = CR.truncate(NewCmpBW, TruncInst::NoUnsignedWrap);
+ CmpInst::Predicate EquivPred;
+ APInt EquivInt;
+ APInt EquivOffset;
+
+ SrcCR.getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
+ return new ICmpInst(
+ EquivPred,
+ EquivOffset.isZero()
+ ? V
+ : Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
+ ConstantInt::get(NewCmpTy, EquivInt));
}
}
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index cb428097f2ae1..8449c7c5ea935 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3209,13 +3209,11 @@ entry:
ret i1 %cmp
}
-; TODO: should be canonicalized to (x - 4) u> 2
define i1 @zext_range_check_ugt(i8 %x) {
; CHECK-LABEL: @zext_range_check_ugt(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[CONV]], -7
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0]], -3
+; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[X:%.*]], -7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], -3
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
@@ -3225,13 +3223,11 @@ entry:
ret i1 %cmp
}
-; TODO: should be canonicalized to (x - 4) u> 2
define i1 @zext_range_check_ult_alter(i8 %x) {
; CHECK-LABEL: @zext_range_check_ult_alter(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -7
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], -3
+; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[X:%.*]], -7
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], -3
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
@@ -3241,6 +3237,19 @@ entry:
ret i1 %cmp
}
+define i1 @zext_range_check_ult_alter2(i8 %x) {
+; CHECK-LABEL: @zext_range_check_ult_alter2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 3
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %conv = zext i8 %x to i32
+ %add = add i32 %conv, -4
+ %cmp = icmp ult i32 %add, 253
+ ret i1 %cmp
+}
+
define i1 @zext_range_check_mergable(i8 %x) {
; CHECK-LABEL: @zext_range_check_mergable(
; CHECK-NEXT: [[COND:%.*]] = icmp slt i8 [[X:%.*]], 7
@@ -3286,21 +3295,6 @@ entry:
ret i1 %cmp
}
-define i1 @zext_range_check_ult_range_check_failure(i8 %x) {
-; CHECK-LABEL: @zext_range_check_ult_range_check_failure(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 253
-; CHECK-NEXT: ret i1 [[CMP]]
-;
-entry:
- %conv = zext i8 %x to i32
- %add = add i32 %conv, -4
- %cmp = icmp ult i32 %add, 253
- ret i1 %cmp
-}
-
; PR 152851
define i1 @val_is_aligend_const_pow2(i32 %num) {
More information about the llvm-commits
mailing list