1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5 declare void @sideeffect()
7 ; negative test (but we could allow this?) - don't hoist to conditional predecessor block
9 define i32 @add_const_incoming0_speculative(i1 %b, i32 %x, i32 %y) {
10 ; CHECK-LABEL: @add_const_incoming0_speculative(
12 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
14 ; CHECK-NEXT: br label [[THEN]]
16 ; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
17 ; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]
18 ; CHECK-NEXT: [[R:%.*]] = add i32 [[P0]], [[P1]]
19 ; CHECK-NEXT: ret i32 [[R]]
22 br i1 %b, label %if, label %then
28 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]
29 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]
34 define i32 @add_const_incoming0_nonspeculative(i1 %b, i32 %x, i32 %y) {
35 ; CHECK-LABEL: @add_const_incoming0_nonspeculative(
37 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
39 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
40 ; CHECK-NEXT: br label [[THEN]]
42 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ 59, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
43 ; CHECK-NEXT: ret i32 [[R]]
46 br i1 %b, label %if, label %then
52 %p0 = phi i32 [ 42, %entry ], [ %x, %if ]
53 %p1 = phi i32 [ 17, %entry ], [ %y, %if ]
58 ; negative test (but we could allow this?) - don't hoist to conditional predecessor block
60 define i32 @sub_const_incoming0(i1 %b, i32 %x, i32 %y) {
61 ; CHECK-LABEL: @sub_const_incoming0(
63 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
65 ; CHECK-NEXT: br label [[THEN]]
67 ; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
68 ; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]
69 ; CHECK-NEXT: [[R:%.*]] = sub i32 [[P1]], [[P0]]
70 ; CHECK-NEXT: ret i32 [[R]]
73 br i1 %b, label %if, label %then
79 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]
80 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]
85 define i32 @sub_const_incoming1(i1 %b, i32 %x, i32 %y) {
86 ; CHECK-LABEL: @sub_const_incoming1(
88 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
90 ; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
91 ; CHECK-NEXT: br label [[THEN]]
93 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[TMP0]], [[IF]] ], [ 25, [[ENTRY:%.*]] ]
94 ; CHECK-NEXT: ret i32 [[R]]
97 br i1 %b, label %if, label %then
103 %p0 = phi i32 [ %x, %if ], [ 42, %entry ]
104 %p1 = phi i32 [ %y, %if ], [ 17, %entry ]
105 %r = sub i32 %p0, %p1
109 define i8 @mul_const_incoming1(i1 %b, i8 %x, i8 %y) {
110 ; CHECK-LABEL: @mul_const_incoming1(
112 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
114 ; CHECK-NEXT: [[TMP0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]
115 ; CHECK-NEXT: br label [[THEN]]
117 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ -54, [[ENTRY:%.*]] ]
118 ; CHECK-NEXT: ret i8 [[R]]
121 br i1 %b, label %if, label %then
127 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
128 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
133 define i8 @and_const_incoming1(i1 %b, i8 %x, i8 %y) {
134 ; CHECK-LABEL: @and_const_incoming1(
136 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
138 ; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
139 ; CHECK-NEXT: br label [[THEN]]
141 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 0, [[ENTRY:%.*]] ]
142 ; CHECK-NEXT: ret i8 [[R]]
145 br i1 %b, label %if, label %then
151 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
152 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
157 define i8 @xor_const_incoming1(i1 %b, i8 %x, i8 %y) {
158 ; CHECK-LABEL: @xor_const_incoming1(
160 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
162 ; CHECK-NEXT: [[TMP0:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
163 ; CHECK-NEXT: br label [[THEN]]
165 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 59, [[ENTRY:%.*]] ]
166 ; CHECK-NEXT: ret i8 [[R]]
169 br i1 %b, label %if, label %then
175 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
176 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
181 define i64 @or_const_incoming1(i1 %b, i64 %x, i64 %y) {
182 ; CHECK-LABEL: @or_const_incoming1(
184 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
186 ; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[X:%.*]], [[Y:%.*]]
187 ; CHECK-NEXT: br label [[THEN]]
189 ; CHECK-NEXT: [[R:%.*]] = phi i64 [ [[TMP0]], [[IF]] ], [ 19, [[ENTRY:%.*]] ]
190 ; CHECK-NEXT: ret i64 [[R]]
193 br i1 %b, label %if, label %then
199 %p0 = phi i64 [ %x, %if ], [ 3, %entry ]
200 %p1 = phi i64 [ %y, %if ], [ 16, %entry ]
205 define i64 @or_const_incoming01(i1 %b, i64 %x, i64 %y) {
206 ; CHECK-LABEL: @or_const_incoming01(
208 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
210 ; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[X:%.*]], [[Y:%.*]]
211 ; CHECK-NEXT: br label [[THEN]]
213 ; CHECK-NEXT: [[R:%.*]] = phi i64 [ 19, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
214 ; CHECK-NEXT: ret i64 [[R]]
217 br i1 %b, label %if, label %then
223 %p0 = phi i64 [ 3, %entry ], [ %x, %if]
224 %p1 = phi i64 [ %y, %if ], [ 16, %entry ]
229 define i64 @or_const_incoming10(i1 %b, i64 %x, i64 %y) {
230 ; CHECK-LABEL: @or_const_incoming10(
232 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
234 ; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[Y:%.*]], [[X:%.*]]
235 ; CHECK-NEXT: br label [[THEN]]
237 ; CHECK-NEXT: [[R:%.*]] = phi i64 [ [[TMP0]], [[IF]] ], [ 19, [[ENTRY:%.*]] ]
238 ; CHECK-NEXT: ret i64 [[R]]
241 br i1 %b, label %if, label %then
247 %p0 = phi i64 [ %y, %if ], [ 16, %entry ]
248 %p1 = phi i64 [ 3, %entry ], [ %x, %if]
253 ; negative test (but we could allow this?) - don't hoist to conditional predecessor block
255 define i8 @ashr_const_incoming0_speculative(i1 %b, i8 %x, i8 %y) {
256 ; CHECK-LABEL: @ashr_const_incoming0_speculative(
258 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
260 ; CHECK-NEXT: br label [[THEN]]
262 ; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
263 ; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 3, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]
264 ; CHECK-NEXT: [[R:%.*]] = ashr i8 [[P0]], [[P1]]
265 ; CHECK-NEXT: ret i8 [[R]]
268 br i1 %b, label %if, label %then
274 %p0 = phi i8 [ 42, %if ], [ %x, %entry ]
275 %p1 = phi i8 [ 3, %if ], [ %y, %entry ]
276 %r = ashr i8 %p0, %p1
280 define i8 @ashr_const_incoming0(i1 %b, i8 %x, i8 %y) {
281 ; CHECK-LABEL: @ashr_const_incoming0(
283 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
285 ; CHECK-NEXT: [[TMP0:%.*]] = ashr i8 [[X:%.*]], [[Y:%.*]]
286 ; CHECK-NEXT: br label [[THEN]]
288 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
289 ; CHECK-NEXT: ret i8 [[R]]
292 br i1 %b, label %if, label %then
298 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
299 %p1 = phi i8 [ 3, %entry ], [ %y, %if ]
300 %r = ashr i8 %p0, %p1
304 define i8 @lshr_const_incoming1(i1 %b, i8 %x, i8 %y) {
305 ; CHECK-LABEL: @lshr_const_incoming1(
307 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
309 ; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 [[X:%.*]], [[Y:%.*]]
310 ; CHECK-NEXT: br label [[THEN]]
312 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 5, [[ENTRY:%.*]] ]
313 ; CHECK-NEXT: ret i8 [[R]]
316 br i1 %b, label %if, label %then
322 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
323 %p1 = phi i8 [ %y, %if ], [ 3, %entry ]
324 %r = lshr i8 %p0, %p1
328 define i8 @shl_const_incoming1(i1 %b, i8 %x, i8 %y) {
329 ; CHECK-LABEL: @shl_const_incoming1(
331 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
333 ; CHECK-NEXT: [[TMP0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
334 ; CHECK-NEXT: br label [[THEN]]
336 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 80, [[ENTRY:%.*]] ]
337 ; CHECK-NEXT: ret i8 [[R]]
340 br i1 %b, label %if, label %then
346 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
347 %p1 = phi i8 [ %y, %if ], [ 3, %entry ]
348 %r = shl nsw nuw i8 %p0, %p1
352 define i8 @sdiv_not_safe_to_speculate(i1 %b, i8 %x, i8 %y) {
353 ; CHECK-LABEL: @sdiv_not_safe_to_speculate(
355 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
357 ; CHECK-NEXT: br label [[THEN]]
359 ; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
360 ; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 3, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]
361 ; CHECK-NEXT: [[R:%.*]] = sdiv exact i8 [[P0]], [[P1]]
362 ; CHECK-NEXT: ret i8 [[R]]
365 br i1 %b, label %if, label %then
371 %p0 = phi i8 [ 42, %if ], [ %x, %entry ]
372 %p1 = phi i8 [ 3, %if ], [ %y, %entry ]
373 %r = sdiv exact i8 %p0, %p1
377 define i8 @sdiv_const_incoming1(i1 %b, i8 %x, i8 %y) {
378 ; CHECK-LABEL: @sdiv_const_incoming1(
380 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
382 ; CHECK-NEXT: [[TMP0:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
383 ; CHECK-NEXT: br label [[THEN]]
385 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ -2, [[ENTRY:%.*]] ]
386 ; CHECK-NEXT: ret i8 [[R]]
389 br i1 %b, label %if, label %then
395 %p0 = phi i8 [ %x, %if ], [ -42, %entry ]
396 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
397 %r = sdiv i8 %p0, %p1
401 define i8 @udiv_const_incoming1(i1 %b, i8 %x, i8 %y) {
402 ; CHECK-LABEL: @udiv_const_incoming1(
404 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
406 ; CHECK-NEXT: [[TMP0:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
407 ; CHECK-NEXT: br label [[THEN]]
409 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 12, [[ENTRY:%.*]] ]
410 ; CHECK-NEXT: ret i8 [[R]]
413 br i1 %b, label %if, label %then
419 %p0 = phi i8 [ %x, %if ], [ -42, %entry ]
420 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
421 %r = udiv i8 %p0, %p1
425 define i8 @srem_const_incoming1(i1 %b, i8 %x, i8 %y) {
426 ; CHECK-LABEL: @srem_const_incoming1(
428 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
430 ; CHECK-NEXT: [[TMP0:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]]
431 ; CHECK-NEXT: br label [[THEN]]
433 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 8, [[ENTRY:%.*]] ]
434 ; CHECK-NEXT: ret i8 [[R]]
437 br i1 %b, label %if, label %then
443 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
444 %p1 = phi i8 [ %y, %if ], [ -17, %entry ]
445 %r = srem i8 %p0, %p1
449 define i8 @urem_const_incoming1(i1 %b, i8 %x, i8 %y) {
450 ; CHECK-LABEL: @urem_const_incoming1(
452 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
454 ; CHECK-NEXT: [[TMP0:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]]
455 ; CHECK-NEXT: br label [[THEN]]
457 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 42, [[ENTRY:%.*]] ]
458 ; CHECK-NEXT: ret i8 [[R]]
461 br i1 %b, label %if, label %then
467 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
468 %p1 = phi i8 [ %y, %if ], [ -17, %entry ]
469 %r = urem i8 %p0, %p1
473 define float @fmul_const_incoming1(i1 %b, float %x, float %y) {
474 ; CHECK-LABEL: @fmul_const_incoming1(
476 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
478 ; CHECK-NEXT: [[TMP0:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
479 ; CHECK-NEXT: br label [[THEN]]
481 ; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 7.140000e+02, [[ENTRY:%.*]] ]
482 ; CHECK-NEXT: ret float [[R]]
485 br i1 %b, label %if, label %then
491 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]
492 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]
493 %r = fmul float %p0, %p1
497 define float @fadd_const_incoming1(i1 %b, float %x, float %y) {
498 ; CHECK-LABEL: @fadd_const_incoming1(
500 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
502 ; CHECK-NEXT: [[TMP0:%.*]] = fadd fast float [[X:%.*]], [[Y:%.*]]
503 ; CHECK-NEXT: br label [[THEN]]
505 ; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 5.900000e+01, [[ENTRY:%.*]] ]
506 ; CHECK-NEXT: ret float [[R]]
509 br i1 %b, label %if, label %then
515 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]
516 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]
517 %r = fadd fast float %p0, %p1
521 define float @fsub_const_incoming1(i1 %b, float %x, float %y) {
522 ; CHECK-LABEL: @fsub_const_incoming1(
524 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
526 ; CHECK-NEXT: [[TMP0:%.*]] = fsub nnan ninf float [[X:%.*]], [[Y:%.*]]
527 ; CHECK-NEXT: br label [[THEN]]
529 ; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 2.500000e+01, [[ENTRY:%.*]] ]
530 ; CHECK-NEXT: ret float [[R]]
533 br i1 %b, label %if, label %then
539 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]
540 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]
541 %r = fsub ninf nnan float %p0, %p1
545 define float @frem_const_incoming1(i1 %b, float %x, float %y) {
546 ; CHECK-LABEL: @frem_const_incoming1(
548 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
550 ; CHECK-NEXT: [[TMP0:%.*]] = frem nsz float [[X:%.*]], [[Y:%.*]]
551 ; CHECK-NEXT: br label [[THEN]]
553 ; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 8.000000e+00, [[ENTRY:%.*]] ]
554 ; CHECK-NEXT: ret float [[R]]
557 br i1 %b, label %if, label %then
563 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]
564 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]
565 %r = frem nsz float %p0, %p1
569 define i32 @add_const_incoming0_use1(i1 %b, i32 %x, i32 %y) {
570 ; CHECK-LABEL: @add_const_incoming0_use1(
572 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
574 ; CHECK-NEXT: br label [[THEN]]
576 ; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
577 ; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]
578 ; CHECK-NEXT: call void @use(i32 [[P0]])
579 ; CHECK-NEXT: [[R:%.*]] = add i32 [[P0]], [[P1]]
580 ; CHECK-NEXT: ret i32 [[R]]
583 br i1 %b, label %if, label %then
589 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]
590 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]
591 call void @use(i32 %p0)
592 %r = add i32 %p0, %p1
596 define i32 @add_const_incoming0_use2(i1 %b, i32 %x, i32 %y) {
597 ; CHECK-LABEL: @add_const_incoming0_use2(
599 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
601 ; CHECK-NEXT: br label [[THEN]]
603 ; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
604 ; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]
605 ; CHECK-NEXT: call void @use(i32 [[P1]])
606 ; CHECK-NEXT: [[R:%.*]] = add i32 [[P0]], [[P1]]
607 ; CHECK-NEXT: ret i32 [[R]]
610 br i1 %b, label %if, label %then
616 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]
617 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]
618 call void @use(i32 %p1)
619 %r = add i32 %p0, %p1
623 define i64 @or_notconst_incoming(i1 %b, i64 %x, i64 %y) {
624 ; CHECK-LABEL: @or_notconst_incoming(
626 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
628 ; CHECK-NEXT: br label [[THEN]]
630 ; CHECK-NEXT: [[P0:%.*]] = phi i64 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
631 ; CHECK-NEXT: [[P1:%.*]] = phi i64 [ [[Y:%.*]], [[IF]] ], [ 43, [[ENTRY]] ]
632 ; CHECK-NEXT: [[R:%.*]] = or i64 [[P0]], [[P1]]
633 ; CHECK-NEXT: ret i64 [[R]]
636 br i1 %b, label %if, label %then
642 %p0 = phi i64 [ 42, %if ], [ %x, %entry ]
643 %p1 = phi i64 [ %y, %if ], [ 43, %entry ]
648 ; The mul could be hoisted before the call that may not return
649 ; if we are ok with speculating a potentially expensive op.
651 define i8 @mul_const_incoming0_speculatable(i1 %b, i8 %x, i8 %y) {
652 ; CHECK-LABEL: @mul_const_incoming0_speculatable(
654 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
656 ; CHECK-NEXT: br label [[THEN]]
658 ; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[ENTRY:%.*]] ], [ [[X:%.*]], [[IF]] ]
659 ; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 17, [[ENTRY]] ], [ [[Y:%.*]], [[IF]] ]
660 ; CHECK-NEXT: call void @sideeffect()
661 ; CHECK-NEXT: [[R:%.*]] = mul i8 [[P0]], [[P1]]
662 ; CHECK-NEXT: ret i8 [[R]]
665 br i1 %b, label %if, label %then
671 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
672 %p1 = phi i8 [ 17, %entry ], [ %y, %if ]
673 call void @sideeffect()
678 ; The udiv should never be hoisted before the call that may not return.
680 define i8 @udiv_const_incoming0_not_speculatable(i1 %b, i8 %x, i8 %y) {
681 ; CHECK-LABEL: @udiv_const_incoming0_not_speculatable(
683 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
685 ; CHECK-NEXT: br label [[THEN]]
687 ; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[ENTRY:%.*]] ], [ [[X:%.*]], [[IF]] ]
688 ; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 17, [[ENTRY]] ], [ [[Y:%.*]], [[IF]] ]
689 ; CHECK-NEXT: call void @sideeffect()
690 ; CHECK-NEXT: [[R:%.*]] = udiv i8 [[P0]], [[P1]]
691 ; CHECK-NEXT: ret i8 [[R]]
694 br i1 %b, label %if, label %then
700 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
701 %p1 = phi i8 [ 17, %entry ], [ %y, %if ]
702 call void @sideeffect()
703 %r = udiv i8 %p0, %p1
707 ; TODO: It is ok to hoist the udiv even though it is not in the same block as the phis.
709 define i8 @udiv_const_incoming0_different_block(i1 %b, i8 %x, i8 %y) {
710 ; CHECK-LABEL: @udiv_const_incoming0_different_block(
712 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
714 ; CHECK-NEXT: br label [[THEN]]
716 ; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[ENTRY:%.*]] ], [ [[X:%.*]], [[IF]] ]
717 ; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 17, [[ENTRY]] ], [ [[Y:%.*]], [[IF]] ]
718 ; CHECK-NEXT: br label [[END:%.*]]
720 ; CHECK-NEXT: [[R:%.*]] = udiv i8 [[P0]], [[P1]]
721 ; CHECK-NEXT: ret i8 [[R]]
724 br i1 %b, label %if, label %then
730 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
731 %p1 = phi i8 [ 17, %entry ], [ %y, %if ]
735 %r = udiv i8 %p0, %p1
739 define { i64, i32 } @ParseRetVal(i1 %b, ptr %x) {
740 ; CHECK-LABEL: @ParseRetVal(
742 ; CHECK-NEXT: br i1 [[B:%.*]], label [[T:%.*]], label [[F:%.*]]
744 ; CHECK-NEXT: [[T4:%.*]] = tail call { i64, i32 } [[X:%.*]]()
745 ; CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i32 } [[T4]], 0
746 ; CHECK-NEXT: [[T6:%.*]] = extractvalue { i64, i32 } [[T4]], 1
747 ; CHECK-NEXT: br label [[F]]
749 ; CHECK-NEXT: [[T16:%.*]] = phi i32 [ [[T6]], [[T]] ], [ 0, [[ENTRY:%.*]] ]
750 ; CHECK-NEXT: [[T19:%.*]] = phi i64 [ [[T5]], [[T]] ], [ 0, [[ENTRY]] ]
751 ; CHECK-NEXT: [[T20:%.*]] = insertvalue { i64, i32 } poison, i64 [[T19]], 0
752 ; CHECK-NEXT: [[T21:%.*]] = insertvalue { i64, i32 } [[T20]], i32 [[T16]], 1
753 ; CHECK-NEXT: ret { i64, i32 } [[T21]]
756 br i1 %b, label %t, label %f
759 %t4 = tail call { i64, i32 } %x()
760 %t5 = extractvalue { i64, i32 } %t4, 0
761 %t6 = extractvalue { i64, i32 } %t4, 1
762 %t7 = and i64 %t5, -4294967296
763 %t8 = and i64 %t5, 4294901760
764 %t9 = and i64 %t5, 65280
765 %t10 = and i64 %t5, 255
769 %t12 = phi i64 [ %t10, %t ], [ 0, %entry ]
770 %t13 = phi i64 [ %t9, %t ], [ 0, %entry ]
771 %t14 = phi i64 [ %t8, %t ], [ 0, %entry ]
772 %t15 = phi i64 [ %t7, %t ], [ 0, %entry ]
773 %t16 = phi i32 [ %t6, %t ], [ 0, %entry ]
774 %t17 = or i64 %t13, %t12
775 %t18 = or i64 %t17, %t14
776 %t19 = or i64 %t18, %t15
777 %t20 = insertvalue { i64, i32 } poison, i64 %t19, 0
778 %t21 = insertvalue { i64, i32 } %t20, i32 %t16, 1
779 ret { i64, i32 } %t21