Skip to content

Commit 9f2fc88

Browse files
authored
[ValueTracking] Simplify uaddo pattern (#65910)
This patch simplifies the overflow check of unsigned addition. `a + b <u a` implies `a + b <u b` `a + b >=u a` implies `a + b >=u b` Alive2: https://alive2.llvm.org/ce/z/H8oK8n Fixes #65863.
1 parent 4b4d383 commit 9f2fc88

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8292,6 +8292,29 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
82928292
if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC)))
82938293
return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC);
82948294

8295+
// L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
8296+
if (ICmpInst::isUnsigned(LPred) && ICmpInst::isUnsigned(RPred)) {
8297+
if (L0 == R1) {
8298+
std::swap(R0, R1);
8299+
RPred = ICmpInst::getSwappedPredicate(RPred);
8300+
}
8301+
if (L1 == R0) {
8302+
std::swap(L0, L1);
8303+
LPred = ICmpInst::getSwappedPredicate(LPred);
8304+
}
8305+
if (L1 == R1) {
8306+
std::swap(L0, L1);
8307+
LPred = ICmpInst::getSwappedPredicate(LPred);
8308+
std::swap(R0, R1);
8309+
RPred = ICmpInst::getSwappedPredicate(RPred);
8310+
}
8311+
if (L0 == R0 &&
8312+
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&
8313+
(RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) &&
8314+
match(L0, m_c_Add(m_Specific(L1), m_Specific(R1))))
8315+
return LPred == RPred;
8316+
}
8317+
82958318
if (LPred == RPred)
82968319
return isImpliedCondOperands(LPred, L0, L1, R0, R1, DL, Depth);
82978320

llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,7 @@ define i1 @uaddo_and(i64 %a, i64 %b){
131131
; CHECK-LABEL: @uaddo_and(
132132
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
133133
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
134-
; CHECK-NEXT: [[COND_B:%.*]] = icmp uge i64 [[S]], [[B]]
135-
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
136-
; CHECK-NEXT: ret i1 [[COND]]
134+
; CHECK-NEXT: ret i1 [[COND_A]]
137135
;
138136
%s = add i64 %a, %b
139137
%cond_a = icmp uge i64 %s, %a
@@ -146,9 +144,7 @@ define i1 @uaddo_and_commuted1(i64 %a, i64 %b){
146144
; CHECK-LABEL: @uaddo_and_commuted1(
147145
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
148146
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
149-
; CHECK-NEXT: [[COND_B:%.*]] = icmp uge i64 [[S]], [[B]]
150-
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
151-
; CHECK-NEXT: ret i1 [[COND]]
147+
; CHECK-NEXT: ret i1 [[COND_A]]
152148
;
153149
%s = add i64 %a, %b
154150
%cond_a = icmp ule i64 %a, %s
@@ -161,9 +157,7 @@ define i1 @uaddo_and_commuted2(i64 %a, i64 %b){
161157
; CHECK-LABEL: @uaddo_and_commuted2(
162158
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
163159
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
164-
; CHECK-NEXT: [[COND_B:%.*]] = icmp ule i64 [[B]], [[S]]
165-
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
166-
; CHECK-NEXT: ret i1 [[COND]]
160+
; CHECK-NEXT: ret i1 [[COND_A]]
167161
;
168162
%s = add i64 %a, %b
169163
%cond_a = icmp uge i64 %s, %a
@@ -176,9 +170,7 @@ define i1 @uaddo_and_commuted3(i64 %a, i64 %b){
176170
; CHECK-LABEL: @uaddo_and_commuted3(
177171
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
178172
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
179-
; CHECK-NEXT: [[COND_B:%.*]] = icmp ule i64 [[B]], [[S]]
180-
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
181-
; CHECK-NEXT: ret i1 [[COND]]
173+
; CHECK-NEXT: ret i1 [[COND_A]]
182174
;
183175
%s = add i64 %a, %b
184176
%cond_a = icmp ule i64 %a, %s
@@ -191,9 +183,7 @@ define i1 @uaddo_or(i64 %a, i64 %b){
191183
; CHECK-LABEL: @uaddo_or(
192184
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
193185
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
194-
; CHECK-NEXT: [[COND_B:%.*]] = icmp ult i64 [[S]], [[B]]
195-
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
196-
; CHECK-NEXT: ret i1 [[COND]]
186+
; CHECK-NEXT: ret i1 [[COND_A]]
197187
;
198188
%s = add i64 %a, %b
199189
%cond_a = icmp ult i64 %s, %a
@@ -206,9 +196,7 @@ define i1 @uaddo_or_commuted1(i64 %a, i64 %b){
206196
; CHECK-LABEL: @uaddo_or_commuted1(
207197
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
208198
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
209-
; CHECK-NEXT: [[COND_B:%.*]] = icmp ult i64 [[S]], [[B]]
210-
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
211-
; CHECK-NEXT: ret i1 [[COND]]
199+
; CHECK-NEXT: ret i1 [[COND_A]]
212200
;
213201
%s = add i64 %a, %b
214202
%cond_a = icmp ugt i64 %a, %s
@@ -221,9 +209,7 @@ define i1 @uaddo_or_commuted2(i64 %a, i64 %b){
221209
; CHECK-LABEL: @uaddo_or_commuted2(
222210
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
223211
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
224-
; CHECK-NEXT: [[COND_B:%.*]] = icmp ugt i64 [[B]], [[S]]
225-
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
226-
; CHECK-NEXT: ret i1 [[COND]]
212+
; CHECK-NEXT: ret i1 [[COND_A]]
227213
;
228214
%s = add i64 %a, %b
229215
%cond_a = icmp ult i64 %s, %a
@@ -236,9 +222,7 @@ define i1 @uaddo_or_commuted3(i64 %a, i64 %b){
236222
; CHECK-LABEL: @uaddo_or_commuted3(
237223
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
238224
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
239-
; CHECK-NEXT: [[COND_B:%.*]] = icmp ugt i64 [[B]], [[S]]
240-
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
241-
; CHECK-NEXT: ret i1 [[COND]]
225+
; CHECK-NEXT: ret i1 [[COND_A]]
242226
;
243227
%s = add i64 %a, %b
244228
%cond_a = icmp ugt i64 %a, %s

0 commit comments

Comments
 (0)