Skip to content

Commit f623df6

Browse files
committed
[InstSimplify] Add tests for monotonic icmps (NFC)
1 parent 66d350a commit f623df6

File tree

1 file changed

+242
-0
lines changed

1 file changed

+242
-0
lines changed
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
3+
4+
define i1 @lshr_or_ule(i32 %x, i32 %y, i32 %z) {
5+
; CHECK-LABEL: define i1 @lshr_or_ule(
6+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
7+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
8+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
9+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
10+
; CHECK-NEXT: ret i1 [[CMP]]
11+
;
12+
%op1 = lshr i32 %x, %y
13+
%op2 = or i32 %x, %z
14+
%cmp = icmp ule i32 %op1, %op2
15+
ret i1 %cmp
16+
}
17+
18+
define i1 @lshr_or_uge_swapped(i32 %x, i32 %y, i32 %z) {
19+
; CHECK-LABEL: define i1 @lshr_or_uge_swapped(
20+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
21+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
22+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
23+
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[OP2]], [[OP1]]
24+
; CHECK-NEXT: ret i1 [[CMP]]
25+
;
26+
%op1 = lshr i32 %x, %y
27+
%op2 = or i32 %x, %z
28+
%cmp = icmp uge i32 %op2, %op1
29+
ret i1 %cmp
30+
}
31+
32+
define i1 @lshr_or_ugt(i32 %x, i32 %y, i32 %z) {
33+
; CHECK-LABEL: define i1 @lshr_or_ugt(
34+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
35+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
36+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
37+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OP1]], [[OP2]]
38+
; CHECK-NEXT: ret i1 [[CMP]]
39+
;
40+
%op1 = lshr i32 %x, %y
41+
%op2 = or i32 %x, %z
42+
%cmp = icmp ugt i32 %op1, %op2
43+
ret i1 %cmp
44+
}
45+
46+
define i1 @lshr_or_ult_wrong_pred(i32 %x, i32 %y, i32 %z) {
47+
; CHECK-LABEL: define i1 @lshr_or_ult_wrong_pred(
48+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
49+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
50+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
51+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[OP1]], [[OP2]]
52+
; CHECK-NEXT: ret i1 [[CMP]]
53+
;
54+
%op1 = lshr i32 %x, %y
55+
%op2 = or i32 %x, %z
56+
%cmp = icmp ult i32 %op1, %op2
57+
ret i1 %cmp
58+
}
59+
60+
define i1 @lshr_or_sle_wrong_pred(i32 %x, i32 %y, i32 %z) {
61+
; CHECK-LABEL: define i1 @lshr_or_sle_wrong_pred(
62+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
63+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
64+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
65+
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[OP1]], [[OP2]]
66+
; CHECK-NEXT: ret i1 [[CMP]]
67+
;
68+
%op1 = lshr i32 %x, %y
69+
%op2 = or i32 %x, %z
70+
%cmp = icmp sle i32 %op1, %op2
71+
ret i1 %cmp
72+
}
73+
74+
define i1 @lshr_or_swapped_ule(i32 %x, i32 %y, i32 %z) {
75+
; CHECK-LABEL: define i1 @lshr_or_swapped_ule(
76+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
77+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
78+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[Z]], [[X]]
79+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
80+
; CHECK-NEXT: ret i1 [[CMP]]
81+
;
82+
%op1 = lshr i32 %x, %y
83+
%op2 = or i32 %z, %x
84+
%cmp = icmp ule i32 %op1, %op2
85+
ret i1 %cmp
86+
}
87+
88+
define i1 @lshr_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
89+
; CHECK-LABEL: define i1 @lshr_or_ule_invalid_swapped(
90+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
91+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[Y]], [[X]]
92+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
93+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
94+
; CHECK-NEXT: ret i1 [[CMP]]
95+
;
96+
%op1 = lshr i32 %y, %x
97+
%op2 = or i32 %x, %z
98+
%cmp = icmp ule i32 %op1, %op2
99+
ret i1 %cmp
100+
}
101+
102+
define i1 @and_uadd_sat_ule(i32 %x, i32 %y, i32 %z) {
103+
; CHECK-LABEL: define i1 @and_uadd_sat_ule(
104+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
105+
; CHECK-NEXT: [[OP1:%.*]] = and i32 [[X]], [[Y]]
106+
; CHECK-NEXT: [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
107+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
108+
; CHECK-NEXT: ret i1 [[CMP]]
109+
;
110+
%op1 = and i32 %x, %y
111+
%op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
112+
%cmp = icmp ule i32 %op1, %op2
113+
ret i1 %cmp
114+
}
115+
116+
define i1 @urem_or_ule(i32 %x, i32 %y, i32 %z) {
117+
; CHECK-LABEL: define i1 @urem_or_ule(
118+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
119+
; CHECK-NEXT: [[OP1:%.*]] = urem i32 [[X]], [[Y]]
120+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
121+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
122+
; CHECK-NEXT: ret i1 [[CMP]]
123+
;
124+
%op1 = urem i32 %x, %y
125+
%op2 = or i32 %x, %z
126+
%cmp = icmp ule i32 %op1, %op2
127+
ret i1 %cmp
128+
}
129+
130+
define i1 @urem_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
131+
; CHECK-LABEL: define i1 @urem_or_ule_invalid_swapped(
132+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
133+
; CHECK-NEXT: [[OP1:%.*]] = urem i32 [[Y]], [[X]]
134+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
135+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
136+
; CHECK-NEXT: ret i1 [[CMP]]
137+
;
138+
%op1 = urem i32 %y, %x
139+
%op2 = or i32 %x, %z
140+
%cmp = icmp ule i32 %op1, %op2
141+
ret i1 %cmp
142+
}
143+
144+
define i1 @udiv_or_ule(i32 %x, i32 %y, i32 %z) {
145+
; CHECK-LABEL: define i1 @udiv_or_ule(
146+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
147+
; CHECK-NEXT: [[OP1:%.*]] = udiv i32 [[X]], [[Y]]
148+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
149+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
150+
; CHECK-NEXT: ret i1 [[CMP]]
151+
;
152+
%op1 = udiv i32 %x, %y
153+
%op2 = or i32 %x, %z
154+
%cmp = icmp ule i32 %op1, %op2
155+
ret i1 %cmp
156+
}
157+
158+
define i1 @udiv_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
159+
; CHECK-LABEL: define i1 @udiv_or_ule_invalid_swapped(
160+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
161+
; CHECK-NEXT: [[OP1:%.*]] = udiv i32 [[Y]], [[X]]
162+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
163+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
164+
; CHECK-NEXT: ret i1 [[CMP]]
165+
;
166+
%op1 = udiv i32 %y, %x
167+
%op2 = or i32 %x, %z
168+
%cmp = icmp ule i32 %op1, %op2
169+
ret i1 %cmp
170+
}
171+
172+
define i1 @usub_sat_uadd_sat_ule(i32 %x, i32 %y, i32 %z) {
173+
; CHECK-LABEL: define i1 @usub_sat_uadd_sat_ule(
174+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
175+
; CHECK-NEXT: [[OP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X]], i32 [[Y]])
176+
; CHECK-NEXT: [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
177+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
178+
; CHECK-NEXT: ret i1 [[CMP]]
179+
;
180+
%op1 = call i32 @llvm.usub.sat(i32 %x, i32 %y)
181+
%op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
182+
%cmp = icmp ule i32 %op1, %op2
183+
ret i1 %cmp
184+
}
185+
186+
define i1 @usub_sat_uadd_sat_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
187+
; CHECK-LABEL: define i1 @usub_sat_uadd_sat_ule_invalid_swapped(
188+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
189+
; CHECK-NEXT: [[OP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[Y]], i32 [[X]])
190+
; CHECK-NEXT: [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
191+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
192+
; CHECK-NEXT: ret i1 [[CMP]]
193+
;
194+
%op1 = call i32 @llvm.usub.sat(i32 %y, i32 %x)
195+
%op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
196+
%cmp = icmp ule i32 %op1, %op2
197+
ret i1 %cmp
198+
}
199+
200+
define i1 @lshr_or_ule_no_common_op(i32 %x, i32 %y, i32 %z, i32 %w) {
201+
; CHECK-LABEL: define i1 @lshr_or_ule_no_common_op(
202+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[W:%.*]]) {
203+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
204+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[W]], [[Z]]
205+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
206+
; CHECK-NEXT: ret i1 [[CMP]]
207+
;
208+
%op1 = lshr i32 %x, %y
209+
%op2 = or i32 %w, %z
210+
%cmp = icmp ule i32 %op1, %op2
211+
ret i1 %cmp
212+
}
213+
214+
define i1 @lshr_or_ule_nested(i32 %x, i32 %y, i32 %z, i32 %w) {
215+
; CHECK-LABEL: define i1 @lshr_or_ule_nested(
216+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[W:%.*]]) {
217+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
218+
; CHECK-NEXT: [[OP2:%.*]] = or i32 [[X]], [[Z]]
219+
; CHECK-NEXT: [[OP3:%.*]] = or i32 [[OP2]], [[W]]
220+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP3]]
221+
; CHECK-NEXT: ret i1 [[CMP]]
222+
;
223+
%op1 = lshr i32 %x, %y
224+
%op2 = or i32 %x, %z
225+
%op3 = or i32 %op2, %w
226+
%cmp = icmp ule i32 %op1, %op3
227+
ret i1 %cmp
228+
}
229+
230+
define i1 @lshr_add_ule_non_monotonic(i32 %x, i32 %y, i32 %z) {
231+
; CHECK-LABEL: define i1 @lshr_add_ule_non_monotonic(
232+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
233+
; CHECK-NEXT: [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
234+
; CHECK-NEXT: [[OP2:%.*]] = add i32 [[X]], [[Z]]
235+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
236+
; CHECK-NEXT: ret i1 [[CMP]]
237+
;
238+
%op1 = lshr i32 %x, %y
239+
%op2 = add i32 %x, %z
240+
%cmp = icmp ule i32 %op1, %op2
241+
ret i1 %cmp
242+
}

0 commit comments

Comments
 (0)