Skip to content

Commit e338204

Browse files
committed
Fold icmp samesign u{gt/lt} (add nsw X, C2), C -> icmp s{gt/lt} X, (C - C2)
whenever applicable.
1 parent d64909e commit e338204

File tree

2 files changed

+24
-17
lines changed

2 files changed

+24
-17
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,7 +3132,7 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31323132

31333133
Value *Op0, *Op1;
31343134
Instruction *Ext0, *Ext1;
3135-
const CmpInst::Predicate Pred = Cmp.getPredicate();
3135+
const CmpPredicate Pred = Cmp.getCmpPredicate();
31363136
if (match(Add,
31373137
m_Add(m_CombineAnd(m_Instruction(Ext0), m_ZExtOrSExt(m_Value(Op0))),
31383138
m_CombineAnd(m_Instruction(Ext1),
@@ -3167,14 +3167,11 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31673167

31683168
// If the add does not wrap, we can always adjust the compare by subtracting
31693169
// the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE
3170-
// are canonicalized to SGT/SLT/UGT/ULT.
3171-
if ((Add->hasNoSignedWrap() &&
3172-
(Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT)) ||
3173-
(Add->hasNoUnsignedWrap() &&
3174-
(Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT))) {
3170+
// have been canonicalized to SGT/SLT/UGT/ULT.
3171+
if (Add->hasNoUnsignedWrap() &&
3172+
(Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT)) {
31753173
bool Overflow;
3176-
APInt NewC =
3177-
Cmp.isSigned() ? C.ssub_ov(*C2, Overflow) : C.usub_ov(*C2, Overflow);
3174+
APInt NewC = C.usub_ov(*C2, Overflow);
31783175
// If there is overflow, the result must be true or false.
31793176
// TODO: Can we assert there is no overflow because InstSimplify always
31803177
// handles those cases?
@@ -3183,6 +3180,18 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31833180
return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC));
31843181
}
31853182

3183+
CmpInst::Predicate ChosenPred = Pred.getPreferredSignedPredicate();
3184+
3185+
if (Add->hasNoSignedWrap() &&
3186+
(ChosenPred == ICmpInst::ICMP_SGT || ChosenPred == ICmpInst::ICMP_SLT)) {
3187+
bool Overflow;
3188+
APInt NewC = C.ssub_ov(*C2, Overflow);
3189+
if (!Overflow)
3190+
// icmp samesign ugt/ult (add nsw X, C2), C
3191+
// -> icmp sgt/slt X, (C - C2)
3192+
return new ICmpInst(ChosenPred, X, ConstantInt::get(Ty, NewC));
3193+
}
3194+
31863195
if (ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() &&
31873196
C.isNonNegative() && (C - *C2).isNonNegative() &&
31883197
computeConstantRange(X, /*ForSigned=*/true).add(*C2).isAllNonNegative())

llvm/test/Transforms/InstCombine/icmp-add.ll

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,8 +3444,7 @@ define i1 @val_is_aligend_pred_mismatch(i32 %num) {
34443444
define i1 @icmp_samesign_with_nsw_add(i32 %arg0) {
34453445
; CHECK-LABEL: @icmp_samesign_with_nsw_add(
34463446
; CHECK-NEXT: entry:
3447-
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[ARG0:%.*]], -26
3448-
; CHECK-NEXT: [[V1:%.*]] = icmp ult i32 [[TMP0]], -8
3447+
; CHECK-NEXT: [[V1:%.*]] = icmp sgt i32 [[ARG0:%.*]], 25
34493448
; CHECK-NEXT: ret i1 [[V1]]
34503449
;
34513450
entry:
@@ -3454,9 +3453,9 @@ entry:
34543453
ret i1 %v1
34553454
}
34563455

3457-
; Shouldn't fire since -124 - 12 causes signed overflow
3458-
define i1 @icmp_samesign_with_nsw_add_no_fire(i8 %arg0) {
3459-
; CHECK-LABEL: @icmp_samesign_with_nsw_add_no_fire(
3456+
; Negative test; Fold shouldn't fire since -124 - 12 causes signed overflow
3457+
define i1 @icmp_samesign_with_nsw_add_neg(i8 %arg0) {
3458+
; CHECK-LABEL: @icmp_samesign_with_nsw_add_neg(
34603459
; CHECK-NEXT: entry:
34613460
; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[ARG0:%.*]], -121
34623461
; CHECK-NEXT: [[V1:%.*]] = icmp ult i8 [[TMP0]], 123
@@ -3471,20 +3470,19 @@ entry:
34713470
define i1 @icmp_with_nuw_add(i32 %arg0) {
34723471
; CHECK-LABEL: @icmp_with_nuw_add(
34733472
; CHECK-NEXT: entry:
3474-
; CHECK-NEXT: [[V1:%.*]] = icmp ugt i32 [[ARG0:%.*]], 11
3473+
; CHECK-NEXT: [[V1:%.*]] = icmp ult i32 [[ARG0:%.*]], 11
34753474
; CHECK-NEXT: ret i1 [[V1]]
34763475
;
34773476
entry:
34783477
%v0 = add nuw i32 %arg0, 7
3479-
%v1 = icmp ugt i32 %v0, 18
3478+
%v1 = icmp ult i32 %v0, 18
34803479
ret i1 %v1
34813480
}
34823481

34833482
define i1 @icmp_partial_negative_samesign_ult_to_slt(i8 range(i8 -1, 5) %x) {
34843483
; CHECK-LABEL: @icmp_partial_negative_samesign_ult_to_slt(
34853484
; CHECK-NEXT: entry:
3486-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], -5
3487-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i8 [[ADD]], -3
3485+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 2
34883486
; CHECK-NEXT: ret i1 [[CMP]]
34893487
;
34903488
entry:

0 commit comments

Comments
 (0)