1; Test conditional sibling calls.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5
6@var = global i32 1;
7@fun_a = global void()* null;
8@fun_b = global void()* null;
9@fun_c = global void(i32)* null;
10
11; Check a conditional sibling call.
12define void @f1(i32 %val1, i32 %val2) {
13; CHECK-LABEL: f1:
14; CHECK: crbl %r2, %r3, 0(%r1)
15; CHECK: br %r14
16  %fun_a = load volatile void() *, void()** @fun_a;
17  %cond = icmp slt i32 %val1, %val2;
18  br i1 %cond, label %a, label %b;
19
20a:
21  tail call void %fun_a()
22  ret void
23
24b:
25  store i32 1, i32 *@var;
26  ret void
27}
28
29; Check a conditional sibling call when there are two possibilities.
30define void @f2(i32 %val1, i32 %val2) {
31; CHECK-LABEL: f2:
32; CHECK: crbl %r2, %r3, 0(%r1)
33; CHECK: br %r1
34  %fun_a = load volatile void() *, void()** @fun_a;
35  %fun_b = load volatile void() *, void()** @fun_b;
36  %cond = icmp slt i32 %val1, %val2;
37  br i1 %cond, label %a, label %b;
38
39a:
40  tail call void %fun_a()
41  ret void
42
43b:
44  tail call void %fun_b()
45  ret void
46}
47
48; Check a conditional sibling call with an argument - not supported.
49define void @f3(i32 %val1, i32 %val2) {
50; CHECK-LABEL: f3:
51; CHECK: crjhe %r2, %r3
52; CHECK: br %r1
53; CHECK: br %r14
54  %fun_c = load volatile void(i32) *, void(i32)** @fun_c;
55  %cond = icmp slt i32 %val1, %val2;
56  br i1 %cond, label %a, label %b;
57
58a:
59  tail call void %fun_c(i32 1)
60  ret void
61
62b:
63  store i32 1, i32 *@var;
64  ret void
65}
66
67; Check a conditional sibling call - unsigned compare.
68define void @f4(i32 %val1, i32 %val2) {
69; CHECK-LABEL: f4:
70; CHECK: clrbl %r2, %r3, 0(%r1)
71; CHECK: br %r14
72  %fun_a = load volatile void() *, void()** @fun_a;
73  %cond = icmp ult i32 %val1, %val2;
74  br i1 %cond, label %a, label %b;
75
76a:
77  tail call void %fun_a()
78  ret void
79
80b:
81  store i32 1, i32 *@var;
82  ret void
83}
84
85; Check a conditional sibling call - 64-bit compare.
86define void @f5(i64 %val1, i64 %val2) {
87; CHECK-LABEL: f5:
88; CHECK: cgrbl %r2, %r3, 0(%r1)
89; CHECK: br %r14
90  %fun_a = load volatile void() *, void()** @fun_a;
91  %cond = icmp slt i64 %val1, %val2;
92  br i1 %cond, label %a, label %b;
93
94a:
95  tail call void %fun_a()
96  ret void
97
98b:
99  store i32 1, i32 *@var;
100  ret void
101}
102
103; Check a conditional sibling call - unsigned 64-bit compare.
104define void @f6(i64 %val1, i64 %val2) {
105; CHECK-LABEL: f6:
106; CHECK: clgrbl %r2, %r3, 0(%r1)
107; CHECK: br %r14
108  %fun_a = load volatile void() *, void()** @fun_a;
109  %cond = icmp ult i64 %val1, %val2;
110  br i1 %cond, label %a, label %b;
111
112a:
113  tail call void %fun_a()
114  ret void
115
116b:
117  store i32 1, i32 *@var;
118  ret void
119}
120
121; Check a conditional sibling call - less-equal compare.
122define void @f7(i32 %val1, i32 %val2) {
123; CHECK-LABEL: f7:
124; CHECK: crble %r2, %r3, 0(%r1)
125; CHECK: br %r14
126  %fun_a = load volatile void() *, void()** @fun_a;
127  %cond = icmp sle i32 %val1, %val2;
128  br i1 %cond, label %a, label %b;
129
130a:
131  tail call void %fun_a()
132  ret void
133
134b:
135  store i32 1, i32 *@var;
136  ret void
137}
138
139; Check a conditional sibling call - high compare.
140define void @f8(i32 %val1, i32 %val2) {
141; CHECK-LABEL: f8:
142; CHECK: crbh %r2, %r3, 0(%r1)
143; CHECK: br %r14
144  %fun_a = load volatile void() *, void()** @fun_a;
145  %cond = icmp sgt i32 %val1, %val2;
146  br i1 %cond, label %a, label %b;
147
148a:
149  tail call void %fun_a()
150  ret void
151
152b:
153  store i32 1, i32 *@var;
154  ret void
155}
156
157; Check a conditional sibling call - high-equal compare.
158define void @f9(i32 %val1, i32 %val2) {
159; CHECK-LABEL: f9:
160; CHECK: crbhe %r2, %r3, 0(%r1)
161; CHECK: br %r14
162  %fun_a = load volatile void() *, void()** @fun_a;
163  %cond = icmp sge i32 %val1, %val2;
164  br i1 %cond, label %a, label %b;
165
166a:
167  tail call void %fun_a()
168  ret void
169
170b:
171  store i32 1, i32 *@var;
172  ret void
173}
174
175; Check a conditional sibling call - equal compare.
176define void @f10(i32 %val1, i32 %val2) {
177; CHECK-LABEL: f10:
178; CHECK: crbe %r2, %r3, 0(%r1)
179; CHECK: br %r14
180  %fun_a = load volatile void() *, void()** @fun_a;
181  %cond = icmp eq i32 %val1, %val2;
182  br i1 %cond, label %a, label %b;
183
184a:
185  tail call void %fun_a()
186  ret void
187
188b:
189  store i32 1, i32 *@var;
190  ret void
191}
192
193; Check a conditional sibling call - unequal compare.
194define void @f11(i32 %val1, i32 %val2) {
195; CHECK-LABEL: f11:
196; CHECK: crblh %r2, %r3, 0(%r1)
197; CHECK: br %r14
198  %fun_a = load volatile void() *, void()** @fun_a;
199  %cond = icmp ne i32 %val1, %val2;
200  br i1 %cond, label %a, label %b;
201
202a:
203  tail call void %fun_a()
204  ret void
205
206b:
207  store i32 1, i32 *@var;
208  ret void
209}
210
211; Check a conditional sibling call - immediate slt.
212define void @f12(i32 %val1) {
213; CHECK-LABEL: f12:
214; CHECK: cible %r2, 4, 0(%r1)
215; CHECK: br %r14
216  %fun_a = load volatile void() *, void()** @fun_a;
217  %cond = icmp slt i32 %val1, 5;
218  br i1 %cond, label %a, label %b;
219
220a:
221  tail call void %fun_a()
222  ret void
223
224b:
225  store i32 1, i32 *@var;
226  ret void
227}
228
229; Check a conditional sibling call - immediate sle.
230define void @f13(i32 %val1) {
231; CHECK-LABEL: f13:
232; CHECK: cible %r2, 5, 0(%r1)
233; CHECK: br %r14
234  %fun_a = load volatile void() *, void()** @fun_a;
235  %cond = icmp sle i32 %val1, 5;
236  br i1 %cond, label %a, label %b;
237
238a:
239  tail call void %fun_a()
240  ret void
241
242b:
243  store i32 1, i32 *@var;
244  ret void
245}
246
247; Check a conditional sibling call - immediate sgt.
248define void @f14(i32 %val1) {
249; CHECK-LABEL: f14:
250; CHECK: cibhe %r2, 6, 0(%r1)
251; CHECK: br %r14
252  %fun_a = load volatile void() *, void()** @fun_a;
253  %cond = icmp sgt i32 %val1, 5;
254  br i1 %cond, label %a, label %b;
255
256a:
257  tail call void %fun_a()
258  ret void
259
260b:
261  store i32 1, i32 *@var;
262  ret void
263}
264
265; Check a conditional sibling call - immediate sge.
266define void @f15(i32 %val1) {
267; CHECK-LABEL: f15:
268; CHECK: cibhe %r2, 5, 0(%r1)
269; CHECK: br %r14
270  %fun_a = load volatile void() *, void()** @fun_a;
271  %cond = icmp sge i32 %val1, 5;
272  br i1 %cond, label %a, label %b;
273
274a:
275  tail call void %fun_a()
276  ret void
277
278b:
279  store i32 1, i32 *@var;
280  ret void
281}
282
283; Check a conditional sibling call - immediate eq.
284define void @f16(i32 %val1) {
285; CHECK-LABEL: f16:
286; CHECK: cibe %r2, 5, 0(%r1)
287; CHECK: br %r14
288  %fun_a = load volatile void() *, void()** @fun_a;
289  %cond = icmp eq i32 %val1, 5;
290  br i1 %cond, label %a, label %b;
291
292a:
293  tail call void %fun_a()
294  ret void
295
296b:
297  store i32 1, i32 *@var;
298  ret void
299}
300
301; Check a conditional sibling call - immediate ne.
302define void @f17(i32 %val1) {
303; CHECK-LABEL: f17:
304; CHECK: ciblh %r2, 5, 0(%r1)
305; CHECK: br %r14
306  %fun_a = load volatile void() *, void()** @fun_a;
307  %cond = icmp ne i32 %val1, 5;
308  br i1 %cond, label %a, label %b;
309
310a:
311  tail call void %fun_a()
312  ret void
313
314b:
315  store i32 1, i32 *@var;
316  ret void
317}
318
319; Check a conditional sibling call - immediate ult.
320define void @f18(i32 %val1) {
321; CHECK-LABEL: f18:
322; CHECK: clible %r2, 4, 0(%r1)
323; CHECK: br %r14
324  %fun_a = load volatile void() *, void()** @fun_a;
325  %cond = icmp ult i32 %val1, 5;
326  br i1 %cond, label %a, label %b;
327
328a:
329  tail call void %fun_a()
330  ret void
331
332b:
333  store i32 1, i32 *@var;
334  ret void
335}
336
337; Check a conditional sibling call - immediate 64-bit slt.
338define void @f19(i64 %val1) {
339; CHECK-LABEL: f19:
340; CHECK: cgible %r2, 4, 0(%r1)
341; CHECK: br %r14
342  %fun_a = load volatile void() *, void()** @fun_a;
343  %cond = icmp slt i64 %val1, 5;
344  br i1 %cond, label %a, label %b;
345
346a:
347  tail call void %fun_a()
348  ret void
349
350b:
351  store i32 1, i32 *@var;
352  ret void
353}
354
355; Check a conditional sibling call - immediate 64-bit ult.
356define void @f20(i64 %val1) {
357; CHECK-LABEL: f20:
358; CHECK: clgible %r2, 4, 0(%r1)
359; CHECK: br %r14
360  %fun_a = load volatile void() *, void()** @fun_a;
361  %cond = icmp ult i64 %val1, 5;
362  br i1 %cond, label %a, label %b;
363
364a:
365  tail call void %fun_a()
366  ret void
367
368b:
369  store i32 1, i32 *@var;
370  ret void
371}
372
373; Check a conditional sibling call to an argument - will fail due to
374; intervening lgr.
375define void @f21(i32 %val1, i32 %val2, void()* %fun) {
376; CHECK-LABEL: f21:
377; CHECK: crjhe %r2, %r3
378; CHECK: lgr %r1, %r4
379; CHECK: br %r1
380; CHECK: br %r14
381  %cond = icmp slt i32 %val1, %val2;
382  br i1 %cond, label %a, label %b;
383
384a:
385  tail call void %fun()
386  ret void
387
388b:
389  store i32 1, i32 *@var;
390  ret void
391}
392
393; Check a conditional sibling call - float olt compare.
394define void @f22(float %val1, float %val2) {
395; CHECK-LABEL: f22:
396; CHECK: cebr %f0, %f2
397; CHECK: blr %r1
398; CHECK: br %r14
399  %fun_a = load volatile void() *, void()** @fun_a;
400  %cond = fcmp olt float %val1, %val2;
401  br i1 %cond, label %a, label %b;
402
403a:
404  tail call void %fun_a()
405  ret void
406
407b:
408  store i32 1, i32 *@var;
409  ret void
410}
411
412; Check a conditional sibling call - float ult compare.
413define void @f23(float %val1, float %val2) {
414; CHECK-LABEL: f23:
415; CHECK: cebr %f0, %f2
416; CHECK: bnher %r1
417; CHECK: br %r14
418  %fun_a = load volatile void() *, void()** @fun_a;
419  %cond = fcmp ult float %val1, %val2;
420  br i1 %cond, label %a, label %b;
421
422a:
423  tail call void %fun_a()
424  ret void
425
426b:
427  store i32 1, i32 *@var;
428  ret void
429}
430
431; Check a conditional sibling call - float ord compare.
432define void @f24(float %val1, float %val2) {
433; CHECK-LABEL: f24:
434; CHECK: cebr %f0, %f2
435; CHECK: bnor %r1
436; CHECK: br %r14
437  %fun_a = load volatile void() *, void()** @fun_a;
438  %cond = fcmp ord float %val1, %val2;
439  br i1 %cond, label %a, label %b;
440
441a:
442  tail call void %fun_a()
443  ret void
444
445b:
446  store i32 1, i32 *@var;
447  ret void
448}
449
450; Check a conditional sibling call - float uno compare.
451define void @f25(float %val1, float %val2) {
452; CHECK-LABEL: f25:
453; CHECK: cebr %f0, %f2
454; CHECK: bor %r1
455; CHECK: br %r14
456  %fun_a = load volatile void() *, void()** @fun_a;
457  %cond = fcmp uno float %val1, %val2;
458  br i1 %cond, label %a, label %b;
459
460a:
461  tail call void %fun_a()
462  ret void
463
464b:
465  store i32 1, i32 *@var;
466  ret void
467}
468