blob: 6bc8b8a041c2da8026264e71b4231dfd30ee9e81 [file] [log] [blame]
Hiroshi Inoue614453b2017-09-05 04:15:17 +00001; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s
2; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s
3
4; Test cases for compare elimination in PPCMIPeephole pass
5
6define void @func1(i32 signext %a) {
7; We should have only one compare instruction
8; CHECK-LABEL: @func1
9; CHECK: cmp
10; CHECK-NOT: cmp
11; CHECK: blr
12entry:
13 %cmp = icmp eq i32 %a, 100
14 br i1 %cmp, label %if.then, label %if.else
15
16if.then:
17 tail call void @dummy1()
18 br label %if.end3
19
20if.else:
21 %cmp1 = icmp slt i32 %a, 100
22 br i1 %cmp1, label %if.then2, label %if.end3
23
24if.then2:
25 tail call void @dummy2()
26 br label %if.end3
27
28if.end3:
29 ret void
30}
31
32
33define void @func2(i32 signext %a) {
34; CHECK-LABEL: @func2
35; CHECK: cmp
36; CHECK-NOT: cmp
37; CHECK: blr
38entry:
39 %cmp = icmp slt i32 %a, 100
40 br i1 %cmp, label %if.then, label %if.else
41
42if.then:
43 tail call void @dummy1()
44 br label %if.end3
45
46if.else:
47 %cmp1 = icmp eq i32 %a, 100
48 br i1 %cmp1, label %if.end3, label %if.then2
49
50if.then2:
51 tail call void @dummy2()
52 br label %if.end3
53
54if.end3:
55 ret void
56}
57
58
59define void @func3(i32 signext %a) {
60; CHECK-LABEL: @func3
61; CHECK: cmp
62; CHECK-NOT: cmp
63; CHECK: blr
64entry:
65 %cmp = icmp sgt i32 %a, 100
66 br i1 %cmp, label %if.then, label %if.else
67
68if.then:
69 tail call void @dummy1()
70 br label %if.end3
71
72if.else:
73 %cmp1 = icmp eq i32 %a, 100
74 br i1 %cmp1, label %if.then2, label %if.end3
75
76if.then2:
77 tail call void @dummy2()
78 br label %if.end3
79
80if.end3:
81 ret void
82}
83
84
85define void @func4(i32 zeroext %a) {
86; CHECK-LABEL: @func4
87; CHECK: cmp
88; CHECK-NOT: cmp
89; CHECK: blr
90entry:
91 %cmp = icmp eq i32 %a, 100
92 br i1 %cmp, label %if.then, label %if.else
93
94if.then:
95 tail call void @dummy1()
96 br label %if.end3
97
98if.else:
99 %cmp1 = icmp ult i32 %a, 100
100 br i1 %cmp1, label %if.then2, label %if.end3
101
102if.then2:
103 tail call void @dummy2()
104 br label %if.end3
105
106if.end3:
107 ret void
108}
109
110
111define void @func5(i32 zeroext %a) {
112; CHECK-LABEL: @func5
113; CHECK: cmp
114; CHECK-NOT: cmp
115; CHECK: blr
116entry:
117 %cmp = icmp ult i32 %a, 100
118 br i1 %cmp, label %if.then, label %if.else
119
120if.then:
121 tail call void @dummy1()
122 br label %if.end3
123
124if.else:
125 %cmp1 = icmp eq i32 %a, 100
126 br i1 %cmp1, label %if.end3, label %if.then2
127
128if.then2:
129 tail call void @dummy2()
130 br label %if.end3
131
132if.end3:
133 ret void
134}
135
136
137define void @func6(i32 zeroext %a) {
138; CHECK-LABEL: @func6
139; CHECK: cmp
140; CHECK-NOT: cmp
141; CHECK: blr
142entry:
143 %cmp = icmp ugt i32 %a, 100
144 br i1 %cmp, label %if.then, label %if.else
145
146if.then:
147 tail call void @dummy1()
148 br label %if.end3
149
150if.else:
151 %cmp1 = icmp eq i32 %a, 100
152 br i1 %cmp1, label %if.then2, label %if.end3
153
154if.then2:
155 tail call void @dummy2()
156 br label %if.end3
157
158if.end3:
159 ret void
160}
161
162
163define void @func7(i64 %a) {
164; CHECK-LABEL: @func7
165; CHECK: cmp
166; CHECK-NOT: cmp
167; CHECK: blr
168entry:
169 %cmp = icmp eq i64 %a, 100
170 br i1 %cmp, label %if.then, label %if.else
171
172if.then:
173 tail call void @dummy1()
174 br label %if.end3
175
176if.else:
177 %cmp1 = icmp slt i64 %a, 100
178 br i1 %cmp1, label %if.then2, label %if.end3
179
180if.then2:
181 tail call void @dummy2()
182 br label %if.end3
183
184if.end3:
185 ret void
186}
187
188
189define void @func8(i64 %a) {
190; CHECK-LABEL: @func8
191; CHECK: cmp
192; CHECK-NOT: cmp
193; CHECK: blr
194entry:
195 %cmp = icmp slt i64 %a, 100
196 br i1 %cmp, label %if.then, label %if.else
197
198if.then:
199 tail call void @dummy1()
200 br label %if.end3
201
202if.else:
203 %cmp1 = icmp eq i64 %a, 100
204 br i1 %cmp1, label %if.end3, label %if.then2
205
206if.then2:
207 tail call void @dummy2()
208 br label %if.end3
209
210if.end3:
211 ret void
212}
213
214
215define void @func9(i64 %a) {
216; CHECK-LABEL: @func9
217; CHECK: cmp
218; CHECK-NOT: cmp
219; CHECK: blr
220entry:
221 %cmp = icmp sgt i64 %a, 100
222 br i1 %cmp, label %if.then, label %if.else
223
224if.then:
225 tail call void @dummy1()
226 br label %if.end3
227
228if.else:
229 %cmp1 = icmp eq i64 %a, 100
230 br i1 %cmp1, label %if.then2, label %if.end3
231
232if.then2:
233 tail call void @dummy2()
234 br label %if.end3
235
236if.end3:
237 ret void
238}
239
240
241define void @func10(i64 %a) {
242; CHECK-LABEL: @func10
243; CHECK: cmp
244; CHECK-NOT: cmp
245; CHECK: blr
246entry:
247 %cmp = icmp eq i64 %a, 100
248 br i1 %cmp, label %if.then, label %if.else
249
250if.then:
251 tail call void @dummy1()
252 br label %if.end3
253
254if.else:
255 %cmp1 = icmp ult i64 %a, 100
256 br i1 %cmp1, label %if.then2, label %if.end3
257
258if.then2:
259 tail call void @dummy2()
260 br label %if.end3
261
262if.end3:
263 ret void
264}
265
266
267define void @func11(i64 %a) {
268; CHECK-LABEL: @func11
269; CHECK: cmp
270; CHECK-NOT: cmp
271; CHECK: blr
272entry:
273 %cmp = icmp ult i64 %a, 100
274 br i1 %cmp, label %if.then, label %if.else
275
276if.then:
277 tail call void @dummy1()
278 br label %if.end3
279
280if.else:
281 %cmp1 = icmp eq i64 %a, 100
282 br i1 %cmp1, label %if.end3, label %if.then2
283
284if.then2:
285 tail call void @dummy2()
286 br label %if.end3
287
288if.end3:
289 ret void
290}
291
292
293define void @func12(i64 %a) {
294; CHECK-LABEL: @func12
295; CHECK: cmp
296; CHECK-NOT: cmp
297; CHECK: blr
298entry:
299 %cmp = icmp ugt i64 %a, 100
300 br i1 %cmp, label %if.then, label %if.else
301
302if.then:
303 tail call void @dummy1()
304 br label %if.end3
305
306if.else:
307 %cmp1 = icmp eq i64 %a, 100
308 br i1 %cmp1, label %if.then2, label %if.end3
309
310if.then2:
311 tail call void @dummy2()
312 br label %if.end3
313
314if.end3:
315 ret void
316}
317
318
319define void @func13(i32 signext %a, i32 signext %b) {
320; CHECK-LABEL: @func13
321; CHECK: cmp
322; CHECK-NOT: cmp
323; CHECK: blr
324entry:
325 %cmp = icmp eq i32 %a, %b
326 br i1 %cmp, label %if.then, label %if.else
327
328if.then:
329 tail call void @dummy1()
330 br label %if.end3
331
332if.else:
333 %cmp1 = icmp slt i32 %a, %b
334 br i1 %cmp1, label %if.then2, label %if.end3
335
336if.then2:
337 tail call void @dummy2()
338 br label %if.end3
339
340if.end3:
341 ret void
342}
343
344
345define void @func14(i32 signext %a, i32 signext %b) {
346; CHECK-LABEL: @func14
347; CHECK: cmp
348; CHECK-NOT: cmp
349; CHECK: blr
350entry:
351 %cmp = icmp slt i32 %a, %b
352 br i1 %cmp, label %if.then, label %if.else
353
354if.then:
355 tail call void @dummy1()
356 br label %if.end3
357
358if.else:
359 %cmp1 = icmp sgt i32 %a, %b
360 br i1 %cmp1, label %if.then2, label %if.end3
361
362if.then2:
363 tail call void @dummy2()
364 br label %if.end3
365
366if.end3:
367 ret void
368}
369
370
371define void @func15(i32 signext %a, i32 signext %b) {
372; CHECK-LABEL: @func15
373; CHECK: cmp
374; CHECK-NOT: cmp
375; CHECK: blr
376entry:
377 %cmp = icmp slt i32 %b, %a
378 br i1 %cmp, label %if.then, label %if.else
379
380if.then:
381 tail call void @dummy1()
382 br label %if.end3
383
384if.else:
385 %cmp1 = icmp eq i32 %a, %b
386 br i1 %cmp1, label %if.then2, label %if.end3
387
388if.then2:
389 tail call void @dummy2()
390 br label %if.end3
391
392if.end3:
393 ret void
394}
395
396
397define void @func16(i32 zeroext %a, i32 zeroext %b) {
398; CHECK-LABEL: @func16
399; CHECK: cmp
400; CHECK-NOT: cmp
401; CHECK: blr
402entry:
403 %cmp = icmp eq i32 %a, %b
404 br i1 %cmp, label %if.then, label %if.else
405
406if.then:
407 tail call void @dummy1()
408 br label %if.end3
409
410if.else:
411 %cmp1 = icmp ult i32 %a, %b
412 br i1 %cmp1, label %if.then2, label %if.end3
413
414if.then2:
415 tail call void @dummy2()
416 br label %if.end3
417
418if.end3:
419 ret void
420}
421
422
423define void @func17(i32 zeroext %a, i32 zeroext %b) {
424; CHECK-LABEL: @func17
425; CHECK: cmp
426; CHECK-NOT: cmp
427; CHECK: blr
428entry:
429 %cmp = icmp ult i32 %a, %b
430 br i1 %cmp, label %if.then, label %if.else
431
432if.then:
433 tail call void @dummy1()
434 br label %if.end3
435
436if.else:
437 %cmp1 = icmp ugt i32 %a, %b
438 br i1 %cmp1, label %if.then2, label %if.end3
439
440if.then2:
441 tail call void @dummy2()
442 br label %if.end3
443
444if.end3:
445 ret void
446}
447
448
449define void @func18(i32 zeroext %a, i32 zeroext %b) {
450; CHECK-LABEL: @func18
451; CHECK: cmp
452; CHECK-NOT: cmp
453; CHECK: blr
454entry:
455 %cmp = icmp ult i32 %b, %a
456 br i1 %cmp, label %if.then, label %if.else
457
458if.then:
459 tail call void @dummy1()
460 br label %if.end3
461
462if.else:
463 %cmp1 = icmp eq i32 %a, %b
464 br i1 %cmp1, label %if.then2, label %if.end3
465
466if.then2:
467 tail call void @dummy2()
468 br label %if.end3
469
470if.end3:
471 ret void
472}
473
474
475define void @func19(i64 %a, i64 %b) {
476; CHECK-LABEL: @func19
477; CHECK: cmp
478; CHECK-NOT: cmp
479; CHECK: blr
480entry:
481 %cmp = icmp eq i64 %a, %b
482 br i1 %cmp, label %if.then, label %if.else
483
484if.then:
485 tail call void @dummy1()
486 br label %if.end3
487
488if.else:
489 %cmp1 = icmp slt i64 %a, %b
490 br i1 %cmp1, label %if.then2, label %if.end3
491
492if.then2:
493 tail call void @dummy2()
494 br label %if.end3
495
496if.end3:
497 ret void
498}
499
500
501define void @func20(i64 %a, i64 %b) {
502; CHECK-LABEL: @func20
503; CHECK: cmp
504; CHECK-NOT: cmp
505; CHECK: blr
506entry:
507 %cmp = icmp slt i64 %a, %b
508 br i1 %cmp, label %if.then, label %if.else
509
510if.then:
511 tail call void @dummy1()
512 br label %if.end3
513
514if.else:
515 %cmp1 = icmp sgt i64 %a, %b
516 br i1 %cmp1, label %if.then2, label %if.end3
517
518if.then2:
519 tail call void @dummy2()
520 br label %if.end3
521
522if.end3:
523 ret void
524}
525
526
527define void @func21(i64 %a, i64 %b) {
528; CHECK-LABEL: @func21
529; CHECK: cmp
530; CHECK-NOT: cmp
531; CHECK: blr
532entry:
533 %cmp = icmp slt i64 %b, %a
534 br i1 %cmp, label %if.then, label %if.else
535
536if.then:
537 tail call void @dummy1()
538 br label %if.end3
539
540if.else:
541 %cmp1 = icmp eq i64 %a, %b
542 br i1 %cmp1, label %if.then2, label %if.end3
543
544if.then2:
545 tail call void @dummy2()
546 br label %if.end3
547
548if.end3:
549 ret void
550}
551
552
553define void @func22(i64 %a, i64 %b) {
554; CHECK-LABEL: @func22
555; CHECK: cmp
556; CHECK-NOT: cmp
557; CHECK: blr
558entry:
559 %cmp = icmp eq i64 %a, %b
560 br i1 %cmp, label %if.then, label %if.else
561
562if.then:
563 tail call void @dummy1()
564 br label %if.end3
565
566if.else:
567 %cmp1 = icmp ult i64 %a, %b
568 br i1 %cmp1, label %if.then2, label %if.end3
569
570if.then2:
571 tail call void @dummy2()
572 br label %if.end3
573
574if.end3:
575 ret void
576}
577
578
579define void @func23(i64 %a, i64 %b) {
580; CHECK-LABEL: @func23
581; CHECK: cmp
582; CHECK-NOT: cmp
583; CHECK: blr
584entry:
585 %cmp = icmp ult i64 %a, %b
586 br i1 %cmp, label %if.then, label %if.else
587
588if.then:
589 tail call void @dummy1()
590 br label %if.end3
591
592if.else:
593 %cmp1 = icmp ugt i64 %a, %b
594 br i1 %cmp1, label %if.then2, label %if.end3
595
596if.then2:
597 tail call void @dummy2()
598 br label %if.end3
599
600if.end3:
601 ret void
602}
603
604
605define void @func24(i64 %a, i64 %b) {
606; CHECK-LABEL: @func24
607; CHECK: cmp
608; CHECK-NOT: cmp
609; CHECK: blr
610entry:
611 %cmp = icmp ult i64 %b, %a
612 br i1 %cmp, label %if.then, label %if.else
613
614if.then:
615 tail call void @dummy1()
616 br label %if.end3
617
618if.else:
619 %cmp1 = icmp eq i64 %a, %b
620 br i1 %cmp1, label %if.then2, label %if.end3
621
622if.then2:
623 tail call void @dummy2()
624 br label %if.end3
625
626if.end3:
627 ret void
628}
629
630
631define void @func25(i64 %a, i64 %b) {
632; CHECK-LABEL: @func25
633; CHECK: cmp
634; CHECK-NOT: cmp
635; CHECK: blr
636entry:
637 %cmp = icmp slt i64 %b, %a
638 br i1 %cmp, label %if.then, label %if.else, !prof !1
639
640if.then:
641 tail call void @dummy1()
642 br label %if.end6
643
644if.else:
645 %cmp2 = icmp eq i64 %a, %b
646 br i1 %cmp2, label %if.then4, label %if.else5
647
648if.then4:
649 tail call void @dummy2()
650 br label %if.end6
651
652if.else5:
653 tail call void @dummy3()
654 br label %if.end6
655
656if.end6:
657 ret void
658}
659
660
661define void @func26(i32 signext %a) {
662; CHECK-LABEL: @func26
663; CHECK: cmp
664; CHECK-NOT: cmp
665; CHECK: blr
666entry:
667 %cmp = icmp sgt i32 %a, 0
668 br i1 %cmp, label %if.then, label %if.else, !prof !2
669
670if.then:
671 tail call void @dummy1()
672 br label %if.end9
673
674if.else:
675 %cmp2 = icmp eq i32 %a, 0
676 br i1 %cmp2, label %if.then7, label %if.else8, !prof !2
677
678if.then7:
679 tail call void @dummy2()
680 br label %if.end9
681
682if.else8:
683 tail call void @dummy3()
684 br label %if.end9
685
686if.end9:
687 ret void
688}
689
690@g1 = external local_unnamed_addr global i32, align 4
691@g2 = external local_unnamed_addr global i32, align 4
692
693define void @func27(i32 signext %a) {
694; CHECK-LABEL: @func27
695; CHECK: cmp
696; CHECK: beq
697; CHECK-NOT: cmp
698; CHECK: bgelr
699; CHECK: blr
700entry:
701 %cmp = icmp eq i32 %a, 0
702 br i1 %cmp, label %if.end3.sink.split, label %if.else
703
704if.else:
705 %cmp1 = icmp slt i32 %a, 0
706 br i1 %cmp1, label %if.end3.sink.split, label %if.end
707
708if.end3.sink.split:
709 %g2.sink = phi i32* [ @g2, %if.else ], [ @g1, %entry ]
710 store i32 0, i32* %g2.sink, align 4
711 br label %if.end
712
713if.end:
714 ret void
715}
716
Hiroshi Inoue79c0bec2017-09-28 08:38:19 +0000717; partially redundant case
718define void @func28(i32 signext %a) {
719; CHECK-LABEL: @func28
720; CHECK: cmplwi [[REG1:[0-9]+]], [[REG2:[0-9]+]]
721; CHECK: .[[LABEL1:[A-Z0-9_]+]]:
722; CHECK-NOT: cmp
723; CHECK: bne 0, .[[LABEL2:[A-Z0-9_]+]]
724; CHECK: bl dummy1
725; CHECK: .[[LABEL2]]:
726; CHECK: cmpwi [[REG1]], [[REG2]]
727; CHECK: bgt 0, .[[LABEL1]]
728; CHECK: blr
729entry:
730 br label %do.body
731
732do.body:
733 %a.addr.0 = phi i32 [ %a, %entry ], [ %call, %if.end ]
734 %cmp = icmp eq i32 %a.addr.0, 0
735 br i1 %cmp, label %if.then, label %if.end
736
737if.then:
738 tail call void @dummy1() #2
739 br label %if.end
740
741if.end:
742 %call = tail call signext i32 @func(i32 signext %a.addr.0) #2
743 %cmp1 = icmp sgt i32 %call, 0
744 br i1 %cmp1, label %do.body, label %do.end
745
746do.end:
747 ret void
748}
749
Hiroshi Inoue11e571e2017-12-20 05:18:19 +0000750define void @func29(i32 signext %a) {
751; We cannot merge two compares due to difference in sign extension behaviors.
752; equivalent C code example:
753; int a = .. ;
754; if (a == -1) dummy1();
755; if (a == (uint16_t)-1) dummy2();
756
757; CHECK-LABEL: @func29
758; CHECK: cmp
759; CHECK: cmp
760; CHECK: blr
761entry:
762 %cmp = icmp eq i32 %a, -1
763 br i1 %cmp, label %if.then, label %if.else
764
765if.then:
766 tail call void @dummy1()
767 br label %if.end3
768
769if.else:
770 %cmp1 = icmp eq i32 %a, 65535
771 br i1 %cmp1, label %if.then2, label %if.end3
772
773if.then2:
774 tail call void @dummy2()
775 br label %if.end3
776
777if.end3:
778 ret void
779}
780
Hiroshi Inoue614453b2017-09-05 04:15:17 +0000781declare void @dummy1()
782declare void @dummy2()
783declare void @dummy3()
Hiroshi Inoue79c0bec2017-09-28 08:38:19 +0000784declare signext i32 @func(i32 signext)
Hiroshi Inoue614453b2017-09-05 04:15:17 +0000785
786!1 = !{!"branch_weights", i32 2000, i32 1}
787!2 = !{!"branch_weights", i32 1, i32 2000}