Skip to content

Commit 9fee32d

Browse files
committed
[InstSimplify] Extend icmp-of-add simplification to sle/sgt/sge
When comparing additions with the same base where one has `nsw`, the following simplification can be performed: ```llvm icmp slt/sgt/sle/sge (x + C1), (x +nsw C2) => icmp slt/sgt/sle/sge C1, C2 ``` Previously this was only done for `slt`. This patch extends it to the `sgt`, `sle`, and `sge` predicates when either of the conditions hold: - `C1 <= C2 && C1 >= 0`, or - `C2 <= C1 && C1 <= 0` This patch also handles the `C1 == C2` case, which was previously excluded. Proof: https://alive2.llvm.org/ce/z/LtmY4f
1 parent c9a2887 commit 9fee32d

File tree

2 files changed

+18
-40
lines changed

2 files changed

+18
-40
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,20 +3261,22 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpPredicate Pred, BinaryOperator *LBO,
32613261

32623262
// If only one of the icmp's operands has NSW flags, try to prove that:
32633263
//
3264-
// icmp slt (x + C1), (x +nsw C2)
3264+
// icmp slt/sgt/sle/sge (x + C1), (x +nsw C2)
32653265
//
32663266
// is equivalent to:
32673267
//
3268-
// icmp slt C1, C2
3268+
// icmp slt/sgt/sle/sge C1, C2
32693269
//
32703270
// which is true if x + C2 has the NSW flags set and:
3271-
// *) C1 < C2 && C1 >= 0, or
3272-
// *) C2 < C1 && C1 <= 0.
3271+
// *) C1 <= C2 && C1 >= 0, or
3272+
// *) C2 <= C1 && C1 <= 0.
32733273
//
32743274
static bool trySimplifyICmpWithAdds(CmpPredicate Pred, Value *LHS, Value *RHS,
32753275
const InstrInfoQuery &IIQ) {
3276-
// TODO: only support icmp slt for now.
3277-
if (Pred != CmpInst::ICMP_SLT || !IIQ.UseInstrInfo)
3276+
// TODO: support other predicates.
3277+
if ((Pred != CmpInst::ICMP_SLT && Pred != CmpInst::ICMP_SGT &&
3278+
Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SGE) ||
3279+
!IIQ.UseInstrInfo)
32783280
return false;
32793281

32803282
// Canonicalize nsw add as RHS.
@@ -3289,8 +3291,8 @@ static bool trySimplifyICmpWithAdds(CmpPredicate Pred, Value *LHS, Value *RHS,
32893291
!match(RHS, m_Add(m_Specific(X), m_APInt(C2))))
32903292
return false;
32913293

3292-
return (C1->slt(*C2) && C1->isNonNegative()) ||
3293-
(C2->slt(*C1) && C1->isNonPositive());
3294+
return (C1->sle(*C2) && C1->isNonNegative()) ||
3295+
(C2->sle(*C1) && C1->isNonPositive());
32943296
}
32953297

32963298
/// TODO: A large part of this logic is duplicated in InstCombine's

