[mlir][NFC] Avoid using braced initializer lists to call a constructor. (#123714)
[llvm-project.git] / llvm / test / Transforms / InstCombine / binop-phi-operands.ll
blob9e049837b0352b08502270a841ef918da8ed19d4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i32)
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(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
13 ; CHECK:       if:
14 ; CHECK-NEXT:    br label [[THEN]]
15 ; CHECK:       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]]
21 entry:
22   br i1 %b, label %if, label %then
24 if:
25   br label %then
27 then:
28   %p0 = phi i32 [ 42, %if ], [ %x, %entry ]
29   %p1 = phi i32 [ 17, %if ], [ %y, %entry ]
30   %r = add i32 %p0, %p1
31   ret i32 %r
34 define i32 @add_const_incoming0_nonspeculative(i1 %b, i32 %x, i32 %y) {
35 ; CHECK-LABEL: @add_const_incoming0_nonspeculative(
36 ; CHECK-NEXT:  entry:
37 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
38 ; CHECK:       if:
39 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
40 ; CHECK-NEXT:    br label [[THEN]]
41 ; CHECK:       then:
42 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ 59, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
43 ; CHECK-NEXT:    ret i32 [[R]]
45 entry:
46   br i1 %b, label %if, label %then
48 if:
49   br label %then
51 then:
52   %p0 = phi i32 [ 42, %entry ], [ %x, %if ]
53   %p1 = phi i32 [ 17, %entry ], [ %y, %if ]
54   %r = add i32 %p0, %p1
55   ret i32 %r
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(
62 ; CHECK-NEXT:  entry:
63 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
64 ; CHECK:       if:
65 ; CHECK-NEXT:    br label [[THEN]]
66 ; CHECK:       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]]
72 entry:
73   br i1 %b, label %if, label %then
75 if:
76   br label %then
78 then:
79   %p0 = phi i32 [ 42, %if ], [ %x, %entry ]
80   %p1 = phi i32 [ 17, %if ], [ %y, %entry ]
81   %r = sub i32 %p1, %p0
82   ret i32 %r
85 define i32 @sub_const_incoming1(i1 %b, i32 %x, i32 %y) {
86 ; CHECK-LABEL: @sub_const_incoming1(
87 ; CHECK-NEXT:  entry:
88 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
89 ; CHECK:       if:
90 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
91 ; CHECK-NEXT:    br label [[THEN]]
92 ; CHECK:       then:
93 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[TMP0]], [[IF]] ], [ 25, [[ENTRY:%.*]] ]
94 ; CHECK-NEXT:    ret i32 [[R]]
96 entry:
97   br i1 %b, label %if, label %then
99 if:
100   br label %then
102 then:
103   %p0 = phi i32 [ %x, %if ], [ 42, %entry ]
104   %p1 = phi i32 [ %y, %if ], [ 17, %entry ]
105   %r = sub i32 %p0, %p1
106   ret i32 %r
109 define i8 @mul_const_incoming1(i1 %b, i8 %x, i8 %y) {
110 ; CHECK-LABEL: @mul_const_incoming1(
111 ; CHECK-NEXT:  entry:
112 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
113 ; CHECK:       if:
114 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]
115 ; CHECK-NEXT:    br label [[THEN]]
116 ; CHECK:       then:
117 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ -54, [[ENTRY:%.*]] ]
118 ; CHECK-NEXT:    ret i8 [[R]]
120 entry:
121   br i1 %b, label %if, label %then
124   br label %then
126 then:
127   %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
128   %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
129   %r = mul i8 %p0, %p1
130   ret i8 %r
133 define i8 @and_const_incoming1(i1 %b, i8 %x, i8 %y) {
134 ; CHECK-LABEL: @and_const_incoming1(
135 ; CHECK-NEXT:  entry:
136 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
137 ; CHECK:       if:
138 ; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
139 ; CHECK-NEXT:    br label [[THEN]]
140 ; CHECK:       then:
141 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 0, [[ENTRY:%.*]] ]
142 ; CHECK-NEXT:    ret i8 [[R]]
144 entry:
145   br i1 %b, label %if, label %then
148   br label %then
150 then:
151   %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
152   %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
153   %r = and i8 %p0, %p1
154   ret i8 %r
157 define i8 @xor_const_incoming1(i1 %b, i8 %x, i8 %y) {
158 ; CHECK-LABEL: @xor_const_incoming1(
159 ; CHECK-NEXT:  entry:
160 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
161 ; CHECK:       if:
162 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
163 ; CHECK-NEXT:    br label [[THEN]]
164 ; CHECK:       then:
165 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 59, [[ENTRY:%.*]] ]
166 ; CHECK-NEXT:    ret i8 [[R]]
168 entry:
169   br i1 %b, label %if, label %then
172   br label %then
174 then:
175   %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
176   %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
177   %r = xor i8 %p0, %p1
178   ret i8 %r
181 define i64 @or_const_incoming1(i1 %b, i64 %x, i64 %y) {
182 ; CHECK-LABEL: @or_const_incoming1(
183 ; CHECK-NEXT:  entry:
184 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
185 ; CHECK:       if:
186 ; CHECK-NEXT:    [[TMP0:%.*]] = or i64 [[X:%.*]], [[Y:%.*]]
187 ; CHECK-NEXT:    br label [[THEN]]
188 ; CHECK:       then:
189 ; CHECK-NEXT:    [[R:%.*]] = phi i64 [ [[TMP0]], [[IF]] ], [ 19, [[ENTRY:%.*]] ]
190 ; CHECK-NEXT:    ret i64 [[R]]
192 entry:
193   br i1 %b, label %if, label %then
196   br label %then
198 then:
199   %p0 = phi i64 [ %x, %if ], [ 3, %entry ]
200   %p1 = phi i64 [ %y, %if ], [ 16, %entry ]
201   %r = or i64 %p0, %p1
202   ret i64 %r
205 define i64 @or_const_incoming01(i1 %b, i64 %x, i64 %y) {
206 ; CHECK-LABEL: @or_const_incoming01(
207 ; CHECK-NEXT:  entry:
208 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
209 ; CHECK:       if:
210 ; CHECK-NEXT:    [[TMP0:%.*]] = or i64 [[X:%.*]], [[Y:%.*]]
211 ; CHECK-NEXT:    br label [[THEN]]
212 ; CHECK:       then:
213 ; CHECK-NEXT:    [[R:%.*]] = phi i64 [ 19, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
214 ; CHECK-NEXT:    ret i64 [[R]]
216 entry:
217   br i1 %b, label %if, label %then
220   br label %then
222 then:
223   %p0 = phi i64 [ 3, %entry ], [ %x, %if]
224   %p1 = phi i64 [ %y, %if ], [ 16, %entry ]
225   %r = or i64 %p0, %p1
226   ret i64 %r
229 define i64 @or_const_incoming10(i1 %b, i64 %x, i64 %y) {
230 ; CHECK-LABEL: @or_const_incoming10(
231 ; CHECK-NEXT:  entry:
232 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
233 ; CHECK:       if:
234 ; CHECK-NEXT:    [[TMP0:%.*]] = or i64 [[Y:%.*]], [[X:%.*]]
235 ; CHECK-NEXT:    br label [[THEN]]
236 ; CHECK:       then:
237 ; CHECK-NEXT:    [[R:%.*]] = phi i64 [ [[TMP0]], [[IF]] ], [ 19, [[ENTRY:%.*]] ]
238 ; CHECK-NEXT:    ret i64 [[R]]
240 entry:
241   br i1 %b, label %if, label %then
244   br label %then
246 then:
247   %p0 = phi i64 [ %y, %if ], [ 16, %entry ]
248   %p1 = phi i64 [ 3, %entry ], [ %x, %if]
249   %r = or i64 %p0, %p1
250   ret i64 %r
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(
257 ; CHECK-NEXT:  entry:
258 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
259 ; CHECK:       if:
260 ; CHECK-NEXT:    br label [[THEN]]
261 ; CHECK:       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]]
267 entry:
268   br i1 %b, label %if, label %then
271   br label %then
273 then:
274   %p0 = phi i8 [ 42, %if ], [ %x, %entry ]
275   %p1 = phi i8 [ 3, %if ], [ %y, %entry ]
276   %r = ashr i8 %p0, %p1
277   ret i8 %r
280 define i8 @ashr_const_incoming0(i1 %b, i8 %x, i8 %y) {
281 ; CHECK-LABEL: @ashr_const_incoming0(
282 ; CHECK-NEXT:  entry:
283 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
284 ; CHECK:       if:
285 ; CHECK-NEXT:    [[TMP0:%.*]] = ashr i8 [[X:%.*]], [[Y:%.*]]
286 ; CHECK-NEXT:    br label [[THEN]]
287 ; CHECK:       then:
288 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]
289 ; CHECK-NEXT:    ret i8 [[R]]
291 entry:
292   br i1 %b, label %if, label %then
295   br label %then
297 then:
298   %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
299   %p1 = phi i8 [ 3, %entry ], [ %y, %if ]
300   %r = ashr i8 %p0, %p1
301   ret i8 %r
304 define i8 @lshr_const_incoming1(i1 %b, i8 %x, i8 %y) {
305 ; CHECK-LABEL: @lshr_const_incoming1(
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
308 ; CHECK:       if:
309 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 [[X:%.*]], [[Y:%.*]]
310 ; CHECK-NEXT:    br label [[THEN]]
311 ; CHECK:       then:
312 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 5, [[ENTRY:%.*]] ]
313 ; CHECK-NEXT:    ret i8 [[R]]
315 entry:
316   br i1 %b, label %if, label %then
319   br label %then
321 then:
322   %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
323   %p1 = phi i8 [ %y, %if ], [ 3, %entry ]
324   %r = lshr i8 %p0, %p1
325   ret i8 %r
328 define i8 @shl_const_incoming1(i1 %b, i8 %x, i8 %y) {
329 ; CHECK-LABEL: @shl_const_incoming1(
330 ; CHECK-NEXT:  entry:
331 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
332 ; CHECK:       if:
333 ; CHECK-NEXT:    [[TMP0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
334 ; CHECK-NEXT:    br label [[THEN]]
335 ; CHECK:       then:
336 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 80, [[ENTRY:%.*]] ]
337 ; CHECK-NEXT:    ret i8 [[R]]
339 entry:
340   br i1 %b, label %if, label %then
343   br label %then
345 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
349   ret i8 %r
352 define i8 @sdiv_not_safe_to_speculate(i1 %b, i8 %x, i8 %y) {
353 ; CHECK-LABEL: @sdiv_not_safe_to_speculate(
354 ; CHECK-NEXT:  entry:
355 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
356 ; CHECK:       if:
357 ; CHECK-NEXT:    br label [[THEN]]
358 ; CHECK:       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]]
364 entry:
365   br i1 %b, label %if, label %then
368   br label %then
370 then:
371   %p0 = phi i8 [ 42, %if ], [ %x, %entry ]
372   %p1 = phi i8 [ 3, %if ], [ %y, %entry ]
373   %r = sdiv exact i8 %p0, %p1
374   ret i8 %r
377 define i8 @sdiv_const_incoming1(i1 %b, i8 %x, i8 %y) {
378 ; CHECK-LABEL: @sdiv_const_incoming1(
379 ; CHECK-NEXT:  entry:
380 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
381 ; CHECK:       if:
382 ; CHECK-NEXT:    [[TMP0:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
383 ; CHECK-NEXT:    br label [[THEN]]
384 ; CHECK:       then:
385 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ -2, [[ENTRY:%.*]] ]
386 ; CHECK-NEXT:    ret i8 [[R]]
388 entry:
389   br i1 %b, label %if, label %then
392   br label %then
394 then:
395   %p0 = phi i8 [ %x, %if ], [ -42, %entry ]
396   %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
397   %r = sdiv i8 %p0, %p1
398   ret i8 %r
401 define i8 @udiv_const_incoming1(i1 %b, i8 %x, i8 %y) {
402 ; CHECK-LABEL: @udiv_const_incoming1(
403 ; CHECK-NEXT:  entry:
404 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
405 ; CHECK:       if:
406 ; CHECK-NEXT:    [[TMP0:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
407 ; CHECK-NEXT:    br label [[THEN]]
408 ; CHECK:       then:
409 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 12, [[ENTRY:%.*]] ]
410 ; CHECK-NEXT:    ret i8 [[R]]
412 entry:
413   br i1 %b, label %if, label %then
416   br label %then
418 then:
419   %p0 = phi i8 [ %x, %if ], [ -42, %entry ]
420   %p1 = phi i8 [ %y, %if ], [ 17, %entry ]
421   %r = udiv i8 %p0, %p1
422   ret i8 %r
425 define i8 @srem_const_incoming1(i1 %b, i8 %x, i8 %y) {
426 ; CHECK-LABEL: @srem_const_incoming1(
427 ; CHECK-NEXT:  entry:
428 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
429 ; CHECK:       if:
430 ; CHECK-NEXT:    [[TMP0:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]]
431 ; CHECK-NEXT:    br label [[THEN]]
432 ; CHECK:       then:
433 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 8, [[ENTRY:%.*]] ]
434 ; CHECK-NEXT:    ret i8 [[R]]
436 entry:
437   br i1 %b, label %if, label %then
440   br label %then
442 then:
443   %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
444   %p1 = phi i8 [ %y, %if ], [ -17, %entry ]
445   %r = srem i8 %p0, %p1
446   ret i8 %r
449 define i8 @urem_const_incoming1(i1 %b, i8 %x, i8 %y) {
450 ; CHECK-LABEL: @urem_const_incoming1(
451 ; CHECK-NEXT:  entry:
452 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
453 ; CHECK:       if:
454 ; CHECK-NEXT:    [[TMP0:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]]
455 ; CHECK-NEXT:    br label [[THEN]]
456 ; CHECK:       then:
457 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 42, [[ENTRY:%.*]] ]
458 ; CHECK-NEXT:    ret i8 [[R]]
460 entry:
461   br i1 %b, label %if, label %then
464   br label %then
466 then:
467   %p0 = phi i8 [ %x, %if ], [ 42, %entry ]
468   %p1 = phi i8 [ %y, %if ], [ -17, %entry ]
469   %r = urem i8 %p0, %p1
470   ret i8 %r
473 define float @fmul_const_incoming1(i1 %b, float %x, float %y) {
474 ; CHECK-LABEL: @fmul_const_incoming1(
475 ; CHECK-NEXT:  entry:
476 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
477 ; CHECK:       if:
478 ; CHECK-NEXT:    [[TMP0:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
479 ; CHECK-NEXT:    br label [[THEN]]
480 ; CHECK:       then:
481 ; CHECK-NEXT:    [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 7.140000e+02, [[ENTRY:%.*]] ]
482 ; CHECK-NEXT:    ret float [[R]]
484 entry:
485   br i1 %b, label %if, label %then
488   br label %then
490 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
494   ret float %r
497 define float @fadd_const_incoming1(i1 %b, float %x, float %y) {
498 ; CHECK-LABEL: @fadd_const_incoming1(
499 ; CHECK-NEXT:  entry:
500 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
501 ; CHECK:       if:
502 ; CHECK-NEXT:    [[TMP0:%.*]] = fadd fast float [[X:%.*]], [[Y:%.*]]
503 ; CHECK-NEXT:    br label [[THEN]]
504 ; CHECK:       then:
505 ; CHECK-NEXT:    [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 5.900000e+01, [[ENTRY:%.*]] ]
506 ; CHECK-NEXT:    ret float [[R]]
508 entry:
509   br i1 %b, label %if, label %then
512   br label %then
514 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
518   ret float %r
521 define float @fsub_const_incoming1(i1 %b, float %x, float %y) {
522 ; CHECK-LABEL: @fsub_const_incoming1(
523 ; CHECK-NEXT:  entry:
524 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
525 ; CHECK:       if:
526 ; CHECK-NEXT:    [[TMP0:%.*]] = fsub nnan ninf float [[X:%.*]], [[Y:%.*]]
527 ; CHECK-NEXT:    br label [[THEN]]
528 ; CHECK:       then:
529 ; CHECK-NEXT:    [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 2.500000e+01, [[ENTRY:%.*]] ]
530 ; CHECK-NEXT:    ret float [[R]]
532 entry:
533   br i1 %b, label %if, label %then
536   br label %then
538 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
542   ret float %r
545 define float @frem_const_incoming1(i1 %b, float %x, float %y) {
546 ; CHECK-LABEL: @frem_const_incoming1(
547 ; CHECK-NEXT:  entry:
548 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
549 ; CHECK:       if:
550 ; CHECK-NEXT:    [[TMP0:%.*]] = frem nsz float [[X:%.*]], [[Y:%.*]]
551 ; CHECK-NEXT:    br label [[THEN]]
552 ; CHECK:       then:
553 ; CHECK-NEXT:    [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 8.000000e+00, [[ENTRY:%.*]] ]
554 ; CHECK-NEXT:    ret float [[R]]
556 entry:
557   br i1 %b, label %if, label %then
560   br label %then
562 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
566   ret float %r
569 define i32 @add_const_incoming0_use1(i1 %b, i32 %x, i32 %y) {
570 ; CHECK-LABEL: @add_const_incoming0_use1(
571 ; CHECK-NEXT:  entry:
572 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
573 ; CHECK:       if:
574 ; CHECK-NEXT:    br label [[THEN]]
575 ; CHECK:       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]]
582 entry:
583   br i1 %b, label %if, label %then
586   br label %then
588 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
593   ret i32 %r
596 define i32 @add_const_incoming0_use2(i1 %b, i32 %x, i32 %y) {
597 ; CHECK-LABEL: @add_const_incoming0_use2(
598 ; CHECK-NEXT:  entry:
599 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
600 ; CHECK:       if:
601 ; CHECK-NEXT:    br label [[THEN]]
602 ; CHECK:       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]]
609 entry:
610   br i1 %b, label %if, label %then
613   br label %then
615 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
620   ret i32 %r
623 define i64 @or_notconst_incoming(i1 %b, i64 %x, i64 %y) {
624 ; CHECK-LABEL: @or_notconst_incoming(
625 ; CHECK-NEXT:  entry:
626 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
627 ; CHECK:       if:
628 ; CHECK-NEXT:    br label [[THEN]]
629 ; CHECK:       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]]
635 entry:
636   br i1 %b, label %if, label %then
639   br label %then
641 then:
642   %p0 = phi i64 [ 42, %if ], [ %x, %entry ]
643   %p1 = phi i64 [ %y, %if ], [ 43, %entry ]
644   %r = or i64 %p0, %p1
645   ret i64 %r
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(
653 ; CHECK-NEXT:  entry:
654 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
655 ; CHECK:       if:
656 ; CHECK-NEXT:    br label [[THEN]]
657 ; CHECK:       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]]
664 entry:
665   br i1 %b, label %if, label %then
668   br label %then
670 then:
671   %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
672   %p1 = phi i8 [ 17, %entry ], [ %y, %if ]
673   call void @sideeffect()
674   %r = mul i8 %p0, %p1
675   ret i8 %r
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(
682 ; CHECK-NEXT:  entry:
683 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
684 ; CHECK:       if:
685 ; CHECK-NEXT:    br label [[THEN]]
686 ; CHECK:       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]]
693 entry:
694   br i1 %b, label %if, label %then
697   br label %then
699 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
704   ret i8 %r
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(
711 ; CHECK-NEXT:  entry:
712 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]
713 ; CHECK:       if:
714 ; CHECK-NEXT:    br label [[THEN]]
715 ; CHECK:       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:%.*]]
719 ; CHECK:       end:
720 ; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[P0]], [[P1]]
721 ; CHECK-NEXT:    ret i8 [[R]]
723 entry:
724   br i1 %b, label %if, label %then
727   br label %then
729 then:
730   %p0 = phi i8 [ 42, %entry ], [ %x, %if ]
731   %p1 = phi i8 [ 17, %entry ], [ %y, %if ]
732   br label %end
734 end:
735   %r = udiv i8 %p0, %p1
736   ret i8 %r
739 define { i64, i32 } @ParseRetVal(i1 %b, ptr %x) {
740 ; CHECK-LABEL: @ParseRetVal(
741 ; CHECK-NEXT:  entry:
742 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[T:%.*]], label [[F:%.*]]
743 ; CHECK:       t:
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]]
748 ; CHECK:       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]]
755 entry:
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
766   br label %f
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