Skip to content

Commit 7e23a23

Browse files
authored
[InstCombine] Fold an unsigned icmp of ucmp/scmp with a constant to an icmp of the original arguments (llvm#104471)
Proofs: https://alive2.llvm.org/ce/z/9mv8HU
1 parent 1cdf1e6 commit 7e23a23

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4018,6 +4018,16 @@ foldICmpOfCmpIntrinsicWithConstant(ICmpInst::Predicate Pred, IntrinsicInst *I,
40184018
NewPredicate = ICmpInst::ICMP_ULE;
40194019
break;
40204020

4021+
case ICmpInst::ICMP_ULT:
4022+
if (C.ugt(1))
4023+
NewPredicate = ICmpInst::ICMP_UGE;
4024+
break;
4025+
4026+
case ICmpInst::ICMP_UGT:
4027+
if (!C.isZero() && !C.isAllOnes())
4028+
NewPredicate = ICmpInst::ICMP_ULT;
4029+
break;
4030+
40214031
default:
40224032
break;
40234033
}

llvm/test/Transforms/InstCombine/scmp.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,31 @@ define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
157157
ret i1 %2
158158
}
159159

160+
; scmp(x, y) u< C => x s>= y when C u> 1 and C != -1
161+
define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {
162+
; CHECK-LABEL: define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(
163+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
164+
; CHECK-NEXT: [[TMP1:%.*]] = icmp sge i32 [[X]], [[Y]]
165+
; CHECK-NEXT: ret i1 [[TMP1]]
166+
;
167+
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
168+
%2 = icmp ult i8 %1, 4
169+
ret i1 %2
170+
}
171+
172+
; scmp(x, y) s> C => x s< y when C != 0 and C != -1
173+
define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {
174+
; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(
175+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
176+
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
177+
; CHECK-NEXT: ret i1 [[TMP2]]
178+
;
179+
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
180+
%2 = icmp ugt i8 %1, 12
181+
ret i1 %2
182+
}
183+
184+
160185
; ========== Fold -scmp(x, y) => scmp(y, x) ==========
161186
define i8 @scmp_negated(i32 %x, i32 %y) {
162187
; CHECK-LABEL: define i8 @scmp_negated(

llvm/test/Transforms/InstCombine/ucmp.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,30 @@ define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {
157157
ret i1 %2
158158
}
159159

160+
; ucmp(x, y) u< C => x u>= y when C u> 1 and C != -1
161+
define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {
162+
; CHECK-LABEL: define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(
163+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
164+
; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[X]], [[Y]]
165+
; CHECK-NEXT: ret i1 [[TMP1]]
166+
;
167+
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
168+
%2 = icmp ult i8 %1, 4
169+
ret i1 %2
170+
}
171+
172+
; ucmp(x, y) u> C => x u< y when C != 0 and C != -1
173+
define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {
174+
; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(
175+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
176+
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
177+
; CHECK-NEXT: ret i1 [[TMP2]]
178+
;
179+
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
180+
%2 = icmp ugt i8 %1, 12
181+
ret i1 %2
182+
}
183+
160184
; ========== Fold -ucmp(x, y) => ucmp(y, x) ==========
161185
define i8 @ucmp_negated(i32 %x, i32 %y) {
162186
; CHECK-LABEL: define i8 @ucmp_negated(

0 commit comments

Comments
 (0)