Skip to content

Commit 716f7e2

Browse files
committed
[SimplifyCFG] Add tests for switch over cmp intrinsic (NFC)
1 parent 9ff0468 commit 716f7e2

File tree

1 file changed

+384
-0
lines changed

1 file changed

+384
-0
lines changed
Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3+
4+
define void @ucmp_gt1(i32 %a, i32 %b) {
5+
; CHECK-LABEL: define void @ucmp_gt1(
6+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
7+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
8+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
9+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
10+
; CHECK-NEXT: i8 0, label %[[BB2]]
11+
; CHECK-NEXT: ]
12+
; CHECK: [[BB1]]:
13+
; CHECK-NEXT: call void @foo()
14+
; CHECK-NEXT: br label %[[BB2]]
15+
; CHECK: [[BB2]]:
16+
; CHECK-NEXT: ret void
17+
;
18+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
19+
switch i8 %res, label %bb1 [
20+
i8 -1, label %bb2
21+
i8 0, label %bb2
22+
]
23+
24+
bb1:
25+
call void @foo()
26+
br label %bb2
27+
28+
bb2:
29+
ret void
30+
}
31+
32+
define void @ucmp_gt2(i32 %a, i32 %b) {
33+
; CHECK-LABEL: define void @ucmp_gt2(
34+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
35+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
36+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
37+
; CHECK-NEXT: i8 0, label %[[BB2:.*]]
38+
; CHECK-NEXT: i8 -1, label %[[BB2]]
39+
; CHECK-NEXT: ]
40+
; CHECK: [[BB1]]:
41+
; CHECK-NEXT: call void @foo()
42+
; CHECK-NEXT: br label %[[BB2]]
43+
; CHECK: [[BB2]]:
44+
; CHECK-NEXT: ret void
45+
;
46+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
47+
switch i8 %res, label %bb1 [
48+
i8 0, label %bb2
49+
i8 -1, label %bb2
50+
]
51+
52+
bb1:
53+
call void @foo()
54+
br label %bb2
55+
56+
bb2:
57+
ret void
58+
}
59+
60+
define void @ucmp_lt1(i32 %a, i32 %b) {
61+
; CHECK-LABEL: define void @ucmp_lt1(
62+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
63+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
64+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB2:.*]] [
65+
; CHECK-NEXT: i8 1, label %[[BB1:.*]]
66+
; CHECK-NEXT: i8 0, label %[[BB1]]
67+
; CHECK-NEXT: ]
68+
; CHECK: [[BB1]]:
69+
; CHECK-NEXT: call void @foo()
70+
; CHECK-NEXT: br label %[[BB2]]
71+
; CHECK: [[BB2]]:
72+
; CHECK-NEXT: ret void
73+
;
74+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
75+
switch i8 %res, label %bb2 [
76+
i8 1, label %bb1
77+
i8 0, label %bb1
78+
]
79+
80+
bb1:
81+
call void @foo()
82+
br label %bb2
83+
84+
bb2:
85+
ret void
86+
}
87+
88+
define void @ucmp_lt2(i32 %a, i32 %b) {
89+
; CHECK-LABEL: define void @ucmp_lt2(
90+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
91+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
92+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB2:.*]] [
93+
; CHECK-NEXT: i8 0, label %[[BB1:.*]]
94+
; CHECK-NEXT: i8 1, label %[[BB1]]
95+
; CHECK-NEXT: ]
96+
; CHECK: [[BB1]]:
97+
; CHECK-NEXT: call void @foo()
98+
; CHECK-NEXT: br label %[[BB2]]
99+
; CHECK: [[BB2]]:
100+
; CHECK-NEXT: ret void
101+
;
102+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
103+
switch i8 %res, label %bb2 [
104+
i8 0, label %bb1
105+
i8 1, label %bb1
106+
]
107+
108+
bb1:
109+
call void @foo()
110+
br label %bb2
111+
112+
bb2:
113+
ret void
114+
}
115+
116+
define void @ucmp_eq1(i32 %a, i32 %b) {
117+
; CHECK-LABEL: define void @ucmp_eq1(
118+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
119+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
120+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
121+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
122+
; CHECK-NEXT: i8 1, label %[[BB2]]
123+
; CHECK-NEXT: ]
124+
; CHECK: [[BB1]]:
125+
; CHECK-NEXT: call void @foo()
126+
; CHECK-NEXT: br label %[[BB2]]
127+
; CHECK: [[BB2]]:
128+
; CHECK-NEXT: ret void
129+
;
130+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
131+
switch i8 %res, label %bb1 [
132+
i8 -1, label %bb2
133+
i8 1, label %bb2
134+
]
135+
136+
bb1:
137+
call void @foo()
138+
br label %bb2
139+
140+
bb2:
141+
ret void
142+
}
143+
144+
define void @ucmp_eq2(i32 %a, i32 %b) {
145+
; CHECK-LABEL: define void @ucmp_eq2(
146+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
147+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
148+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
149+
; CHECK-NEXT: i8 1, label %[[BB2:.*]]
150+
; CHECK-NEXT: i8 -1, label %[[BB2]]
151+
; CHECK-NEXT: ]
152+
; CHECK: [[BB1]]:
153+
; CHECK-NEXT: call void @foo()
154+
; CHECK-NEXT: br label %[[BB2]]
155+
; CHECK: [[BB2]]:
156+
; CHECK-NEXT: ret void
157+
;
158+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
159+
switch i8 %res, label %bb1 [
160+
i8 1, label %bb2
161+
i8 -1, label %bb2
162+
]
163+
164+
bb1:
165+
call void @foo()
166+
br label %bb2
167+
168+
bb2:
169+
ret void
170+
}
171+
172+
define void @scmp_gt1(i32 %a, i32 %b) {
173+
; CHECK-LABEL: define void @scmp_gt1(
174+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
175+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
176+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
177+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
178+
; CHECK-NEXT: i8 0, label %[[BB2]]
179+
; CHECK-NEXT: ]
180+
; CHECK: [[BB1]]:
181+
; CHECK-NEXT: call void @foo()
182+
; CHECK-NEXT: br label %[[BB2]]
183+
; CHECK: [[BB2]]:
184+
; CHECK-NEXT: ret void
185+
;
186+
%res = call i8 @llvm.scmp.i8.i32(i32 %a, i32 %b)
187+
switch i8 %res, label %bb1 [
188+
i8 -1, label %bb2
189+
i8 0, label %bb2
190+
]
191+
192+
bb1:
193+
call void @foo()
194+
br label %bb2
195+
196+
bb2:
197+
ret void
198+
}
199+
200+
define void @scmp_gt2(i32 %a, i32 %b) {
201+
; CHECK-LABEL: define void @scmp_gt2(
202+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
203+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
204+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
205+
; CHECK-NEXT: i8 0, label %[[BB2:.*]]
206+
; CHECK-NEXT: i8 -1, label %[[BB2]]
207+
; CHECK-NEXT: ]
208+
; CHECK: [[BB1]]:
209+
; CHECK-NEXT: call void @foo()
210+
; CHECK-NEXT: br label %[[BB2]]
211+
; CHECK: [[BB2]]:
212+
; CHECK-NEXT: ret void
213+
;
214+
%res = call i8 @llvm.scmp.i8.i32(i32 %a, i32 %b)
215+
switch i8 %res, label %bb1 [
216+
i8 0, label %bb2
217+
i8 -1, label %bb2
218+
]
219+
220+
bb1:
221+
call void @foo()
222+
br label %bb2
223+
224+
bb2:
225+
ret void
226+
}
227+
228+
define void @ucmp_gt_multiuse(i32 %a, i32 %b) {
229+
; CHECK-LABEL: define void @ucmp_gt_multiuse(
230+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
231+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
232+
; CHECK-NEXT: call void @use(i8 [[RES]])
233+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
234+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
235+
; CHECK-NEXT: i8 0, label %[[BB2]]
236+
; CHECK-NEXT: ]
237+
; CHECK: [[BB1]]:
238+
; CHECK-NEXT: call void @foo()
239+
; CHECK-NEXT: br label %[[BB2]]
240+
; CHECK: [[BB2]]:
241+
; CHECK-NEXT: ret void
242+
;
243+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
244+
call void @use(i8 %res)
245+
switch i8 %res, label %bb1 [
246+
i8 -1, label %bb2
247+
i8 0, label %bb2
248+
]
249+
250+
bb1:
251+
call void @foo()
252+
br label %bb2
253+
254+
bb2:
255+
ret void
256+
}
257+
258+
define i32 @ucmp_gt_phi(i32 %a, i32 %b) {
259+
; CHECK-LABEL: define i32 @ucmp_gt_phi(
260+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
261+
; CHECK-NEXT: [[ENTRY:.*]]:
262+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
263+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
264+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
265+
; CHECK-NEXT: i8 0, label %[[BB2]]
266+
; CHECK-NEXT: ]
267+
; CHECK: [[BB1]]:
268+
; CHECK-NEXT: call void @foo()
269+
; CHECK-NEXT: br label %[[BB2]]
270+
; CHECK: [[BB2]]:
271+
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[BB1]] ], [ 1, %[[ENTRY]] ], [ 1, %[[ENTRY]] ]
272+
; CHECK-NEXT: ret i32 [[PHI]]
273+
;
274+
entry:
275+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
276+
switch i8 %res, label %bb1 [
277+
i8 -1, label %bb2
278+
i8 0, label %bb2
279+
]
280+
281+
bb1:
282+
call void @foo()
283+
br label %bb2
284+
285+
bb2:
286+
%phi = phi i32 [ 0, %bb1 ], [ 1, %entry ], [ 1, %entry ]
287+
ret i32 %phi
288+
}
289+
290+
define void @ucmp_gt_extra_case(i32 %a, i32 %b) {
291+
; CHECK-LABEL: define void @ucmp_gt_extra_case(
292+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
293+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
294+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
295+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
296+
; CHECK-NEXT: i8 0, label %[[BB2]]
297+
; CHECK-NEXT: i8 1, label %[[BB2]]
298+
; CHECK-NEXT: ]
299+
; CHECK: [[BB1]]:
300+
; CHECK-NEXT: call void @foo()
301+
; CHECK-NEXT: br label %[[BB2]]
302+
; CHECK: [[BB2]]:
303+
; CHECK-NEXT: ret void
304+
;
305+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
306+
switch i8 %res, label %bb1 [
307+
i8 -1, label %bb2
308+
i8 0, label %bb2
309+
i8 1, label %bb2
310+
]
311+
312+
bb1:
313+
call void @foo()
314+
br label %bb2
315+
316+
bb2:
317+
ret void
318+
}
319+
320+
define void @ucmp_gt_wrong_case(i32 %a, i32 %b) {
321+
; CHECK-LABEL: define void @ucmp_gt_wrong_case(
322+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
323+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
324+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
325+
; CHECK-NEXT: i8 -2, label %[[BB2:.*]]
326+
; CHECK-NEXT: i8 0, label %[[BB2]]
327+
; CHECK-NEXT: ]
328+
; CHECK: [[BB1]]:
329+
; CHECK-NEXT: call void @foo()
330+
; CHECK-NEXT: br label %[[BB2]]
331+
; CHECK: [[BB2]]:
332+
; CHECK-NEXT: ret void
333+
;
334+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
335+
switch i8 %res, label %bb1 [
336+
i8 -2, label %bb2
337+
i8 0, label %bb2
338+
]
339+
340+
bb1:
341+
call void @foo()
342+
br label %bb2
343+
344+
bb2:
345+
ret void
346+
}
347+
348+
define void @ucmp_gt_not_same_succ(i32 %a, i32 %b) {
349+
; CHECK-LABEL: define void @ucmp_gt_not_same_succ(
350+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
351+
; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
352+
; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [
353+
; CHECK-NEXT: i8 -1, label %[[BB2:.*]]
354+
; CHECK-NEXT: i8 0, label %[[BB3:.*]]
355+
; CHECK-NEXT: ]
356+
; CHECK: [[BB1]]:
357+
; CHECK-NEXT: call void @foo()
358+
; CHECK-NEXT: br label %[[BB2]]
359+
; CHECK: [[BB3]]:
360+
; CHECK-NEXT: call void @foo()
361+
; CHECK-NEXT: br label %[[BB2]]
362+
; CHECK: [[BB2]]:
363+
; CHECK-NEXT: ret void
364+
;
365+
%res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
366+
switch i8 %res, label %bb1 [
367+
i8 -1, label %bb2
368+
i8 0, label %bb3
369+
]
370+
371+
bb1:
372+
call void @foo()
373+
br label %bb2
374+
375+
bb3:
376+
call void @foo()
377+
br label %bb2
378+
379+
bb2:
380+
ret void
381+
}
382+
383+
declare void @use(i8)
384+
declare void @foo()

0 commit comments

Comments
 (0)