[X86] combineTargetShuffle - commute VPERMV3 shuffles so any load is on the RHS
[llvm-project.git] / llvm / test / CodeGen / SystemZ / int-cmp-44.ll
blob41ace057706c3c064310e23396c58a1c365e0d57
1 ; Test that compares are omitted if CC already has the right value
2 ; (z10 version).
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -no-integrated-as \
5 ; RUN:   -verify-machineinstrs| FileCheck %s
7 declare void @foo()
9 ; Addition provides enough for comparisons with zero if we know no
10 ; signed overflow happens, which is when the "nsw" flag is set.
11 ; First test the EQ case.
12 define i32 @f1(i32 %a, i32 %b, ptr %dest) {
13 ; CHECK-LABEL: f1:
14 ; CHECK: afi %r2, 1000000
15 ; CHECK-NEXT: ber %r14
16 ; CHECK: br %r14
17 entry:
18   %res = add nsw i32 %a, 1000000
19   %cmp = icmp eq i32 %res, 0
20   br i1 %cmp, label %exit, label %store
22 store:
23   store i32 %b, ptr %dest
24   br label %exit
26 exit:
27   ret i32 %res
30 ; ...and again with NE.
31 define i32 @f2(i32 %a, i32 %b, ptr %dest) {
32 ; CHECK-LABEL: f2:
33 ; CHECK: afi %r2, 1000000
34 ; CHECK-NEXT: blhr %r14
35 ; CHECK: br %r14
36 entry:
37   %res = add nsw i32 %a, 1000000
38   %cmp = icmp ne i32 %res, 0
39   br i1 %cmp, label %exit, label %store
41 store:
42   store i32 %b, ptr %dest
43   br label %exit
45 exit:
46   ret i32 %res
49 ; ...and again with SLT.
50 define i32 @f3(i32 %a, i32 %b, ptr %dest) {
51 ; CHECK-LABEL: f3:
52 ; CHECK: afi %r2, 1000000
53 ; CHECK-NEXT: blr %r14
54 entry:
55   %res = add nsw i32 %a, 1000000
56   %cmp = icmp slt i32 %res, 0
57   br i1 %cmp, label %exit, label %store
59 store:
60   store i32 %b, ptr %dest
61   br label %exit
63 exit:
64   ret i32 %res
67 ; ...and again with SLE.
68 define i32 @f4(i32 %a, i32 %b, ptr %dest) {
69 ; CHECK-LABEL: f4:
70 ; CHECK: afi %r2, 1000000
71 ; CHECK-NEXT: bler %r14
72 entry:
73   %res = add nsw i32 %a, 1000000
74   %cmp = icmp sle i32 %res, 0
75   br i1 %cmp, label %exit, label %store
77 store:
78   store i32 %b, ptr %dest
79   br label %exit
81 exit:
82   ret i32 %res
85 ; ...and again with SGT.
86 define i32 @f5(i32 %a, i32 %b, ptr %dest) {
87 ; CHECK-LABEL: f5:
88 ; CHECK: afi %r2, 1000000
89 ; CHECK-NEXT: bhr %r14
90 entry:
91   %res = add nsw i32 %a, 1000000
92   %cmp = icmp sgt i32 %res, 0
93   br i1 %cmp, label %exit, label %store
95 store:
96   store i32 %b, ptr %dest
97   br label %exit
99 exit:
100   ret i32 %res
103 ; ...and again with SGE.
104 define i32 @f6(i32 %a, i32 %b, ptr %dest) {
105 ; CHECK-LABEL: f6:
106 ; CHECK: afi %r2, 1000000
107 ; CHECK-NEXT: bher %r14
108 entry:
109   %res = add nsw i32 %a, 1000000
110   %cmp = icmp sge i32 %res, 0
111   br i1 %cmp, label %exit, label %store
113 store:
114   store i32 %b, ptr %dest
115   br label %exit
117 exit:
118   ret i32 %res
121 ; Subtraction provides in addition also enough for equality comparisons with
122 ; zero even without "nsw".
123 define i32 @f7(i32 %a, i32 %b, ptr %dest) {
124 ; CHECK-LABEL: f7:
125 ; CHECK: s %r2, 0(%r4)
126 ; CHECK-NEXT: bner %r14
127 ; CHECK: br %r14
128 entry:
129   %cur = load i32, ptr %dest
130   %res = sub i32 %a, %cur
131   %cmp = icmp ne i32 %res, 0
132   br i1 %cmp, label %exit, label %store
134 store:
135   store i32 %b, ptr %dest
136   br label %exit
138 exit:
139   ret i32 %res
142 ; ...and again with SLT.
143 define i32 @f8(i32 %a, i32 %b, ptr %dest) {
144 ; CHECK-LABEL: f8:
145 ; CHECK: s %r2, 0(%r4)
146 ; CHECK-NEXT: blr %r14
147 entry:
148   %cur = load i32, ptr %dest
149   %res = sub nsw i32 %a, %cur
150   %cmp = icmp slt i32 %res, 0
151   br i1 %cmp, label %exit, label %store
153 store:
154   store i32 %b, ptr %dest
155   br label %exit
157 exit:
158   ret i32 %res
161 ; Logic register-register instructions also provide enough for equality
162 ; comparisons with zero.
163 define i32 @f9(i32 %a, i32 %b, ptr %dest) {
164 ; CHECK-LABEL: f9:
165 ; CHECK: nr %r2, %r3
166 ; CHECK-NEXT: blr %r14
167 ; CHECK: br %r14
168 entry:
169   %res = and i32 %a, %b
170   %cmp = icmp ne i32 %res, 0
171   br i1 %cmp, label %exit, label %store
173 store:
174   store i32 %b, ptr %dest
175   br label %exit
177 exit:
178   ret i32 %res
181 ; ...but not for ordered comparisons.
182 define i32 @f10(i32 %a, i32 %b, ptr %dest) {
183 ; CHECK-LABEL: f10:
184 ; CHECK: nr %r2, %r3
185 ; CHECK-NEXT: cibl %r2, 0, 0(%r14)
186 ; CHECK: br %r14
187 entry:
188   %res = and i32 %a, %b
189   %cmp = icmp slt i32 %res, 0
190   br i1 %cmp, label %exit, label %store
192 store:
193   store i32 %b, ptr %dest
194   br label %exit
196 exit:
197   ret i32 %res
200 ; Logic register-immediate instructions also provide enough for equality
201 ; comparisons with zero if the immediate covers the whole register.
202 define i32 @f11(i32 %a, i32 %b, ptr %dest) {
203 ; CHECK-LABEL: f11:
204 ; CHECK: nilf %r2, 100000001
205 ; CHECK-NEXT: blr %r14
206 ; CHECK: br %r14
207 entry:
208   %res = and i32 %a, 100000001
209   %cmp = icmp ne i32 %res, 0
210   br i1 %cmp, label %exit, label %store
212 store:
213   store i32 %b, ptr %dest
214   br label %exit
216 exit:
217   ret i32 %res
220 ; Partial logic register-immediate instructions do not provide simple
221 ; zero results.
222 define i32 @f12(i32 %a, i32 %b, ptr %dest) {
223 ; CHECK-LABEL: f12:
224 ; CHECK: nill %r2, 65436
225 ; CHECK-NEXT: ciblh %r2, 0, 0(%r14)
226 ; CHECK: br %r14
227 entry:
228   %res = and i32 %a, -100
229   %cmp = icmp ne i32 %res, 0
230   br i1 %cmp, label %exit, label %store
232 store:
233   store i32 %b, ptr %dest
234   br label %exit
236 exit:
237   ret i32 %res
240 ; SRA provides the same CC result as a comparison with zero.
241 define i32 @f13(i32 %a, i32 %b, ptr %dest) {
242 ; CHECK-LABEL: f13:
243 ; CHECK: sra %r2, 0(%r3)
244 ; CHECK-NEXT: ber %r14
245 ; CHECK: br %r14
246 entry:
247   %res = ashr i32 %a, %b
248   %cmp = icmp eq i32 %res, 0
249   br i1 %cmp, label %exit, label %store
251 store:
252   store i32 %b, ptr %dest
253   br label %exit
255 exit:
256   ret i32 %res
259 ; ...and again with NE.
260 define i32 @f14(i32 %a, i32 %b, ptr %dest) {
261 ; CHECK-LABEL: f14:
262 ; CHECK: sra %r2, 0(%r3)
263 ; CHECK-NEXT: blhr %r14
264 ; CHECK: br %r14
265 entry:
266   %res = ashr i32 %a, %b
267   %cmp = icmp ne i32 %res, 0
268   br i1 %cmp, label %exit, label %store
270 store:
271   store i32 %b, ptr %dest
272   br label %exit
274 exit:
275   ret i32 %res
278 ; ...and SLT.
279 define i32 @f15(i32 %a, i32 %b, ptr %dest) {
280 ; CHECK-LABEL: f15:
281 ; CHECK: sra %r2, 0(%r3)
282 ; CHECK-NEXT: blr %r14
283 ; CHECK: br %r14
284 entry:
285   %res = ashr i32 %a, %b
286   %cmp = icmp slt i32 %res, 0
287   br i1 %cmp, label %exit, label %store
289 store:
290   store i32 %b, ptr %dest
291   br label %exit
293 exit:
294   ret i32 %res
297 ; ...and SLE.
298 define i32 @f16(i32 %a, i32 %b, ptr %dest) {
299 ; CHECK-LABEL: f16:
300 ; CHECK: sra %r2, 0(%r3)
301 ; CHECK-NEXT: bler %r14
302 ; CHECK: br %r14
303 entry:
304   %res = ashr i32 %a, %b
305   %cmp = icmp sle i32 %res, 0
306   br i1 %cmp, label %exit, label %store
308 store:
309   store i32 %b, ptr %dest
310   br label %exit
312 exit:
313   ret i32 %res
316 ; ...and SGT.
317 define i32 @f17(i32 %a, i32 %b, ptr %dest) {
318 ; CHECK-LABEL: f17:
319 ; CHECK: sra %r2, 0(%r3)
320 ; CHECK-NEXT: bhr %r14
321 ; CHECK: br %r14
322 entry:
323   %res = ashr i32 %a, %b
324   %cmp = icmp sgt i32 %res, 0
325   br i1 %cmp, label %exit, label %store
327 store:
328   store i32 %b, ptr %dest
329   br label %exit
331 exit:
332   ret i32 %res
335 ; ...and SGE.
336 define i32 @f18(i32 %a, i32 %b, ptr %dest) {
337 ; CHECK-LABEL: f18:
338 ; CHECK: sra %r2, 0(%r3)
339 ; CHECK-NEXT: bher %r14
340 ; CHECK: br %r14
341 entry:
342   %res = ashr i32 %a, %b
343   %cmp = icmp sge i32 %res, 0
344   br i1 %cmp, label %exit, label %store
346 store:
347   store i32 %b, ptr %dest
348   br label %exit
350 exit:
351   ret i32 %res
354 ; RISBG provides the same result as a comparison against zero.
355 ; Test the EQ case.
356 define i64 @f19(i64 %a, i64 %b, ptr %dest) {
357 ; CHECK-LABEL: f19:
358 ; CHECK: risbg %r2, %r3, 0, 190, 0
359 ; CHECK-NEXT: ber %r14
360 ; CHECK: br %r14
361 entry:
362   %res = and i64 %b, -2
363   %cmp = icmp eq i64 %res, 0
364   br i1 %cmp, label %exit, label %store
366 store:
367   store i64 %b, ptr %dest
368   br label %exit
370 exit:
371   ret i64 %res
374 ; ...and the SLT case.
375 define i64 @f20(i64 %a, i64 %b, ptr %dest) {
376 ; CHECK-LABEL: f20:
377 ; CHECK: risbg %r2, %r3, 0, 190, 0
378 ; CHECK-NEXT: blr %r14
379 ; CHECK: br %r14
380 entry:
381   %res = and i64 %b, -2
382   %cmp = icmp slt i64 %res, 0
383   br i1 %cmp, label %exit, label %store
385 store:
386   store i64 %b, ptr %dest
387   br label %exit
389 exit:
390   ret i64 %res
393 ; Test a case where the register we're testing is set by a non-CC-clobbering
394 ; instruction.
395 define i32 @f21(i32 %a, i32 %b, ptr %dest) {
396 ; CHECK-LABEL: f21:
397 ; CHECK: afi %r2, 1000000
398 ; CHECK-NEXT: #APP
399 ; CHECK-NEXT: blah %r2
400 ; CHECK-NEXT: #NO_APP
401 ; CHECK-NEXT: cibe %r2, 0, 0(%r14)
402 ; CHECK: br %r14
403 entry:
404   %add = add i32 %a, 1000000
405   %res = call i32 asm "blah $0", "=r,0" (i32 %add)
406   %cmp = icmp eq i32 %res, 0
407   br i1 %cmp, label %exit, label %store
409 store:
410   store i32 %b, ptr %dest
411   br label %exit
413 exit:
414   ret i32 %res
417 ; ...and again with a CC-clobbering instruction.
418 define i32 @f22(i32 %a, i32 %b, ptr %dest) {
419 ; CHECK-LABEL: f22:
420 ; CHECK: afi %r2, 1000000
421 ; CHECK-NEXT: #APP
422 ; CHECK-NEXT: blah %r2
423 ; CHECK-NEXT: #NO_APP
424 ; CHECK-NEXT: cibe %r2, 0, 0(%r14)
425 ; CHECK: br %r14
426 entry:
427   %add = add i32 %a, 1000000
428   %res = call i32 asm "blah $0", "=r,0,~{cc}" (i32 %add)
429   %cmp = icmp eq i32 %res, 0
430   br i1 %cmp, label %exit, label %store
432 store:
433   store i32 %b, ptr %dest
434   br label %exit
436 exit:
437   ret i32 %res
440 ; Check that stores do not interfere.
441 define i32 @f23(i32 %a, i32 %b, ptr %dest1, ptr %dest2) {
442 ; CHECK-LABEL: f23:
443 ; CHECK: afi %r2, 1000000
444 ; CHECK-NEXT: st %r2, 0(%r4)
445 ; CHECK-NEXT: blhr %r14
446 ; CHECK: br %r14
447 entry:
448   %res = add nsw i32 %a, 1000000
449   store i32 %res, ptr %dest1
450   %cmp = icmp ne i32 %res, 0
451   br i1 %cmp, label %exit, label %store
453 store:
454   store i32 %b, ptr %dest2
455   br label %exit
457 exit:
458   ret i32 %res
461 ; Check that calls do interfere.
462 define void @f24(ptr %ptr) {
463 ; CHECK-LABEL: f24:
464 ; CHECK: afi [[REG:%r[0-9]+]], 1000000
465 ; CHECK-NEXT: brasl %r14, foo@PLT
466 ; CHECK-NEXT: cijlh [[REG]], 0, .L{{.*}}
467 ; CHECK: br %r14
468 entry:
469   %val = load i32, ptr %ptr
470   %xor = xor i32 %val, 1
471   %add = add i32 %xor, 1000000
472   call void @foo()
473   %cmp = icmp eq i32 %add, 0
474   br i1 %cmp, label %store, label %exit, !prof !1
476 store:
477   store i32 %add, ptr %ptr
478   br label %exit
480 exit:
481   ret void
484 ; Check that inline asms don't interfere if they don't clobber CC.
485 define void @f25(i32 %a, ptr %ptr) {
486 ; CHECK-LABEL: f25:
487 ; CHECK: afi %r2, 1000000
488 ; CHECK-NEXT: #APP
489 ; CHECK-NEXT: blah
490 ; CHECK-NEXT: #NO_APP
491 ; CHECK-NEXT: blhr %r14
492 ; CHECK: br %r14
493 entry:
494   %add = add nsw i32 %a, 1000000
495   call void asm sideeffect "blah", "r"(i32 %add)
496   %cmp = icmp ne i32 %add, 0
497   br i1 %cmp, label %exit, label %store
499 store:
500   store i32 %add, ptr %ptr
501   br label %exit
503 exit:
504   ret void
507 ; ...but do interfere if they do clobber CC.
508 define void @f26(i32 %a, ptr %ptr) {
509 ; CHECK-LABEL: f26:
510 ; CHECK: afi %r2, 1000000
511 ; CHECK-NEXT: #APP
512 ; CHECK-NEXT: blah
513 ; CHECK-NEXT: #NO_APP
514 ; CHECK-NEXT: ciblh %r2, 0, 0(%r14)
515 ; CHECK: br %r14
516 entry:
517   %add = add i32 %a, 1000000
518   call void asm sideeffect "blah", "r,~{cc}"(i32 %add)
519   %cmp = icmp ne i32 %add, 0
520   br i1 %cmp, label %exit, label %store
522 store:
523   store i32 %add, ptr %ptr
524   br label %exit
526 exit:
527   ret void
530 ; Test a case where CC is set based on a different register from the
531 ; compare input.
532 define i32 @f27(i32 %a, i32 %b, ptr %dest1, ptr %dest2) {
533 ; CHECK-LABEL: f27:
534 ; CHECK: afi %r2, 1000000
535 ; CHECK-NEXT: sr %r3, %r2
536 ; CHECK-NEXT: st %r3, 0(%r4)
537 ; CHECK-NEXT: cibe %r2, 0, 0(%r14)
538 ; CHECK: br %r14
539 entry:
540   %add = add nsw i32 %a, 1000000
541   %sub = sub i32 %b, %add
542   store i32 %sub, ptr %dest1
543   %cmp = icmp eq i32 %add, 0
544   br i1 %cmp, label %exit, label %store
546 store:
547   store i32 %sub, ptr %dest2
548   br label %exit
550 exit:
551   ret i32 %add
554 ; Make sure that we don't confuse a base register for a destination.
555 define void @f28(i64 %a, ptr %dest) {
556 ; CHECK-LABEL: f28:
557 ; CHECK: xi 0(%r2), 15
558 ; CHECK: cgibe %r2, 0, 0(%r14)
559 ; CHECK: br %r14
560 entry:
561   %ptr = inttoptr i64 %a to ptr
562   %val = load i8, ptr %ptr
563   %xor = xor i8 %val, 15
564   store i8 %xor, ptr %ptr
565   %cmp = icmp eq i64 %a, 0
566   br i1 %cmp, label %exit, label %store
568 store:
569   store i64 %a, ptr %dest
570   br label %exit
572 exit:
573   ret void
576 ; Test that L gets converted to LT where useful.
577 define i32 @f29(i64 %base, i64 %index, ptr %dest) {
578 ; CHECK-LABEL: f29:
579 ; CHECK: lt %r2, 0({{%r2,%r3|%r3,%r2}})
580 ; CHECK-NEXT: bler %r14
581 ; CHECK: br %r14
582 entry:
583   %add = add i64 %base, %index
584   %ptr = inttoptr i64 %add to ptr
585   %res = load i32, ptr %ptr
586   %cmp = icmp sle i32 %res, 0
587   br i1 %cmp, label %exit, label %store
589 store:
590   store i32 %res, ptr %dest
591   br label %exit
593 exit:
594   ret i32 %res
597 ; Test that LY gets converted to LT where useful.
598 define i32 @f30(i64 %base, i64 %index, ptr %dest) {
599 ; CHECK-LABEL: f30:
600 ; CHECK: lt %r2, 100000({{%r2,%r3|%r3,%r2}})
601 ; CHECK-NEXT: bler %r14
602 ; CHECK: br %r14
603 entry:
604   %add1 = add i64 %base, %index
605   %add2 = add i64 %add1, 100000
606   %ptr = inttoptr i64 %add2 to ptr
607   %res = load i32, ptr %ptr
608   %cmp = icmp sle i32 %res, 0
609   br i1 %cmp, label %exit, label %store
611 store:
612   store i32 %res, ptr %dest
613   br label %exit
615 exit:
616   ret i32 %res
619 ; Test that LG gets converted to LTG where useful.
620 define i64 @f31(i64 %base, i64 %index, ptr %dest) {
621 ; CHECK-LABEL: f31:
622 ; CHECK: ltg %r2, 0({{%r2,%r3|%r3,%r2}})
623 ; CHECK-NEXT: bher %r14
624 ; CHECK: br %r14
625 entry:
626   %add = add i64 %base, %index
627   %ptr = inttoptr i64 %add to ptr
628   %res = load i64, ptr %ptr
629   %cmp = icmp sge i64 %res, 0
630   br i1 %cmp, label %exit, label %store
632 store:
633   store i64 %res, ptr %dest
634   br label %exit
636 exit:
637   ret i64 %res
640 ; Test that LGF gets converted to LTGF where useful.
641 define i64 @f32(i64 %base, i64 %index, ptr %dest) {
642 ; CHECK-LABEL: f32:
643 ; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
644 ; CHECK-NEXT: bhr %r14
645 ; CHECK: br %r14
646 entry:
647   %add = add i64 %base, %index
648   %ptr = inttoptr i64 %add to ptr
649   %val = load i32, ptr %ptr
650   %res = sext i32 %val to i64
651   %cmp = icmp sgt i64 %res, 0
652   br i1 %cmp, label %exit, label %store
654 store:
655   store i64 %res, ptr %dest
656   br label %exit
658 exit:
659   ret i64 %res
662 ; Test that LR gets converted to LTR where useful.
663 define i32 @f33(i32 %dummy, i32 %val, ptr %dest) {
664 ; CHECK-LABEL: f33:
665 ; CHECK: ltr %r2, %r3
666 ; CHECK-NEXT: #APP
667 ; CHECK-NEXT: blah %r2
668 ; CHECK-NEXT: #NO_APP
669 ; CHECK-NEXT: blr %r14
670 ; CHECK: br %r14
671 entry:
672   call void asm sideeffect "blah $0", "{r2}"(i32 %val)
673   %cmp = icmp slt i32 %val, 0
674   br i1 %cmp, label %exit, label %store
676 store:
677   store i32 %val, ptr %dest
678   br label %exit
680 exit:
681   ret i32 %val
684 ; Test that LGR gets converted to LTGR where useful.
685 define i64 @f34(i64 %dummy, i64 %val, ptr %dest) {
686 ; CHECK-LABEL: f34:
687 ; CHECK: ltgr %r2, %r3
688 ; CHECK-NEXT: #APP
689 ; CHECK-NEXT: blah %r2
690 ; CHECK-NEXT: #NO_APP
691 ; CHECK-NEXT: bhr %r14
692 ; CHECK: br %r14
693 entry:
694   call void asm sideeffect "blah $0", "{r2}"(i64 %val)
695   %cmp = icmp sgt i64 %val, 0
696   br i1 %cmp, label %exit, label %store
698 store:
699   store i64 %val, ptr %dest
700   br label %exit
702 exit:
703   ret i64 %val
706 ; Test that LGFR gets converted to LTGFR where useful.
707 define i64 @f35(i64 %dummy, i32 %val, ptr %dest) {
708 ; CHECK-LABEL: f35:
709 ; CHECK: ltgfr %r2, %r3
710 ; CHECK-NEXT: #APP
711 ; CHECK-NEXT: blah %r2
712 ; CHECK-NEXT: #NO_APP
713 ; CHECK-NEXT: bhr %r14
714 ; CHECK: br %r14
715 entry:
716   %ext = sext i32 %val to i64
717   call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
718   %cmp = icmp sgt i64 %ext, 0
719   br i1 %cmp, label %exit, label %store
721 store:
722   store i64 %ext, ptr %dest
723   br label %exit
725 exit:
726   ret i64 %ext
729 ; Test a case where it is the source rather than destination of LR that
730 ; we need.
731 define i32 @f36(i32 %val, i32 %dummy, ptr %dest) {
732 ; CHECK-LABEL: f36:
733 ; CHECK: ltr %r3, %r2
734 ; CHECK-NEXT: #APP
735 ; CHECK-NEXT: blah %r3
736 ; CHECK-NEXT: #NO_APP
737 ; CHECK-NEXT: blr %r14
738 ; CHECK: br %r14
739 entry:
740   call void asm sideeffect "blah $0", "{r3}"(i32 %val)
741   %cmp = icmp slt i32 %val, 0
742   br i1 %cmp, label %exit, label %store
744 store:
745   store i32 %val, ptr %dest
746   br label %exit
748 exit:
749   ret i32 %val
752 ; Test a case where it is the source rather than destination of LGR that
753 ; we need.
754 define i64 @f37(i64 %val, i64 %dummy, ptr %dest) {
755 ; CHECK-LABEL: f37:
756 ; CHECK: ltgr %r3, %r2
757 ; CHECK-NEXT: #APP
758 ; CHECK-NEXT: blah %r3
759 ; CHECK-NEXT: #NO_APP
760 ; CHECK-NEXT: blr %r14
761 ; CHECK: br %r14
762 entry:
763   call void asm sideeffect "blah $0", "{r3}"(i64 %val)
764   %cmp = icmp slt i64 %val, 0
765   br i1 %cmp, label %exit, label %store
767 store:
768   store i64 %val, ptr %dest
769   br label %exit
771 exit:
772   ret i64 %val
775 ; Test a case where it is the source rather than destination of LGFR that
776 ; we need.
777 define i32 @f38(i32 %val, i64 %dummy, ptr %dest) {
778 ; CHECK-LABEL: f38:
779 ; CHECK: ltgfr %r3, %r2
780 ; CHECK-NEXT: #APP
781 ; CHECK-NEXT: blah %r3
782 ; CHECK-NEXT: #NO_APP
783 ; CHECK-NEXT: blr %r14
784 ; CHECK: br %r14
785 entry:
786   %ext = sext i32 %val to i64
787   call void asm sideeffect "blah $0", "{r3}"(i64 %ext)
788   %cmp = icmp slt i32 %val, 0
789   br i1 %cmp, label %exit, label %store
791 store:
792   store i32 %val, ptr %dest
793   br label %exit
795 exit:
796   ret i32 %val
799 ; Test f35 for in-register extensions.
800 define i64 @f39(i64 %dummy, i64 %a, ptr %dest) {
801 ; CHECK-LABEL: f39:
802 ; CHECK: ltgfr %r2, %r3
803 ; CHECK-NEXT: #APP
804 ; CHECK-NEXT: blah %r2
805 ; CHECK-NEXT: #NO_APP
806 ; CHECK-NEXT: bhr %r14
807 ; CHECK: br %r14
808 entry:
809   %val = trunc i64 %a to i32
810   %ext = sext i32 %val to i64
811   call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
812   %cmp = icmp sgt i64 %ext, 0
813   br i1 %cmp, label %exit, label %store
815 store:
816   store i64 %ext, ptr %dest
817   br label %exit
819 exit:
820   ret i64 %ext
823 ; ...and again with what InstCombine would produce for f40.
824 define i64 @f40(i64 %dummy, i64 %a, ptr %dest) {
825 ; CHECK-LABEL: f40:
826 ; CHECK: ltgfr %r2, %r3
827 ; CHECK-NEXT: #APP
828 ; CHECK-NEXT: blah %r2
829 ; CHECK-NEXT: #NO_APP
830 ; CHECK-NEXT: bhr %r14
831 ; CHECK: br %r14
832 entry:
833   %shl = shl i64 %a, 32
834   %ext = ashr i64 %shl, 32
835   call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
836   %cmp = icmp sgt i64 %shl, 0
837   br i1 %cmp, label %exit, label %store
839 store:
840   store i64 %ext, ptr %dest
841   br label %exit
843 exit:
844   ret i64 %ext
847 ; Try a form of f7 in which the subtraction operands are compared directly.
848 define i32 @f41(i32 %a, i32 %b, ptr %dest) {
849 ; CHECK-LABEL: f41:
850 ; CHECK: s %r2, 0(%r4)
851 ; CHECK-NEXT: bner %r14
852 ; CHECK: br %r14
853 entry:
854   %cur = load i32, ptr %dest
855   %res = sub i32 %a, %cur
856   %cmp = icmp ne i32 %a, %cur
857   br i1 %cmp, label %exit, label %store
859 store:
860   store i32 %b, ptr %dest
861   br label %exit
863 exit:
864   ret i32 %res
867 ; A version of f32 that tests the unextended value.
868 define i64 @f42(i64 %base, i64 %index, ptr %dest) {
869 ; CHECK-LABEL: f42:
870 ; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
871 ; CHECK-NEXT: bhr %r14
872 ; CHECK: br %r14
873 entry:
874   %add = add i64 %base, %index
875   %ptr = inttoptr i64 %add to ptr
876   %val = load i32, ptr %ptr
877   %res = sext i32 %val to i64
878   %cmp = icmp sgt i32 %val, 0
879   br i1 %cmp, label %exit, label %store
881 store:
882   store i64 %res, ptr %dest
883   br label %exit
885 exit:
886   ret i64 %res
889 !1 = !{!"branch_weights", i32 2, i32 1}