Skip to content

Commit 726d4a9

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 29ab236 commit 726d4a9

File tree

2 files changed

+17
-18
lines changed

2 files changed

+17
-18
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 10 additions & 9 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.getPredicate(), Cmp.hasSameSign());
31363136
if (match(Add,
31373137
m_Add(m_CombineAnd(m_Instruction(Ext0), m_ZExtOrSExt(m_Value(Op0))),
31383138
m_CombineAnd(m_Instruction(Ext1),
@@ -3167,20 +3167,21 @@ 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+
// has been canonicalized to SGT/SLT/UGT/ULT.
3171+
CmpInst::Predicate ChosenPred = Pred.getPreferredSignedPredicate();
3172+
if ((Add->hasNoSignedWrap() && (ChosenPred == ICmpInst::ICMP_SGT ||
3173+
ChosenPred == ICmpInst::ICMP_SLT)) ||
3174+
(Add->hasNoUnsignedWrap() && (ChosenPred == ICmpInst::ICMP_UGT ||
3175+
ChosenPred == ICmpInst::ICMP_ULT))) {
31753176
bool Overflow;
3176-
APInt NewC =
3177-
Cmp.isSigned() ? C.ssub_ov(*C2, Overflow) : C.usub_ov(*C2, Overflow);
3177+
APInt NewC = ICmpInst::isSigned(ChosenPred) ? C.ssub_ov(*C2, Overflow)
3178+
: C.usub_ov(*C2, Overflow);
31783179
// If there is overflow, the result must be true or false.
31793180
// TODO: Can we assert there is no overflow because InstSimplify always
31803181
// handles those cases?
31813182
if (!Overflow)
31823183
// icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2)
3183-
return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC));
3184+
return new ICmpInst(ChosenPred, X, ConstantInt::get(Ty, NewC));
31843185
}
31853186

31863187
if (ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() &&

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)