llvm/test/Transforms/InstSimplify/compare.ll

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,10 +2687,7 @@ define i1 @icmp_nsw_false_2(i32 %V) {
26872687

26882688
define i1 @icmp_nsw_false_3(i32 %V) {
26892689
; CHECK-LABEL: @icmp_nsw_false_3(
2690-
; CHECK-NEXT: [[ADD5:%.*]] = add nsw i32 [[V:%.*]], 5
2691-
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[V]], 5
2692-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD6]]
2693-
; CHECK-NEXT: ret i1 [[CMP]]
2690+
; CHECK-NEXT: ret i1 false
26942691
;
26952692
%add5 = add nsw i32 %V, 5
26962693
%add6 = add i32 %V, 5
@@ -2805,10 +2802,7 @@ define <4 x i1> @icmp_nsw_vec(<4 x i32> %V) {
28052802

28062803
define i1 @icmp_nsw_3(i32 %V) {
28072804
; CHECK-LABEL: @icmp_nsw_3(
2808-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 5
2809-
; CHECK-NEXT: [[ADD5_2:%.*]] = add nsw i32 [[V]], 5
2810-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD5]], [[ADD5_2]]
2811-
; CHECK-NEXT: ret i1 [[CMP]]
2805+
; CHECK-NEXT: ret i1 false
28122806
;
28132807
%add5 = add i32 %V, 5
28142808
%add5_2 = add nsw i32 %V, 5
@@ -2883,10 +2877,7 @@ define i1 @icmp_nsw_9(i32 %V1, i32 %V2) {
28832877

28842878
define i1 @icmp_nsw_10(i32 %V) {
28852879
; CHECK-LABEL: @icmp_nsw_10(
2886-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 5
2887-
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], 6
2888-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD6]], [[ADD5]]
2889-
; CHECK-NEXT: ret i1 [[CMP]]
2880+
; CHECK-NEXT: ret i1 true
28902881
;
28912882
%add5 = add i32 %V, 5
28922883
%add6 = add nsw i32 %V, 6
@@ -2919,10 +2910,7 @@ define i1 @icmp_nsw_12(i32 %V) {
29192910

29202911
define i1 @icmp_nsw_13(i32 %V) {
29212912
; CHECK-LABEL: @icmp_nsw_13(
2922-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 7
2923-
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], 10
2924-
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[ADD5]], [[ADD6]]
2925-
; CHECK-NEXT: ret i1 [[CMP]]
2913+
; CHECK-NEXT: ret i1 true
29262914
;
29272915
%add5 = add i32 %V, 7
29282916
%add6 = add nsw i32 %V, 10
@@ -2932,10 +2920,7 @@ define i1 @icmp_nsw_13(i32 %V) {
29322920

29332921
define i1 @icmp_nsw_14(i32 %V) {
29342922
; CHECK-LABEL: @icmp_nsw_14(
2935-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], 7
2936-
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], 10
2937-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ADD5]], [[ADD6]]
2938-
; CHECK-NEXT: ret i1 [[CMP]]
2923+
; CHECK-NEXT: ret i1 false
29392924
;
29402925
%add5 = add i32 %V, 7
29412926
%add6 = add nsw i32 %V, 10
@@ -2967,10 +2952,7 @@ define i1 @icmp_nsw_nonpos2(i32 %V) {
29672952

29682953
define i1 @icmp_nsw_nonpos3(i32 %V) {
29692954
; CHECK-LABEL: @icmp_nsw_nonpos3(
2970-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], -2
2971-
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], -5
2972-
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[ADD5]], [[ADD6]]
2973-
; CHECK-NEXT: ret i1 [[CMP]]
2955+
; CHECK-NEXT: ret i1 false
29742956
;
29752957
%add5 = add i32 %V, -2
29762958
%add6 = add nsw i32 %V, -5
@@ -2980,10 +2962,7 @@ define i1 @icmp_nsw_nonpos3(i32 %V) {
29802962

29812963
define i1 @icmp_nsw_nonpos4(i32 %V) {
29822964
; CHECK-LABEL: @icmp_nsw_nonpos4(
2983-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], -10
2984-
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], -30
2985-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD5]], [[ADD6]]
2986-
; CHECK-NEXT: ret i1 [[CMP]]
2965+
; CHECK-NEXT: ret i1 true
29872966
;
29882967
%add5 = add i32 %V, -10
29892968
%add6 = add nsw i32 %V, -30
@@ -2993,10 +2972,7 @@ define i1 @icmp_nsw_nonpos4(i32 %V) {
29932972

29942973
define i1 @icmp_nsw_nonpos5(i32 %V) {
29952974
; CHECK-LABEL: @icmp_nsw_nonpos5(
2996-
; CHECK-NEXT: [[ADD5:%.*]] = add i32 [[V:%.*]], -15
2997-
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[V]], -100
2998-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ADD5]], [[ADD6]]
2999-
; CHECK-NEXT: ret i1 [[CMP]]
2975+
; CHECK-NEXT: ret i1 true
30002976
;
30012977
%add5 = add i32 %V, -15
30022978
%add6 = add nsw i32 %V, -100

0 commit comments

Comments
 (0)