blob: 5218d41c6ad3b5fcc4a511893bf60ae32cbb5c35 [file] [log] [blame]
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +00001; Test that compares are ommitted if CC already has the right value
2; (z10 version).
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5
6declare void @foo()
7
8; Addition provides enough for equality comparisons with zero. First teest
9; the EQ case.
10define i32 @f1(i32 %a, i32 %b, i32 *%dest) {
11; CHECK-LABEL: f1:
12; CHECK: afi %r2, 1000000
13; CHECK-NEXT: je .L{{.*}}
14; CHECK: br %r14
15entry:
16 %res = add i32 %a, 1000000
17 %cmp = icmp eq i32 %res, 0
18 br i1 %cmp, label %exit, label %store
19
20store:
21 store i32 %b, i32 *%dest
22 br label %exit
23
24exit:
25 ret i32 %res
26}
27
28; ...and again with NE.
29define i32 @f2(i32 %a, i32 %b, i32 *%dest) {
30; CHECK-LABEL: f2:
31; CHECK: afi %r2, 1000000
32; CHECK-NEXT: jne .L{{.*}}
33; CHECK: br %r14
34entry:
35 %res = add i32 %a, 1000000
36 %cmp = icmp ne i32 %res, 0
37 br i1 %cmp, label %exit, label %store
38
39store:
40 store i32 %b, i32 *%dest
41 br label %exit
42
43exit:
44 ret i32 %res
45}
46
47; SLT requires a comparison.
48define i32 @f3(i32 %a, i32 %b, i32 *%dest) {
49; CHECK-LABEL: f3:
50; CHECK: afi %r2, 1000000
51; CHECK-NEXT: cijl %r2, 0, .L{{.*}}
52; CHECK: br %r14
53entry:
54 %res = add i32 %a, 1000000
55 %cmp = icmp slt i32 %res, 0
56 br i1 %cmp, label %exit, label %store
57
58store:
59 store i32 %b, i32 *%dest
60 br label %exit
61
62exit:
63 ret i32 %res
64}
65
66; ...SLE too.
67define i32 @f4(i32 %a, i32 %b, i32 *%dest) {
68; CHECK-LABEL: f4:
69; CHECK: afi %r2, 1000000
70; CHECK-NEXT: cijle %r2, 0, .L{{.*}}
71; CHECK: br %r14
72entry:
73 %res = add i32 %a, 1000000
74 %cmp = icmp sle i32 %res, 0
75 br i1 %cmp, label %exit, label %store
76
77store:
78 store i32 %b, i32 *%dest
79 br label %exit
80
81exit:
82 ret i32 %res
83}
84
85; ...SGT too.
86define i32 @f5(i32 %a, i32 %b, i32 *%dest) {
87; CHECK-LABEL: f5:
88; CHECK: afi %r2, 1000000
89; CHECK-NEXT: cijh %r2, 0, .L{{.*}}
90; CHECK: br %r14
91entry:
92 %res = add i32 %a, 1000000
93 %cmp = icmp sgt i32 %res, 0
94 br i1 %cmp, label %exit, label %store
95
96store:
97 store i32 %b, i32 *%dest
98 br label %exit
99
100exit:
101 ret i32 %res
102}
103
104; ...SGE too.
105define i32 @f6(i32 %a, i32 %b, i32 *%dest) {
106; CHECK-LABEL: f6:
107; CHECK: afi %r2, 1000000
108; CHECK-NEXT: cijhe %r2, 0, .L{{.*}}
109; CHECK: br %r14
110entry:
111 %res = add i32 %a, 1000000
112 %cmp = icmp sge i32 %res, 0
113 br i1 %cmp, label %exit, label %store
114
115store:
116 store i32 %b, i32 *%dest
117 br label %exit
118
119exit:
120 ret i32 %res
121}
122
123; Subtraction also provides enough for equality comparisons with zero.
124define i32 @f7(i32 %a, i32 %b, i32 *%dest) {
125; CHECK-LABEL: f7:
126; CHECK: s %r2, 0(%r4)
127; CHECK-NEXT: jne .L{{.*}}
128; CHECK: br %r14
129entry:
130 %cur = load i32 *%dest
131 %res = sub i32 %a, %cur
132 %cmp = icmp ne i32 %res, 0
133 br i1 %cmp, label %exit, label %store
134
135store:
136 store i32 %b, i32 *%dest
137 br label %exit
138
139exit:
140 ret i32 %res
141}
142
143; ...but not for ordered comparisons.
144define i32 @f8(i32 %a, i32 %b, i32 *%dest) {
145; CHECK-LABEL: f8:
146; CHECK: s %r2, 0(%r4)
147; CHECK-NEXT: cijl %r2, 0, .L{{.*}}
148; CHECK: br %r14
149entry:
150 %cur = load i32 *%dest
151 %res = sub i32 %a, %cur
152 %cmp = icmp slt i32 %res, 0
153 br i1 %cmp, label %exit, label %store
154
155store:
156 store i32 %b, i32 *%dest
157 br label %exit
158
159exit:
160 ret i32 %res
161}
162
163; Logic register-register instructions also provide enough for equality
164; comparisons with zero.
165define i32 @f9(i32 %a, i32 %b, i32 *%dest) {
166; CHECK-LABEL: f9:
167; CHECK: nr %r2, %r3
168; CHECK-NEXT: jl .L{{.*}}
169; CHECK: br %r14
170entry:
171 %res = and i32 %a, %b
172 %cmp = icmp ne i32 %res, 0
173 br i1 %cmp, label %exit, label %store
174
175store:
176 store i32 %b, i32 *%dest
177 br label %exit
178
179exit:
180 ret i32 %res
181}
182
183; ...but not for ordered comparisons.
184define i32 @f10(i32 %a, i32 %b, i32 *%dest) {
185; CHECK-LABEL: f10:
186; CHECK: nr %r2, %r3
187; CHECK-NEXT: cijl %r2, 0, .L{{.*}}
188; CHECK: br %r14
189entry:
190 %res = and i32 %a, %b
191 %cmp = icmp slt i32 %res, 0
192 br i1 %cmp, label %exit, label %store
193
194store:
195 store i32 %b, i32 *%dest
196 br label %exit
197
198exit:
199 ret i32 %res
200}
201
202; Logic register-immediate instructions also provide enough for equality
203; comparisons with zero if the immediate covers the whole register.
204define i32 @f11(i32 %a, i32 %b, i32 *%dest) {
205; CHECK-LABEL: f11:
206; CHECK: nilf %r2, 100
207; CHECK-NEXT: jl .L{{.*}}
208; CHECK: br %r14
209entry:
210 %res = and i32 %a, 100
211 %cmp = icmp ne i32 %res, 0
212 br i1 %cmp, label %exit, label %store
213
214store:
215 store i32 %b, i32 *%dest
216 br label %exit
217
218exit:
219 ret i32 %res
220}
221
222; Partial logic register-immediate instructions do not provide simple
223; zero results.
224define i32 @f12(i32 %a, i32 %b, i32 *%dest) {
225; CHECK-LABEL: f12:
226; CHECK: nill %r2, 65436
227; CHECK-NEXT: cijlh %r2, 0, .L{{.*}}
228; CHECK: br %r14
229entry:
230 %res = and i32 %a, -100
231 %cmp = icmp ne i32 %res, 0
232 br i1 %cmp, label %exit, label %store
233
234store:
235 store i32 %b, i32 *%dest
236 br label %exit
237
238exit:
239 ret i32 %res
240}
241
242; SRA provides the same CC result as a comparison with zero.
243define i32 @f13(i32 %a, i32 %b, i32 *%dest) {
244; CHECK-LABEL: f13:
245; CHECK: sra %r2, 0(%r3)
246; CHECK-NEXT: je .L{{.*}}
247; CHECK: br %r14
248entry:
249 %res = ashr i32 %a, %b
250 %cmp = icmp eq i32 %res, 0
251 br i1 %cmp, label %exit, label %store
252
253store:
254 store i32 %b, i32 *%dest
255 br label %exit
256
257exit:
258 ret i32 %res
259}
260
261; ...and again with NE.
262define i32 @f14(i32 %a, i32 %b, i32 *%dest) {
263; CHECK-LABEL: f14:
264; CHECK: sra %r2, 0(%r3)
265; CHECK-NEXT: jlh .L{{.*}}
266; CHECK: br %r14
267entry:
268 %res = ashr i32 %a, %b
269 %cmp = icmp ne i32 %res, 0
270 br i1 %cmp, label %exit, label %store
271
272store:
273 store i32 %b, i32 *%dest
274 br label %exit
275
276exit:
277 ret i32 %res
278}
279
280; ...and SLT.
281define i32 @f15(i32 %a, i32 %b, i32 *%dest) {
282; CHECK-LABEL: f15:
283; CHECK: sra %r2, 0(%r3)
284; CHECK-NEXT: jl .L{{.*}}
285; CHECK: br %r14
286entry:
287 %res = ashr i32 %a, %b
288 %cmp = icmp slt i32 %res, 0
289 br i1 %cmp, label %exit, label %store
290
291store:
292 store i32 %b, i32 *%dest
293 br label %exit
294
295exit:
296 ret i32 %res
297}
298
299; ...and SLE.
300define i32 @f16(i32 %a, i32 %b, i32 *%dest) {
301; CHECK-LABEL: f16:
302; CHECK: sra %r2, 0(%r3)
303; CHECK-NEXT: jle .L{{.*}}
304; CHECK: br %r14
305entry:
306 %res = ashr i32 %a, %b
307 %cmp = icmp sle i32 %res, 0
308 br i1 %cmp, label %exit, label %store
309
310store:
311 store i32 %b, i32 *%dest
312 br label %exit
313
314exit:
315 ret i32 %res
316}
317
318; ...and SGT.
319define i32 @f17(i32 %a, i32 %b, i32 *%dest) {
320; CHECK-LABEL: f17:
321; CHECK: sra %r2, 0(%r3)
322; CHECK-NEXT: jh .L{{.*}}
323; CHECK: br %r14
324entry:
325 %res = ashr i32 %a, %b
326 %cmp = icmp sgt i32 %res, 0
327 br i1 %cmp, label %exit, label %store
328
329store:
330 store i32 %b, i32 *%dest
331 br label %exit
332
333exit:
334 ret i32 %res
335}
336
337; ...and SGE.
338define i32 @f18(i32 %a, i32 %b, i32 *%dest) {
339; CHECK-LABEL: f18:
340; CHECK: sra %r2, 0(%r3)
341; CHECK-NEXT: jhe .L{{.*}}
342; CHECK: br %r14
343entry:
344 %res = ashr i32 %a, %b
345 %cmp = icmp sge i32 %res, 0
346 br i1 %cmp, label %exit, label %store
347
348store:
349 store i32 %b, i32 *%dest
350 br label %exit
351
352exit:
353 ret i32 %res
354}
355
356; RISBG provides the same result as a comparison against zero.
357; Test the EQ case.
358define i64 @f19(i64 %a, i64 %b, i64 *%dest) {
359; CHECK-LABEL: f19:
360; CHECK: risbg %r2, %r3, 0, 190, 0
361; CHECK-NEXT: je .L{{.*}}
362; CHECK: br %r14
363entry:
364 %res = and i64 %b, -2
365 %cmp = icmp eq i64 %res, 0
366 br i1 %cmp, label %exit, label %store
367
368store:
369 store i64 %b, i64 *%dest
370 br label %exit
371
372exit:
373 ret i64 %res
374}
375
376; ...and the SLT case.
377define i64 @f20(i64 %a, i64 %b, i64 *%dest) {
378; CHECK-LABEL: f20:
379; CHECK: risbg %r2, %r3, 0, 190, 0
380; CHECK-NEXT: jl .L{{.*}}
381; CHECK: br %r14
382entry:
383 %res = and i64 %b, -2
384 %cmp = icmp slt i64 %res, 0
385 br i1 %cmp, label %exit, label %store
386
387store:
388 store i64 %b, i64 *%dest
389 br label %exit
390
391exit:
392 ret i64 %res
393}
394
395; Test a case where the register we're testing is set by a non-CC-clobbering
396; instruction.
397define i32 @f21(i32 %a, i32 %b, i32 *%dest) {
398; CHECK-LABEL: f21:
399; CHECK: afi %r2, 1000000
400; CHECK-NEXT: #APP
401; CHECK-NEXT: blah %r2
402; CHECK-NEXT: #NO_APP
403; CHECK-NEXT: cije %r2, 0, .L{{.*}}
404; CHECK: br %r14
405entry:
406 %add = add i32 %a, 1000000
407 %res = call i32 asm "blah $0", "=r,0" (i32 %add)
408 %cmp = icmp eq i32 %res, 0
409 br i1 %cmp, label %exit, label %store
410
411store:
412 store i32 %b, i32 *%dest
413 br label %exit
414
415exit:
416 ret i32 %res
417}
418
419; ...and again with a CC-clobbering instruction.
420define i32 @f22(i32 %a, i32 %b, i32 *%dest) {
421; CHECK-LABEL: f22:
422; CHECK: afi %r2, 1000000
423; CHECK-NEXT: #APP
424; CHECK-NEXT: blah %r2
425; CHECK-NEXT: #NO_APP
426; CHECK-NEXT: cije %r2, 0, .L{{.*}}
427; CHECK: br %r14
428entry:
429 %add = add i32 %a, 1000000
430 %res = call i32 asm "blah $0", "=r,0,~{cc}" (i32 %add)
431 %cmp = icmp eq i32 %res, 0
432 br i1 %cmp, label %exit, label %store
433
434store:
435 store i32 %b, i32 *%dest
436 br label %exit
437
438exit:
439 ret i32 %res
440}
441
442; Check that stores do not interfere.
443define i32 @f23(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) {
444; CHECK-LABEL: f23:
445; CHECK: afi %r2, 1000000
446; CHECK-NEXT: st %r2, 0(%r4)
447; CHECK-NEXT: jne .L{{.*}}
448; CHECK: br %r14
449entry:
450 %res = add i32 %a, 1000000
451 store i32 %res, i32 *%dest1
452 %cmp = icmp ne i32 %res, 0
453 br i1 %cmp, label %exit, label %store
454
455store:
456 store i32 %b, i32 *%dest2
457 br label %exit
458
459exit:
460 ret i32 %res
461}
462
463; Check that calls do interfere.
464define void @f24(i32 *%ptr) {
465; CHECK-LABEL: f24:
466; CHECK: afi [[REG:%r[0-9]+]], 1000000
467; CHECK-NEXT: brasl %r14, foo@PLT
468; CHECK-NEXT: cijlh [[REG]], 0, .L{{.*}}
469; CHECK: br %r14
470entry:
471 %val = load i32 *%ptr
472 %xor = xor i32 %val, 1
473 %add = add i32 %xor, 1000000
474 call void @foo()
475 %cmp = icmp ne i32 %add, 0
476 br i1 %cmp, label %exit, label %store
477
478store:
479 store i32 %add, i32 *%ptr
480 br label %exit
481
482exit:
483 ret void
484}
485
486; Check that inline asms don't interfere if they don't clobber CC.
487define void @f25(i32 %a, i32 *%ptr) {
488; CHECK-LABEL: f25:
489; CHECK: afi %r2, 1000000
490; CHECK-NEXT: #APP
491; CHECK-NEXT: blah
492; CHECK-NEXT: #NO_APP
493; CHECK-NEXT: jne .L{{.*}}
494; CHECK: br %r14
495entry:
496 %add = add i32 %a, 1000000
497 call void asm sideeffect "blah", "r"(i32 %add)
498 %cmp = icmp ne i32 %add, 0
499 br i1 %cmp, label %exit, label %store
500
501store:
502 store i32 %add, i32 *%ptr
503 br label %exit
504
505exit:
506 ret void
507}
508
509; ...but do interfere if they do clobber CC.
510define void @f26(i32 %a, i32 *%ptr) {
511; CHECK-LABEL: f26:
512; CHECK: afi %r2, 1000000
513; CHECK-NEXT: #APP
514; CHECK-NEXT: blah
515; CHECK-NEXT: #NO_APP
516; CHECK-NEXT: cijlh %r2, 0, .L{{.*}}
517; CHECK: br %r14
518entry:
519 %add = add i32 %a, 1000000
520 call void asm sideeffect "blah", "r,~{cc}"(i32 %add)
521 %cmp = icmp ne i32 %add, 0
522 br i1 %cmp, label %exit, label %store
523
524store:
525 store i32 %add, i32 *%ptr
526 br label %exit
527
528exit:
529 ret void
530}
531
532; Test a case where CC is set based on a different register from the
533; compare input.
534define i32 @f27(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) {
535; CHECK-LABEL: f27:
536; CHECK: afi %r2, 1000000
537; CHECK-NEXT: sr %r3, %r2
538; CHECK-NEXT: st %r3, 0(%r4)
539; CHECK-NEXT: cije %r2, 0, .L{{.*}}
540; CHECK: br %r14
541entry:
542 %add = add i32 %a, 1000000
543 %sub = sub i32 %b, %add
544 store i32 %sub, i32 *%dest1
545 %cmp = icmp eq i32 %add, 0
546 br i1 %cmp, label %exit, label %store
547
548store:
549 store i32 %sub, i32 *%dest2
550 br label %exit
551
552exit:
553 ret i32 %add
554}
555
556; Make sure that we don't confuse a base register for a destination.
557define void @f28(i64 %a, i64 *%dest) {
558; CHECK-LABEL: f28:
559; CHECK: xi 0(%r2), 15
560; CHECK: cgije %r2, 0, .L{{.*}}
561; CHECK: br %r14
562entry:
563 %ptr = inttoptr i64 %a to i8 *
564 %val = load i8 *%ptr
565 %xor = xor i8 %val, 15
566 store i8 %xor, i8 *%ptr
567 %cmp = icmp eq i64 %a, 0
568 br i1 %cmp, label %exit, label %store
569
570store:
571 store i64 %a, i64 *%dest
572 br label %exit
573
574exit:
575 ret void
576}