1 # RUN: llc -run-pass=peephole-opt %s -o - | FileCheck %s
2 # RUN: llc -passes=peephole-opt %s -o - | FileCheck %s
4 # Test the compare fold peephole.
6 # CHECK-LABEL: name: test0a
7 # TODO: Enhance combiner to handle this case. This expands into:
10 # sel.eq $r18, $r3, $rv
11 # This is different from the pattern currently matched. If the lowered form had
12 # been sub.f $r3, 0, $r0 then it would have matched.
14 # CHECK-LABEL: name: test1a
15 # CHECK: [[IN1:%.*]]:gpr = COPY $r7
16 # CHECK: [[IN2:%.*]]:gpr = COPY $r6
17 # CHECK: SUB_F_R [[IN1]], [[IN2]], 0, implicit-def $sr
19 # CHECK-LABEL: name: test1b
20 # CHECK: [[IN1:%.*]]:gpr = COPY $r7
21 # CHECK: [[IN2:%.*]]:gpr = COPY $r6
22 # CHECK: SUB_F_R [[IN1]], [[IN2]], 0, implicit-def $sr
24 # CHECK-LABEL: name: test2a
25 # CHECK: [[IN1:%.*]]:gpr = COPY $r7
26 # CHECK: [[IN2:%.*]]:gpr = COPY $r6
27 # CHECK: SUB_F_R [[IN1]], [[IN2]], 0, implicit-def $sr
29 # CHECK-LABEL: name: test2b
30 # CHECK: [[IN1:%.*]]:gpr = COPY $r7
31 # CHECK: [[IN2:%.*]]:gpr = COPY $r6
32 # CHECK: SUB_F_R [[IN1]], [[IN2]], 0, implicit-def $sr
34 # CHECK-LABEL: name: test3
40 target datalayout = "E-m:e-p:32:32-i64:64-a:0:32-n32-S64"
41 target triple = "lanai-unknown-unknown"
43 @a = global i32 -1, align 4
44 @b = global i32 0, align 4
46 define i32 @test0a(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
49 %cmp = icmp eq i32 %sub, 0
50 %cond = select i1 %cmp, i32 %c, i32 %sub
54 define i32 @test0b(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
56 %cmp = icmp eq i32 %b, %a
57 %cond = select i1 %cmp, i32 %c, i32 %b
61 define i32 @test1a(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
64 %cmp = icmp slt i32 %sub, 0
65 %cond = select i1 %cmp, i32 %c, i32 %d
69 define i32 @test1b(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
72 %cmp = icmp slt i32 %sub, 0
73 %cond = select i1 %cmp, i32 %c, i32 %d
77 define i32 @test2a(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
80 %cmp = icmp sgt i32 %sub, -1
81 %cond = select i1 %cmp, i32 %c, i32 %d
85 define i32 @test2b(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
88 %cmp = icmp sgt i32 %sub, -1
89 %cond = select i1 %cmp, i32 %c, i32 %d
93 define i32 @test3(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
96 %cmp = icmp slt i32 %sub, 1
97 %cond = select i1 %cmp, i32 %c, i32 %d
101 define i32 @test4(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) {
103 %cmp = icmp ne i32 %a, 0
104 %cmp1 = icmp ult i32 %a, %b
105 %or.cond = and i1 %cmp, %cmp1
106 br i1 %or.cond, label %return, label %if.end
108 if.end: ; preds = %entry
109 %cmp2 = icmp ne i32 %b, 0
110 %cmp4 = icmp ult i32 %b, %c
111 %or.cond29 = and i1 %cmp2, %cmp4
112 br i1 %or.cond29, label %return, label %if.end6
114 if.end6: ; preds = %if.end
115 %cmp7 = icmp ne i32 %c, 0
116 %cmp9 = icmp ult i32 %c, %d
117 %or.cond30 = and i1 %cmp7, %cmp9
118 br i1 %or.cond30, label %return, label %if.end11
120 if.end11: ; preds = %if.end6
121 %cmp12 = icmp ne i32 %d, 0
122 %cmp14 = icmp ult i32 %d, %a
123 %or.cond31 = and i1 %cmp12, %cmp14
124 %b. = select i1 %or.cond31, i32 %b, i32 21
127 return: ; preds = %if.end6, %if.end, %entry
128 %retval.0 = phi i32 [ %c, %entry ], [ %d, %if.end ], [ %a, %if.end6 ]
132 define void @testBB() {
134 %0 = load i32, ptr @a, align 4, !tbaa !0
135 %1 = load i32, ptr @b, align 4, !tbaa !0
136 %sub.i = sub i32 %1, %0
137 %tobool = icmp sgt i32 %sub.i, -1
138 br i1 %tobool, label %if.end, label %if.then
140 if.then: ; preds = %entry
141 %call1 = tail call i32 @g()
144 while.body: ; preds = %while.body, %if.then
147 if.end: ; preds = %entry
148 %cmp.i = icmp slt i32 %sub.i, 1
149 br i1 %cmp.i, label %if.then4, label %if.end7
151 if.then4: ; preds = %if.end
152 %call5 = tail call i32 @g()
153 br label %while.body6
155 while.body6: ; preds = %while.body6, %if.then4
156 br label %while.body6
158 if.end7: ; preds = %if.end
164 ; Function Attrs: nounwind
165 declare void @llvm.stackprotector(ptr, ptr) #0
167 attributes #0 = { nounwind }
169 !0 = !{!1, !1, i64 0}
170 !1 = !{!"int", !2, i64 0}
171 !2 = !{!"omnipotent char", !3, i64 0}
172 !3 = !{!"Simple C/C++ TBAA"}
178 exposesReturnsTwice: false
179 tracksRegLiveness: true
181 - { id: 0, class: gpr }
182 - { id: 1, class: gpr }
183 - { id: 2, class: gpr }
184 - { id: 3, class: gpr }
185 - { id: 4, class: gpr }
186 - { id: 5, class: gpr }
188 - { reg: '$r6', virtual-reg: '%0' }
189 - { reg: '$r7', virtual-reg: '%1' }
190 - { reg: '$r18', virtual-reg: '%2' }
192 isFrameAddressTaken: false
193 isReturnAddressTaken: false
202 hasOpaqueSPAdjustment: false
204 hasMustTailInVarArgFunc: false
207 liveins: $r6, $r7, $r18
213 SFSUB_F_RI_LO %4, 0, implicit-def $sr
214 %5 = SELECT %2, %4, 7, implicit $sr
216 RET implicit $rca, implicit $rv
222 exposesReturnsTwice: false
223 tracksRegLiveness: true
225 - { id: 0, class: gpr }
226 - { id: 1, class: gpr }
227 - { id: 2, class: gpr }
228 - { id: 3, class: gpr }
229 - { id: 4, class: gpr }
231 - { reg: '$r6', virtual-reg: '%0' }
232 - { reg: '$r7', virtual-reg: '%1' }
233 - { reg: '$r18', virtual-reg: '%2' }
235 isFrameAddressTaken: false
236 isReturnAddressTaken: false
245 hasOpaqueSPAdjustment: false
247 hasMustTailInVarArgFunc: false
250 liveins: $r6, $r7, $r18
255 SFSUB_F_RR %1, %0, implicit-def $sr
256 %4 = SELECT %2, %1, 7, implicit $sr
258 RET implicit $rca, implicit $rv
264 exposesReturnsTwice: false
265 tracksRegLiveness: true
267 - { id: 0, class: gpr }
268 - { id: 1, class: gpr }
269 - { id: 2, class: gpr }
270 - { id: 3, class: gpr }
271 - { id: 4, class: gpr }
272 - { id: 5, class: gpr }
274 - { reg: '$r6', virtual-reg: '%0' }
275 - { reg: '$r7', virtual-reg: '%1' }
276 - { reg: '$r18', virtual-reg: '%2' }
277 - { reg: '$r19', virtual-reg: '%3' }
279 isFrameAddressTaken: false
280 isReturnAddressTaken: false
289 hasOpaqueSPAdjustment: false
291 hasMustTailInVarArgFunc: false
294 liveins: $r6, $r7, $r18, $r19
301 SFSUB_F_RI_LO killed %4, 0, implicit-def $sr
302 %5 = SELECT %2, %3, 11, implicit $sr
304 RET implicit $rca, implicit $rv
310 exposesReturnsTwice: false
311 tracksRegLiveness: true
313 - { id: 0, class: gpr }
314 - { id: 1, class: gpr }
315 - { id: 2, class: gpr }
316 - { id: 3, class: gpr }
317 - { id: 4, class: gpr }
318 - { id: 5, class: gpr }
320 - { reg: '$r6', virtual-reg: '%0' }
321 - { reg: '$r7', virtual-reg: '%1' }
322 - { reg: '$r18', virtual-reg: '%2' }
323 - { reg: '$r19', virtual-reg: '%3' }
325 isFrameAddressTaken: false
326 isReturnAddressTaken: false
335 hasOpaqueSPAdjustment: false
337 hasMustTailInVarArgFunc: false
340 liveins: $r6, $r7, $r18, $r19
347 SFSUB_F_RI_LO killed %4, 0, implicit-def $sr
348 %5 = SELECT %2, %3, 11, implicit $sr
350 RET implicit $rca, implicit $rv
356 exposesReturnsTwice: false
357 tracksRegLiveness: true
359 - { id: 0, class: gpr }
360 - { id: 1, class: gpr }
361 - { id: 2, class: gpr }
362 - { id: 3, class: gpr }
363 - { id: 4, class: gpr }
364 - { id: 5, class: gpr }
366 - { reg: '$r6', virtual-reg: '%0' }
367 - { reg: '$r7', virtual-reg: '%1' }
368 - { reg: '$r18', virtual-reg: '%2' }
369 - { reg: '$r19', virtual-reg: '%3' }
371 isFrameAddressTaken: false
372 isReturnAddressTaken: false
381 hasOpaqueSPAdjustment: false
383 hasMustTailInVarArgFunc: false
386 liveins: $r6, $r7, $r18, $r19
393 SFSUB_F_RI_LO killed %4, 0, implicit-def $sr
394 %5 = SELECT %2, %3, 10, implicit $sr
396 RET implicit $rca, implicit $rv
402 exposesReturnsTwice: false
403 tracksRegLiveness: true
405 - { id: 0, class: gpr }
406 - { id: 1, class: gpr }
407 - { id: 2, class: gpr }
408 - { id: 3, class: gpr }
409 - { id: 4, class: gpr }
410 - { id: 5, class: gpr }
412 - { reg: '$r6', virtual-reg: '%0' }
413 - { reg: '$r7', virtual-reg: '%1' }
414 - { reg: '$r18', virtual-reg: '%2' }
415 - { reg: '$r19', virtual-reg: '%3' }
417 isFrameAddressTaken: false
418 isReturnAddressTaken: false
427 hasOpaqueSPAdjustment: false
429 hasMustTailInVarArgFunc: false
432 liveins: $r6, $r7, $r18, $r19
439 SFSUB_F_RI_LO killed %4, 0, implicit-def $sr
440 %5 = SELECT %2, %3, 10, implicit $sr
442 RET implicit $rca, implicit $rv
448 exposesReturnsTwice: false
449 tracksRegLiveness: true
451 - { id: 0, class: gpr }
452 - { id: 1, class: gpr }
453 - { id: 2, class: gpr }
454 - { id: 3, class: gpr }
455 - { id: 4, class: gpr }
456 - { id: 5, class: gpr }
458 - { reg: '$r6', virtual-reg: '%0' }
459 - { reg: '$r7', virtual-reg: '%1' }
460 - { reg: '$r18', virtual-reg: '%2' }
461 - { reg: '$r19', virtual-reg: '%3' }
463 isFrameAddressTaken: false
464 isReturnAddressTaken: false
473 hasOpaqueSPAdjustment: false
475 hasMustTailInVarArgFunc: false
478 liveins: $r6, $r7, $r18, $r19
485 SFSUB_F_RI_LO killed %4, 1, implicit-def $sr
486 %5 = SELECT %2, %3, 13, implicit $sr
488 RET implicit $rca, implicit $rv
494 exposesReturnsTwice: false
495 tracksRegLiveness: true
497 - { id: 0, class: gpr }
498 - { id: 1, class: gpr }
499 - { id: 2, class: gpr }
500 - { id: 3, class: gpr }
501 - { id: 4, class: gpr }
502 - { id: 5, class: gpr }
503 - { id: 6, class: gpr }
504 - { id: 7, class: gpr }
505 - { id: 8, class: gpr }
506 - { id: 9, class: gpr }
507 - { id: 10, class: gpr }
508 - { id: 11, class: gpr }
509 - { id: 12, class: gpr }
510 - { id: 13, class: gpr }
511 - { id: 14, class: gpr }
512 - { id: 15, class: gpr }
513 - { id: 16, class: gpr }
514 - { id: 17, class: gpr }
515 - { id: 18, class: gpr }
516 - { id: 19, class: gpr }
517 - { id: 20, class: gpr }
518 - { id: 21, class: gpr }
519 - { id: 22, class: gpr }
521 - { reg: '$r6', virtual-reg: '%1' }
522 - { reg: '$r7', virtual-reg: '%2' }
523 - { reg: '$r18', virtual-reg: '%3' }
524 - { reg: '$r19', virtual-reg: '%4' }
526 isFrameAddressTaken: false
527 isReturnAddressTaken: false
536 hasOpaqueSPAdjustment: false
538 hasMustTailInVarArgFunc: false
541 successors: %bb.4.return, %bb.1.if.end
542 liveins: $r6, $r7, $r18, $r19
548 SFSUB_F_RI_LO %1, 0, implicit-def $sr
549 %5 = SCC 6, implicit $sr
550 SFSUB_F_RR %1, %2, implicit-def $sr
551 %6 = SCC 4, implicit $sr
552 %7 = AND_R killed %5, killed %6, 0
554 %9 = AND_R killed %7, %8, 0
555 SFSUB_F_RI_LO killed %9, 0, implicit-def $sr
556 BRCC %bb.4.return, 6, implicit $sr
560 successors: %bb.4.return, %bb.2.if.end6
562 SFSUB_F_RI_LO %2, 0, implicit-def $sr
563 %10 = SCC 6, implicit $sr
564 SFSUB_F_RR %2, %3, implicit-def $sr
565 %11 = SCC 4, implicit $sr
566 %12 = AND_R killed %10, killed %11, 0
567 %14 = AND_R killed %12, %8, 0
568 SFSUB_F_RI_LO killed %14, 0, implicit-def $sr
569 BRCC %bb.4.return, 6, implicit $sr
573 successors: %bb.4.return, %bb.3.if.end11
575 SFSUB_F_RI_LO %3, 0, implicit-def $sr
576 %15 = SCC 6, implicit $sr
577 SFSUB_F_RR %3, %4, implicit-def $sr
578 %16 = SCC 4, implicit $sr
579 %17 = AND_R killed %15, killed %16, 0
581 %19 = AND_R killed %17, killed %18, 0
582 SFSUB_F_RI_LO killed %19, 0, implicit-def $sr
583 BRCC %bb.4.return, 6, implicit $sr
588 SFSUB_F_RR %4, %1, implicit-def $sr
589 %21 = SELECT %2, %20, 4, implicit $sr
590 SFSUB_F_RI_LO %4, 0, implicit-def $sr
591 %22 = SELECT killed %21, %20, 6, implicit $sr
593 RET implicit $rca, implicit $rv
596 %0 = PHI %3, %bb.0.entry, %4, %bb.1.if.end, %1, %bb.2.if.end6
598 RET implicit $rca, implicit $rv
604 exposesReturnsTwice: false
605 tracksRegLiveness: true
607 - { id: 0, class: gpr }
608 - { id: 1, class: gpr }
609 - { id: 2, class: gpr }
610 - { id: 3, class: gpr }
611 - { id: 4, class: gpr }
612 - { id: 5, class: gpr }
613 - { id: 6, class: gpr }
614 - { id: 7, class: gpr }
615 - { id: 8, class: gpr }
617 isFrameAddressTaken: false
618 isReturnAddressTaken: false
627 hasOpaqueSPAdjustment: false
629 hasMustTailInVarArgFunc: false
632 successors: %bb.3.if.end, %bb.1.if.then
634 %1 = MOVHI target-flags(lanai-hi) @a
635 %2 = OR_I_LO killed %1, target-flags(lanai-lo) @a
636 %3 = LDW_RI killed %2, 0, 0 :: (load (s32) from @a, !tbaa !0)
637 %4 = MOVHI target-flags(lanai-hi) @b
638 %5 = OR_I_LO killed %4, target-flags(lanai-lo) @b
639 %6 = LDW_RI killed %5, 0, 0 :: (load (s32) from @b, !tbaa !0)
640 %0 = SUB_R killed %6, killed %3, 0
641 SFSUB_F_RI_LO %0, 0, implicit-def $sr
642 BRCC %bb.3.if.end, 10, implicit $sr
646 successors: %bb.2.while.body
648 ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
649 CALL @g, csr, implicit-def dead $rca, implicit $sp, implicit-def $sp, implicit-def $rv
650 ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
653 successors: %bb.2.while.body
658 successors: %bb.4.if.then4, %bb.6.if.end7
661 BRCC %bb.6.if.end7, 14, implicit $sr
665 successors: %bb.5.while.body6
667 ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
668 CALL @g, csr, implicit-def dead $rca, implicit $sp, implicit-def $sp, implicit-def $rv
669 ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
672 successors: %bb.5.while.body6