Skip to content

Commit 9bb817a

Browse files
committed
[ValueTracking] Simplify uaddo pattern
1 parent 44e5afd commit 9bb817a

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

llvm/lib/Analysis/ValueTracking.cpp

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

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

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

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,107 @@ define i1 @and_not_implied(i8 %x, i1 %c) {
126126
%and = and i1 %or, %cmp2
127127
ret i1 %and
128128
}
129+
130+
define i1 @uaddo_and(i64 %a, i64 %b){
131+
; CHECK-LABEL: @uaddo_and(
132+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
133+
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
134+
; CHECK-NEXT: ret i1 [[COND_A]]
135+
;
136+
%s = add i64 %a, %b
137+
%cond_a = icmp uge i64 %s, %a
138+
%cond_b = icmp uge i64 %s, %b
139+
%cond = and i1 %cond_a, %cond_b
140+
ret i1 %cond
141+
}
142+
143+
define i1 @uaddo_and_commuted1(i64 %a, i64 %b){
144+
; CHECK-LABEL: @uaddo_and_commuted1(
145+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
146+
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
147+
; CHECK-NEXT: ret i1 [[COND_A]]
148+
;
149+
%s = add i64 %a, %b
150+
%cond_a = icmp ule i64 %a, %s
151+
%cond_b = icmp uge i64 %s, %b
152+
%cond = and i1 %cond_a, %cond_b
153+
ret i1 %cond
154+
}
155+
156+
define i1 @uaddo_and_commuted2(i64 %a, i64 %b){
157+
; CHECK-LABEL: @uaddo_and_commuted2(
158+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
159+
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
160+
; CHECK-NEXT: ret i1 [[COND_A]]
161+
;
162+
%s = add i64 %a, %b
163+
%cond_a = icmp uge i64 %s, %a
164+
%cond_b = icmp ule i64 %b, %s
165+
%cond = and i1 %cond_a, %cond_b
166+
ret i1 %cond
167+
}
168+
169+
define i1 @uaddo_and_commuted3(i64 %a, i64 %b){
170+
; CHECK-LABEL: @uaddo_and_commuted3(
171+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
172+
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
173+
; CHECK-NEXT: ret i1 [[COND_A]]
174+
;
175+
%s = add i64 %a, %b
176+
%cond_a = icmp ule i64 %a, %s
177+
%cond_b = icmp ule i64 %b, %s
178+
%cond = and i1 %cond_a, %cond_b
179+
ret i1 %cond
180+
}
181+
182+
define i1 @uaddo_or(i64 %a, i64 %b){
183+
; CHECK-LABEL: @uaddo_or(
184+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
185+
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
186+
; CHECK-NEXT: ret i1 [[COND_A]]
187+
;
188+
%s = add i64 %a, %b
189+
%cond_a = icmp ult i64 %s, %a
190+
%cond_b = icmp ult i64 %s, %b
191+
%cond = or i1 %cond_a, %cond_b
192+
ret i1 %cond
193+
}
194+
195+
define i1 @uaddo_or_commuted1(i64 %a, i64 %b){
196+
; CHECK-LABEL: @uaddo_or_commuted1(
197+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
198+
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
199+
; CHECK-NEXT: ret i1 [[COND_A]]
200+
;
201+
%s = add i64 %a, %b
202+
%cond_a = icmp ugt i64 %a, %s
203+
%cond_b = icmp ult i64 %s, %b
204+
%cond = or i1 %cond_a, %cond_b
205+
ret i1 %cond
206+
}
207+
208+
define i1 @uaddo_or_commuted2(i64 %a, i64 %b){
209+
; CHECK-LABEL: @uaddo_or_commuted2(
210+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
211+
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
212+
; CHECK-NEXT: ret i1 [[COND_A]]
213+
;
214+
%s = add i64 %a, %b
215+
%cond_a = icmp ult i64 %s, %a
216+
%cond_b = icmp ugt i64 %b, %s
217+
%cond = or i1 %cond_a, %cond_b
218+
ret i1 %cond
219+
}
220+
221+
define i1 @uaddo_or_commuted3(i64 %a, i64 %b){
222+
; CHECK-LABEL: @uaddo_or_commuted3(
223+
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
224+
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
225+
; CHECK-NEXT: ret i1 [[COND_A]]
226+
;
227+
%s = add i64 %a, %b
228+
%cond_a = icmp ugt i64 %a, %s
229+
%cond_b = icmp ugt i64 %b, %s
230+
%cond = or i1 %cond_a, %cond_b
231+
ret i1 %cond
232+
}

0 commit comments

Comments
 (0)