blob: 85a8788a3bddec2d3f263d19eeb3cf9108442367 [file] [log] [blame]
Alp Tokercb402912014-01-24 17:20:08 +00001; Test that compares are omitted if CC already has the right value
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +00002; (z10 version).
3;
Jonas Paulsson83553d02015-10-26 15:03:49 +00004; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -no-integrated-as \
5; RUN: -verify-machineinstrs| FileCheck %s
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +00006
7declare void @foo()
8
9; Addition provides enough for equality comparisons with zero. First teest
10; the EQ case.
11define i32 @f1(i32 %a, i32 %b, i32 *%dest) {
12; CHECK-LABEL: f1:
13; CHECK: afi %r2, 1000000
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000014; CHECK-NEXT: ber %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +000015; CHECK: br %r14
16entry:
17 %res = add i32 %a, 1000000
18 %cmp = icmp eq i32 %res, 0
19 br i1 %cmp, label %exit, label %store
20
21store:
22 store i32 %b, i32 *%dest
23 br label %exit
24
25exit:
26 ret i32 %res
27}
28
29; ...and again with NE.
30define i32 @f2(i32 %a, i32 %b, i32 *%dest) {
31; CHECK-LABEL: f2:
32; CHECK: afi %r2, 1000000
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000033; CHECK-NEXT: bner %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +000034; CHECK: br %r14
35entry:
36 %res = add i32 %a, 1000000
37 %cmp = icmp ne i32 %res, 0
38 br i1 %cmp, label %exit, label %store
39
40store:
41 store i32 %b, i32 *%dest
42 br label %exit
43
44exit:
45 ret i32 %res
46}
47
48; SLT requires a comparison.
49define i32 @f3(i32 %a, i32 %b, i32 *%dest) {
50; CHECK-LABEL: f3:
51; CHECK: afi %r2, 1000000
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000052; CHECK-NEXT: cibl %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +000053; CHECK: br %r14
54entry:
55 %res = add i32 %a, 1000000
56 %cmp = icmp slt i32 %res, 0
57 br i1 %cmp, label %exit, label %store
58
59store:
60 store i32 %b, i32 *%dest
61 br label %exit
62
63exit:
64 ret i32 %res
65}
66
67; ...SLE too.
68define i32 @f4(i32 %a, i32 %b, i32 *%dest) {
69; CHECK-LABEL: f4:
70; CHECK: afi %r2, 1000000
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000071; CHECK-NEXT: cible %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +000072; CHECK: br %r14
73entry:
74 %res = add i32 %a, 1000000
75 %cmp = icmp sle i32 %res, 0
76 br i1 %cmp, label %exit, label %store
77
78store:
79 store i32 %b, i32 *%dest
80 br label %exit
81
82exit:
83 ret i32 %res
84}
85
86; ...SGT too.
87define i32 @f5(i32 %a, i32 %b, i32 *%dest) {
88; CHECK-LABEL: f5:
89; CHECK: afi %r2, 1000000
Ulrich Weigand2eb027d2016-04-07 16:11:44 +000090; CHECK-NEXT: cibh %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +000091; CHECK: br %r14
92entry:
93 %res = add i32 %a, 1000000
94 %cmp = icmp sgt i32 %res, 0
95 br i1 %cmp, label %exit, label %store
96
97store:
98 store i32 %b, i32 *%dest
99 br label %exit
100
101exit:
102 ret i32 %res
103}
104
105; ...SGE too.
106define i32 @f6(i32 %a, i32 %b, i32 *%dest) {
107; CHECK-LABEL: f6:
108; CHECK: afi %r2, 1000000
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000109; CHECK-NEXT: cibhe %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000110; CHECK: br %r14
111entry:
112 %res = add i32 %a, 1000000
113 %cmp = icmp sge i32 %res, 0
114 br i1 %cmp, label %exit, label %store
115
116store:
117 store i32 %b, i32 *%dest
118 br label %exit
119
120exit:
121 ret i32 %res
122}
123
124; Subtraction also provides enough for equality comparisons with zero.
125define i32 @f7(i32 %a, i32 %b, i32 *%dest) {
126; CHECK-LABEL: f7:
127; CHECK: s %r2, 0(%r4)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000128; CHECK-NEXT: bner %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000129; CHECK: br %r14
130entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000131 %cur = load i32 , i32 *%dest
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000132 %res = sub i32 %a, %cur
133 %cmp = icmp ne i32 %res, 0
134 br i1 %cmp, label %exit, label %store
135
136store:
137 store i32 %b, i32 *%dest
138 br label %exit
139
140exit:
141 ret i32 %res
142}
143
144; ...but not for ordered comparisons.
145define i32 @f8(i32 %a, i32 %b, i32 *%dest) {
146; CHECK-LABEL: f8:
147; CHECK: s %r2, 0(%r4)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000148; CHECK-NEXT: cibl %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000149; CHECK: br %r14
150entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000151 %cur = load i32 , i32 *%dest
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000152 %res = sub i32 %a, %cur
153 %cmp = icmp slt i32 %res, 0
154 br i1 %cmp, label %exit, label %store
155
156store:
157 store i32 %b, i32 *%dest
158 br label %exit
159
160exit:
161 ret i32 %res
162}
163
164; Logic register-register instructions also provide enough for equality
165; comparisons with zero.
166define i32 @f9(i32 %a, i32 %b, i32 *%dest) {
167; CHECK-LABEL: f9:
168; CHECK: nr %r2, %r3
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000169; CHECK-NEXT: blr %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000170; CHECK: br %r14
171entry:
172 %res = and i32 %a, %b
173 %cmp = icmp ne i32 %res, 0
174 br i1 %cmp, label %exit, label %store
175
176store:
177 store i32 %b, i32 *%dest
178 br label %exit
179
180exit:
181 ret i32 %res
182}
183
184; ...but not for ordered comparisons.
185define i32 @f10(i32 %a, i32 %b, i32 *%dest) {
186; CHECK-LABEL: f10:
187; CHECK: nr %r2, %r3
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000188; CHECK-NEXT: cibl %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000189; CHECK: br %r14
190entry:
191 %res = and i32 %a, %b
192 %cmp = icmp slt i32 %res, 0
193 br i1 %cmp, label %exit, label %store
194
195store:
196 store i32 %b, i32 *%dest
197 br label %exit
198
199exit:
200 ret i32 %res
201}
202
203; Logic register-immediate instructions also provide enough for equality
204; comparisons with zero if the immediate covers the whole register.
205define i32 @f11(i32 %a, i32 %b, i32 *%dest) {
206; CHECK-LABEL: f11:
Richard Sandiford35b9be22013-08-28 10:31:43 +0000207; CHECK: nilf %r2, 100000001
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000208; CHECK-NEXT: blr %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000209; CHECK: br %r14
210entry:
Richard Sandiford35b9be22013-08-28 10:31:43 +0000211 %res = and i32 %a, 100000001
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000212 %cmp = icmp ne i32 %res, 0
213 br i1 %cmp, label %exit, label %store
214
215store:
216 store i32 %b, i32 *%dest
217 br label %exit
218
219exit:
220 ret i32 %res
221}
222
223; Partial logic register-immediate instructions do not provide simple
224; zero results.
225define i32 @f12(i32 %a, i32 %b, i32 *%dest) {
226; CHECK-LABEL: f12:
227; CHECK: nill %r2, 65436
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000228; CHECK-NEXT: ciblh %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000229; CHECK: br %r14
230entry:
231 %res = and i32 %a, -100
232 %cmp = icmp ne i32 %res, 0
233 br i1 %cmp, label %exit, label %store
234
235store:
236 store i32 %b, i32 *%dest
237 br label %exit
238
239exit:
240 ret i32 %res
241}
242
243; SRA provides the same CC result as a comparison with zero.
244define i32 @f13(i32 %a, i32 %b, i32 *%dest) {
245; CHECK-LABEL: f13:
246; CHECK: sra %r2, 0(%r3)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000247; CHECK-NEXT: ber %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000248; CHECK: br %r14
249entry:
250 %res = ashr i32 %a, %b
251 %cmp = icmp eq i32 %res, 0
252 br i1 %cmp, label %exit, label %store
253
254store:
255 store i32 %b, i32 *%dest
256 br label %exit
257
258exit:
259 ret i32 %res
260}
261
262; ...and again with NE.
263define i32 @f14(i32 %a, i32 %b, i32 *%dest) {
264; CHECK-LABEL: f14:
265; CHECK: sra %r2, 0(%r3)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000266; CHECK-NEXT: blhr %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000267; CHECK: br %r14
268entry:
269 %res = ashr i32 %a, %b
270 %cmp = icmp ne i32 %res, 0
271 br i1 %cmp, label %exit, label %store
272
273store:
274 store i32 %b, i32 *%dest
275 br label %exit
276
277exit:
278 ret i32 %res
279}
280
281; ...and SLT.
282define i32 @f15(i32 %a, i32 %b, i32 *%dest) {
283; CHECK-LABEL: f15:
284; CHECK: sra %r2, 0(%r3)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000285; CHECK-NEXT: blr %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000286; CHECK: br %r14
287entry:
288 %res = ashr i32 %a, %b
289 %cmp = icmp slt i32 %res, 0
290 br i1 %cmp, label %exit, label %store
291
292store:
293 store i32 %b, i32 *%dest
294 br label %exit
295
296exit:
297 ret i32 %res
298}
299
300; ...and SLE.
301define i32 @f16(i32 %a, i32 %b, i32 *%dest) {
302; CHECK-LABEL: f16:
303; CHECK: sra %r2, 0(%r3)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000304; CHECK-NEXT: bler %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000305; CHECK: br %r14
306entry:
307 %res = ashr i32 %a, %b
308 %cmp = icmp sle i32 %res, 0
309 br i1 %cmp, label %exit, label %store
310
311store:
312 store i32 %b, i32 *%dest
313 br label %exit
314
315exit:
316 ret i32 %res
317}
318
319; ...and SGT.
320define i32 @f17(i32 %a, i32 %b, i32 *%dest) {
321; CHECK-LABEL: f17:
322; CHECK: sra %r2, 0(%r3)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000323; CHECK-NEXT: bhr %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000324; CHECK: br %r14
325entry:
326 %res = ashr i32 %a, %b
327 %cmp = icmp sgt i32 %res, 0
328 br i1 %cmp, label %exit, label %store
329
330store:
331 store i32 %b, i32 *%dest
332 br label %exit
333
334exit:
335 ret i32 %res
336}
337
338; ...and SGE.
339define i32 @f18(i32 %a, i32 %b, i32 *%dest) {
340; CHECK-LABEL: f18:
341; CHECK: sra %r2, 0(%r3)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000342; CHECK-NEXT: bher %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000343; CHECK: br %r14
344entry:
345 %res = ashr i32 %a, %b
346 %cmp = icmp sge i32 %res, 0
347 br i1 %cmp, label %exit, label %store
348
349store:
350 store i32 %b, i32 *%dest
351 br label %exit
352
353exit:
354 ret i32 %res
355}
356
357; RISBG provides the same result as a comparison against zero.
358; Test the EQ case.
359define i64 @f19(i64 %a, i64 %b, i64 *%dest) {
360; CHECK-LABEL: f19:
361; CHECK: risbg %r2, %r3, 0, 190, 0
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000362; CHECK-NEXT: ber %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000363; CHECK: br %r14
364entry:
365 %res = and i64 %b, -2
366 %cmp = icmp eq i64 %res, 0
367 br i1 %cmp, label %exit, label %store
368
369store:
370 store i64 %b, i64 *%dest
371 br label %exit
372
373exit:
374 ret i64 %res
375}
376
377; ...and the SLT case.
378define i64 @f20(i64 %a, i64 %b, i64 *%dest) {
379; CHECK-LABEL: f20:
380; CHECK: risbg %r2, %r3, 0, 190, 0
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000381; CHECK-NEXT: blr %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000382; CHECK: br %r14
383entry:
384 %res = and i64 %b, -2
385 %cmp = icmp slt i64 %res, 0
386 br i1 %cmp, label %exit, label %store
387
388store:
389 store i64 %b, i64 *%dest
390 br label %exit
391
392exit:
393 ret i64 %res
394}
395
396; Test a case where the register we're testing is set by a non-CC-clobbering
397; instruction.
398define i32 @f21(i32 %a, i32 %b, i32 *%dest) {
399; CHECK-LABEL: f21:
400; CHECK: afi %r2, 1000000
401; CHECK-NEXT: #APP
402; CHECK-NEXT: blah %r2
403; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000404; CHECK-NEXT: cibe %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000405; CHECK: br %r14
406entry:
407 %add = add i32 %a, 1000000
408 %res = call i32 asm "blah $0", "=r,0" (i32 %add)
409 %cmp = icmp eq i32 %res, 0
410 br i1 %cmp, label %exit, label %store
411
412store:
413 store i32 %b, i32 *%dest
414 br label %exit
415
416exit:
417 ret i32 %res
418}
419
420; ...and again with a CC-clobbering instruction.
421define i32 @f22(i32 %a, i32 %b, i32 *%dest) {
422; CHECK-LABEL: f22:
423; CHECK: afi %r2, 1000000
424; CHECK-NEXT: #APP
425; CHECK-NEXT: blah %r2
426; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000427; CHECK-NEXT: cibe %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000428; CHECK: br %r14
429entry:
430 %add = add i32 %a, 1000000
431 %res = call i32 asm "blah $0", "=r,0,~{cc}" (i32 %add)
432 %cmp = icmp eq i32 %res, 0
433 br i1 %cmp, label %exit, label %store
434
435store:
436 store i32 %b, i32 *%dest
437 br label %exit
438
439exit:
440 ret i32 %res
441}
442
443; Check that stores do not interfere.
444define i32 @f23(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) {
445; CHECK-LABEL: f23:
446; CHECK: afi %r2, 1000000
447; CHECK-NEXT: st %r2, 0(%r4)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000448; CHECK-NEXT: bner %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000449; CHECK: br %r14
450entry:
451 %res = add i32 %a, 1000000
452 store i32 %res, i32 *%dest1
453 %cmp = icmp ne i32 %res, 0
454 br i1 %cmp, label %exit, label %store
455
456store:
457 store i32 %b, i32 *%dest2
458 br label %exit
459
460exit:
461 ret i32 %res
462}
463
464; Check that calls do interfere.
465define void @f24(i32 *%ptr) {
466; CHECK-LABEL: f24:
467; CHECK: afi [[REG:%r[0-9]+]], 1000000
468; CHECK-NEXT: brasl %r14, foo@PLT
469; CHECK-NEXT: cijlh [[REG]], 0, .L{{.*}}
470; CHECK: br %r14
471entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000472 %val = load i32 , i32 *%ptr
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000473 %xor = xor i32 %val, 1
474 %add = add i32 %xor, 1000000
475 call void @foo()
Kyle Buttb15c0662017-01-31 23:48:32 +0000476 %cmp = icmp eq i32 %add, 0
477 br i1 %cmp, label %store, label %exit, !prof !1
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000478
479store:
480 store i32 %add, i32 *%ptr
481 br label %exit
482
483exit:
484 ret void
485}
486
487; Check that inline asms don't interfere if they don't clobber CC.
488define void @f25(i32 %a, i32 *%ptr) {
489; CHECK-LABEL: f25:
490; CHECK: afi %r2, 1000000
491; CHECK-NEXT: #APP
492; CHECK-NEXT: blah
493; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000494; CHECK-NEXT: bner %r14
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000495; CHECK: br %r14
496entry:
497 %add = add i32 %a, 1000000
498 call void asm sideeffect "blah", "r"(i32 %add)
499 %cmp = icmp ne i32 %add, 0
500 br i1 %cmp, label %exit, label %store
501
502store:
503 store i32 %add, i32 *%ptr
504 br label %exit
505
506exit:
507 ret void
508}
509
510; ...but do interfere if they do clobber CC.
511define void @f26(i32 %a, i32 *%ptr) {
512; CHECK-LABEL: f26:
513; CHECK: afi %r2, 1000000
514; CHECK-NEXT: #APP
515; CHECK-NEXT: blah
516; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000517; CHECK-NEXT: ciblh %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000518; CHECK: br %r14
519entry:
520 %add = add i32 %a, 1000000
521 call void asm sideeffect "blah", "r,~{cc}"(i32 %add)
522 %cmp = icmp ne i32 %add, 0
523 br i1 %cmp, label %exit, label %store
524
525store:
526 store i32 %add, i32 *%ptr
527 br label %exit
528
529exit:
530 ret void
531}
532
533; Test a case where CC is set based on a different register from the
534; compare input.
535define i32 @f27(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) {
536; CHECK-LABEL: f27:
537; CHECK: afi %r2, 1000000
538; CHECK-NEXT: sr %r3, %r2
539; CHECK-NEXT: st %r3, 0(%r4)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000540; CHECK-NEXT: cibe %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000541; CHECK: br %r14
542entry:
543 %add = add i32 %a, 1000000
544 %sub = sub i32 %b, %add
545 store i32 %sub, i32 *%dest1
546 %cmp = icmp eq i32 %add, 0
547 br i1 %cmp, label %exit, label %store
548
549store:
550 store i32 %sub, i32 *%dest2
551 br label %exit
552
553exit:
554 ret i32 %add
555}
556
557; Make sure that we don't confuse a base register for a destination.
558define void @f28(i64 %a, i64 *%dest) {
559; CHECK-LABEL: f28:
560; CHECK: xi 0(%r2), 15
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000561; CHECK: cgibe %r2, 0, 0(%r14)
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000562; CHECK: br %r14
563entry:
564 %ptr = inttoptr i64 %a to i8 *
David Blaikiea79ac142015-02-27 21:17:42 +0000565 %val = load i8 , i8 *%ptr
Richard Sandifordfd7f4ae2013-08-01 10:39:40 +0000566 %xor = xor i8 %val, 15
567 store i8 %xor, i8 *%ptr
568 %cmp = icmp eq i64 %a, 0
569 br i1 %cmp, label %exit, label %store
570
571store:
572 store i64 %a, i64 *%dest
573 br label %exit
574
575exit:
576 ret void
577}
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000578
579; Test that L gets converted to LT where useful.
580define i32 @f29(i64 %base, i64 %index, i32 *%dest) {
581; CHECK-LABEL: f29:
582; CHECK: lt %r2, 0({{%r2,%r3|%r3,%r2}})
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000583; CHECK-NEXT: bler %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000584; CHECK: br %r14
585entry:
586 %add = add i64 %base, %index
587 %ptr = inttoptr i64 %add to i32 *
David Blaikiea79ac142015-02-27 21:17:42 +0000588 %res = load i32 , i32 *%ptr
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000589 %cmp = icmp sle i32 %res, 0
590 br i1 %cmp, label %exit, label %store
591
592store:
593 store i32 %res, i32 *%dest
594 br label %exit
595
596exit:
597 ret i32 %res
598}
599
600; Test that LY gets converted to LT where useful.
601define i32 @f30(i64 %base, i64 %index, i32 *%dest) {
602; CHECK-LABEL: f30:
603; CHECK: lt %r2, 100000({{%r2,%r3|%r3,%r2}})
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000604; CHECK-NEXT: bler %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000605; CHECK: br %r14
606entry:
607 %add1 = add i64 %base, %index
608 %add2 = add i64 %add1, 100000
609 %ptr = inttoptr i64 %add2 to i32 *
David Blaikiea79ac142015-02-27 21:17:42 +0000610 %res = load i32 , i32 *%ptr
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000611 %cmp = icmp sle i32 %res, 0
612 br i1 %cmp, label %exit, label %store
613
614store:
615 store i32 %res, i32 *%dest
616 br label %exit
617
618exit:
619 ret i32 %res
620}
621
622; Test that LG gets converted to LTG where useful.
623define i64 @f31(i64 %base, i64 %index, i64 *%dest) {
624; CHECK-LABEL: f31:
625; CHECK: ltg %r2, 0({{%r2,%r3|%r3,%r2}})
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000626; CHECK-NEXT: bher %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000627; CHECK: br %r14
628entry:
629 %add = add i64 %base, %index
630 %ptr = inttoptr i64 %add to i64 *
David Blaikiea79ac142015-02-27 21:17:42 +0000631 %res = load i64 , i64 *%ptr
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000632 %cmp = icmp sge i64 %res, 0
633 br i1 %cmp, label %exit, label %store
634
635store:
636 store i64 %res, i64 *%dest
637 br label %exit
638
639exit:
640 ret i64 %res
641}
642
643; Test that LGF gets converted to LTGF where useful.
644define i64 @f32(i64 %base, i64 %index, i64 *%dest) {
645; CHECK-LABEL: f32:
646; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000647; CHECK-NEXT: bhr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000648; CHECK: br %r14
649entry:
650 %add = add i64 %base, %index
651 %ptr = inttoptr i64 %add to i32 *
David Blaikiea79ac142015-02-27 21:17:42 +0000652 %val = load i32 , i32 *%ptr
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000653 %res = sext i32 %val to i64
654 %cmp = icmp sgt i64 %res, 0
655 br i1 %cmp, label %exit, label %store
656
657store:
658 store i64 %res, i64 *%dest
659 br label %exit
660
661exit:
662 ret i64 %res
663}
664
665; Test that LR gets converted to LTR where useful.
666define i32 @f33(i32 %dummy, i32 %val, i32 *%dest) {
667; CHECK-LABEL: f33:
668; CHECK: ltr %r2, %r3
669; CHECK-NEXT: #APP
670; CHECK-NEXT: blah %r2
671; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000672; CHECK-NEXT: blr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000673; CHECK: br %r14
674entry:
675 call void asm sideeffect "blah $0", "{r2}"(i32 %val)
676 %cmp = icmp slt i32 %val, 0
677 br i1 %cmp, label %exit, label %store
678
679store:
680 store i32 %val, i32 *%dest
681 br label %exit
682
683exit:
684 ret i32 %val
685}
686
687; Test that LGR gets converted to LTGR where useful.
688define i64 @f34(i64 %dummy, i64 %val, i64 *%dest) {
689; CHECK-LABEL: f34:
690; CHECK: ltgr %r2, %r3
691; CHECK-NEXT: #APP
692; CHECK-NEXT: blah %r2
693; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000694; CHECK-NEXT: bhr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000695; CHECK: br %r14
696entry:
697 call void asm sideeffect "blah $0", "{r2}"(i64 %val)
698 %cmp = icmp sgt i64 %val, 0
699 br i1 %cmp, label %exit, label %store
700
701store:
702 store i64 %val, i64 *%dest
703 br label %exit
704
705exit:
706 ret i64 %val
707}
708
709; Test that LGFR gets converted to LTGFR where useful.
710define i64 @f35(i64 %dummy, i32 %val, i64 *%dest) {
711; CHECK-LABEL: f35:
712; CHECK: ltgfr %r2, %r3
713; CHECK-NEXT: #APP
714; CHECK-NEXT: blah %r2
715; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000716; CHECK-NEXT: bhr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000717; CHECK: br %r14
718entry:
719 %ext = sext i32 %val to i64
720 call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
721 %cmp = icmp sgt i64 %ext, 0
722 br i1 %cmp, label %exit, label %store
723
724store:
725 store i64 %ext, i64 *%dest
726 br label %exit
727
728exit:
729 ret i64 %ext
730}
731
732; Test a case where it is the source rather than destination of LR that
733; we need.
734define i32 @f36(i32 %val, i32 %dummy, i32 *%dest) {
735; CHECK-LABEL: f36:
736; CHECK: ltr %r3, %r2
737; CHECK-NEXT: #APP
738; CHECK-NEXT: blah %r3
739; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000740; CHECK-NEXT: blr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000741; CHECK: br %r14
742entry:
743 call void asm sideeffect "blah $0", "{r3}"(i32 %val)
744 %cmp = icmp slt i32 %val, 0
745 br i1 %cmp, label %exit, label %store
746
747store:
748 store i32 %val, i32 *%dest
749 br label %exit
750
751exit:
752 ret i32 %val
753}
754
755; Test a case where it is the source rather than destination of LGR that
756; we need.
757define i64 @f37(i64 %val, i64 %dummy, i64 *%dest) {
758; CHECK-LABEL: f37:
759; CHECK: ltgr %r3, %r2
760; CHECK-NEXT: #APP
761; CHECK-NEXT: blah %r3
762; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000763; CHECK-NEXT: blr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000764; CHECK: br %r14
765entry:
766 call void asm sideeffect "blah $0", "{r3}"(i64 %val)
767 %cmp = icmp slt i64 %val, 0
768 br i1 %cmp, label %exit, label %store
769
770store:
771 store i64 %val, i64 *%dest
772 br label %exit
773
774exit:
775 ret i64 %val
776}
777
778; Test a case where it is the source rather than destination of LGFR that
779; we need.
780define i32 @f38(i32 %val, i64 %dummy, i32 *%dest) {
781; CHECK-LABEL: f38:
782; CHECK: ltgfr %r3, %r2
783; CHECK-NEXT: #APP
784; CHECK-NEXT: blah %r3
785; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000786; CHECK-NEXT: blr %r14
Richard Sandifordb49a3ab2013-08-05 11:03:20 +0000787; CHECK: br %r14
788entry:
789 %ext = sext i32 %val to i64
790 call void asm sideeffect "blah $0", "{r3}"(i64 %ext)
791 %cmp = icmp slt i32 %val, 0
792 br i1 %cmp, label %exit, label %store
793
794store:
795 store i32 %val, i32 *%dest
796 br label %exit
797
798exit:
799 ret i32 %val
800}
Richard Sandifordbd2f0e92013-12-13 15:07:39 +0000801
802; Test f35 for in-register extensions.
803define i64 @f39(i64 %dummy, i64 %a, i64 *%dest) {
804; CHECK-LABEL: f39:
805; CHECK: ltgfr %r2, %r3
806; CHECK-NEXT: #APP
807; CHECK-NEXT: blah %r2
808; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000809; CHECK-NEXT: bhr %r14
Richard Sandifordbd2f0e92013-12-13 15:07:39 +0000810; CHECK: br %r14
811entry:
812 %val = trunc i64 %a to i32
813 %ext = sext i32 %val to i64
814 call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
815 %cmp = icmp sgt i64 %ext, 0
816 br i1 %cmp, label %exit, label %store
817
818store:
819 store i64 %ext, i64 *%dest
820 br label %exit
821
822exit:
823 ret i64 %ext
824}
825
826; ...and again with what InstCombine would produce for f40.
827define i64 @f40(i64 %dummy, i64 %a, i64 *%dest) {
828; CHECK-LABEL: f40:
829; CHECK: ltgfr %r2, %r3
830; CHECK-NEXT: #APP
831; CHECK-NEXT: blah %r2
832; CHECK-NEXT: #NO_APP
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000833; CHECK-NEXT: bhr %r14
Richard Sandifordbd2f0e92013-12-13 15:07:39 +0000834; CHECK: br %r14
835entry:
836 %shl = shl i64 %a, 32
837 %ext = ashr i64 %shl, 32
838 call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
839 %cmp = icmp sgt i64 %shl, 0
840 br i1 %cmp, label %exit, label %store
841
842store:
843 store i64 %ext, i64 *%dest
844 br label %exit
845
846exit:
847 ret i64 %ext
848}
Richard Sandiford0847c452013-12-13 15:50:30 +0000849
850; Try a form of f7 in which the subtraction operands are compared directly.
851define i32 @f41(i32 %a, i32 %b, i32 *%dest) {
852; CHECK-LABEL: f41:
853; CHECK: s %r2, 0(%r4)
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000854; CHECK-NEXT: bner %r14
Richard Sandiford0847c452013-12-13 15:50:30 +0000855; CHECK: br %r14
856entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000857 %cur = load i32 , i32 *%dest
Richard Sandiford0847c452013-12-13 15:50:30 +0000858 %res = sub i32 %a, %cur
859 %cmp = icmp ne i32 %a, %cur
860 br i1 %cmp, label %exit, label %store
861
862store:
863 store i32 %b, i32 *%dest
864 br label %exit
865
866exit:
867 ret i32 %res
868}
Richard Sandiford83a0b6a2013-12-20 11:56:02 +0000869
870; A version of f32 that tests the unextended value.
871define i64 @f42(i64 %base, i64 %index, i64 *%dest) {
872; CHECK-LABEL: f42:
873; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000874; CHECK-NEXT: bhr %r14
Richard Sandiford83a0b6a2013-12-20 11:56:02 +0000875; CHECK: br %r14
876entry:
877 %add = add i64 %base, %index
878 %ptr = inttoptr i64 %add to i32 *
David Blaikiea79ac142015-02-27 21:17:42 +0000879 %val = load i32 , i32 *%ptr
Richard Sandiford83a0b6a2013-12-20 11:56:02 +0000880 %res = sext i32 %val to i64
881 %cmp = icmp sgt i32 %val, 0
882 br i1 %cmp, label %exit, label %store
883
884store:
885 store i64 %res, i64 *%dest
886 br label %exit
887
888exit:
889 ret i64 %res
890}
Kyle Buttb15c0662017-01-31 23:48:32 +0000891
892!1 = !{!"branch_weights", i32 2, i32 1}