Skip to content

Commit

Permalink
[InstCombine] Fold an unsigned icmp of ucmp/scmp with a constant to a…
Browse files Browse the repository at this point in the history
…n icmp of the original arguments (llvm#104471)

Proofs: https://alive2.llvm.org/ce/z/9mv8HU
  • Loading branch information
Poseydon42 authored Aug 16, 2024
1 parent 1cdf1e6 commit 7e23a23
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
10 changes: 10 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4018,6 +4018,16 @@ foldICmpOfCmpIntrinsicWithConstant(ICmpInst::Predicate Pred, IntrinsicInst *I,
NewPredicate = ICmpInst::ICMP_ULE;
break;

case ICmpInst::ICMP_ULT:
if (C.ugt(1))
NewPredicate = ICmpInst::ICMP_UGE;
break;

case ICmpInst::ICMP_UGT:
if (!C.isZero() && !C.isAllOnes())
NewPredicate = ICmpInst::ICMP_ULT;
break;

default:
break;
}
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/Transforms/InstCombine/scmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,31 @@ define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
ret i1 %2
}

; scmp(x, y) u< C => x s>= y when C u> 1 and C != -1
define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = icmp sge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP1]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
%2 = icmp ult i8 %1, 4
ret i1 %2
}

; scmp(x, y) s> C => x s< y when C != 0 and C != -1
define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
%2 = icmp ugt i8 %1, 12
ret i1 %2
}


; ========== Fold -scmp(x, y) => scmp(y, x) ==========
define i8 @scmp_negated(i32 %x, i32 %y) {
; CHECK-LABEL: define i8 @scmp_negated(
Expand Down
24 changes: 24 additions & 0 deletions llvm/test/Transforms/InstCombine/ucmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {
ret i1 %2
}

; ucmp(x, y) u< C => x u>= y when C u> 1 and C != -1
define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP1]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
%2 = icmp ult i8 %1, 4
ret i1 %2
}

; ucmp(x, y) u> C => x u< y when C != 0 and C != -1
define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
%2 = icmp ugt i8 %1, 12
ret i1 %2
}

; ========== Fold -ucmp(x, y) => ucmp(y, x) ==========
define i8 @ucmp_negated(i32 %x, i32 %y) {
; CHECK-LABEL: define i8 @ucmp_negated(
Expand Down

0 comments on commit 7e23a23

Please sign in to comment.