1; 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
717; partially redundant case
718define void @func28(i32 signext %a) {
719; CHECK-LABEL: @func28
720; CHECK: cmplwi	 [[REG1:[0-9]+]], [[REG2:[0-9]+]]
721; CHECK: .[[LABEL2:[A-Z0-9_]+]]:
722; CHECK: cmpwi   [[REG1]], [[REG2]]
723; CHECK: ble     0, .[[LABEL1:[A-Z0-9_]+]]
724; CHECK-NOT: cmp
725; CHECK: bne     0, .[[LABEL2]]
726; CHECK: bl dummy1
727; CHECK: b .[[LABEL2]]
728; CHECK: .[[LABEL1]]:
729; CHECK: blr
730entry:
731  br label %do.body
732
733do.body:
734  %a.addr.0 = phi i32 [ %a, %entry ], [ %call, %if.end ]
735  %cmp = icmp eq i32 %a.addr.0, 0
736  br i1 %cmp, label %if.then, label %if.end
737
738if.then:
739  tail call void @dummy1() #2
740  br label %if.end
741
742if.end:
743  %call = tail call signext i32 @func(i32 signext %a.addr.0) #2
744  %cmp1 = icmp sgt i32 %call, 0
745  br i1 %cmp1, label %do.body, label %do.end
746
747do.end:
748  ret void
749}
750
751define void @func29(i32 signext %a) {
752; We cannot merge two compares due to difference in sign extension behaviors.
753; equivalent C code example:
754;   int a = .. ;
755;   if (a == -1) dummy1();
756;   if (a == (uint16_t)-1) dummy2();
757
758; CHECK-LABEL: @func29
759; CHECK: cmp
760; CHECK: cmp
761; CHECK: blr
762entry:
763  %cmp = icmp eq i32 %a, -1
764  br i1 %cmp, label %if.then, label %if.else
765
766if.then:
767  tail call void @dummy1()
768  br label %if.end3
769
770if.else:
771  %cmp1 = icmp eq i32 %a, 65535
772  br i1 %cmp1, label %if.then2, label %if.end3
773
774if.then2:
775  tail call void @dummy2()
776  br label %if.end3
777
778if.end3:
779  ret void
780}
781
782declare void @dummy1()
783declare void @dummy2()
784declare void @dummy3()
785declare signext i32 @func(i32 signext)
786
787!1 = !{!"branch_weights", i32 2000, i32 1}
788!2 = !{!"branch_weights", i32 1, i32 2000}
789