xref: /llvm-project/llvm/test/Transforms/InstCombine/commutative-operation-over-phis.ll (revision 8674a023bcacb677ce48b8831e2ae35b5aa2d8ef)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3
4declare void @dummy()
5
6declare i32 @llvm.smax.i32(i32 %a, i32 %b)
7declare i32 @llvm.smin.i32(i32 %a, i32 %b)
8declare i32 @llvm.umax.i32(i32 %a, i32 %b)
9declare i32 @llvm.umin.i32(i32 %a, i32 %b)
10declare float @llvm.maxnum.f32(float %a, float %b)
11declare float @llvm.minnum.f32(float %a, float %b)
12declare float @llvm.maximum.f32(float %a, float %b)
13declare float @llvm.minimum.f32(float %a, float %b)
14declare float @llvm.pow.f32(float %a, float %b)
15
16define i8 @fold_phi_mul(i1 %c, i8 %a, i8 %b)  {
17; CHECK-LABEL: define i8 @fold_phi_mul(
18; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
19; CHECK-NEXT:  entry:
20; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
21; CHECK:       then:
22; CHECK-NEXT:    call void @dummy()
23; CHECK-NEXT:    br label [[END]]
24; CHECK:       end:
25; CHECK-NEXT:    [[RET:%.*]] = mul i8 [[A]], [[B]]
26; CHECK-NEXT:    ret i8 [[RET]]
27;
28entry:
29  br i1 %c, label %then, label %end
30then:
31  call void @dummy()
32  br label %end
33end:
34  %phi1 = phi i8 [%a, %entry], [%b, %then]
35  %phi2 = phi i8 [%b, %entry], [%a, %then]
36  %ret = mul i8 %phi1, %phi2
37  ret i8 %ret
38}
39
40define i8 @fold_phi_mul_three(i1 %c, i1 %d, i8 %a, i8 %b)  {
41; CHECK-LABEL: define i8 @fold_phi_mul_three(
42; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
43; CHECK-NEXT:  entry:
44; CHECK-NEXT:    br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]]
45; CHECK:       then1:
46; CHECK-NEXT:    call void @dummy()
47; CHECK-NEXT:    br i1 [[D]], label [[THEN2:%.*]], label [[END]]
48; CHECK:       then2:
49; CHECK-NEXT:    call void @dummy()
50; CHECK-NEXT:    br label [[END]]
51; CHECK:       end:
52; CHECK-NEXT:    [[RET:%.*]] = mul i8 [[A]], [[B]]
53; CHECK-NEXT:    ret i8 [[RET]]
54;
55entry:
56  br i1 %c, label %then1, label %end
57then1:
58  call void @dummy()
59  br i1 %d, label %then2, label %end
60then2:
61  call void @dummy()
62  br label %end
63end:
64  %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2]
65  %phi2 = phi i8 [%b, %entry], [%a, %then1], [%b, %then2]
66  %ret = mul i8 %phi1, %phi2
67  ret i8 %ret
68}
69
70define i8 @fold_phi_mul_three_notopt(i1 %c, i1 %d, i8 %a, i8 %b)  {
71; CHECK-LABEL: define i8 @fold_phi_mul_three_notopt(
72; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
73; CHECK-NEXT:  entry:
74; CHECK-NEXT:    br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]]
75; CHECK:       then1:
76; CHECK-NEXT:    call void @dummy()
77; CHECK-NEXT:    br i1 [[D]], label [[THEN2:%.*]], label [[END]]
78; CHECK:       then2:
79; CHECK-NEXT:    call void @dummy()
80; CHECK-NEXT:    br label [[END]]
81; CHECK:       end:
82; CHECK-NEXT:    [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN1]] ], [ [[A]], [[THEN2]] ]
83; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN1]] ], [ [[A]], [[THEN2]] ]
84; CHECK-NEXT:    [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]]
85; CHECK-NEXT:    ret i8 [[RET]]
86;
87entry:
88  br i1 %c, label %then1, label %end
89then1:
90  call void @dummy()
91  br i1 %d, label %then2, label %end
92then2:
93  call void @dummy()
94  br label %end
95end:
96  %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2]
97  %phi2 = phi i8 [%b, %entry], [%a, %then1], [%a, %then2]
98  %ret = mul i8 %phi1, %phi2
99  ret i8 %ret
100}
101
102define i8 @fold_phi_mul_nsw_nuw(i1 %c, i8 %a, i8 %b)  {
103; CHECK-LABEL: define i8 @fold_phi_mul_nsw_nuw(
104; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
105; CHECK-NEXT:  entry:
106; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
107; CHECK:       then:
108; CHECK-NEXT:    call void @dummy()
109; CHECK-NEXT:    br label [[END]]
110; CHECK:       end:
111; CHECK-NEXT:    [[RET:%.*]] = mul nuw nsw i8 [[A]], [[B]]
112; CHECK-NEXT:    ret i8 [[RET]]
113;
114entry:
115  br i1 %c, label %then, label %end
116then:
117  call void @dummy()
118  br label %end
119end:
120  %phi1 = phi i8 [%a, %entry], [%b, %then]
121  %phi2 = phi i8 [%b, %entry], [%a, %then]
122  %ret = mul nsw nuw i8 %phi1, %phi2
123  ret i8 %ret
124}
125
126define <2 x i8> @fold_phi_mul_fix_vec(i1 %c, <2 x i8> %a, <2 x i8> %b)  {
127; CHECK-LABEL: define <2 x i8> @fold_phi_mul_fix_vec(
128; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {
129; CHECK-NEXT:  entry:
130; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
131; CHECK:       then:
132; CHECK-NEXT:    call void @dummy()
133; CHECK-NEXT:    br label [[END]]
134; CHECK:       end:
135; CHECK-NEXT:    [[RET:%.*]] = mul <2 x i8> [[A]], [[B]]
136; CHECK-NEXT:    ret <2 x i8> [[RET]]
137;
138entry:
139  br i1 %c, label %then, label %end
140then:
141  call void @dummy()
142  br label %end
143end:
144  %phi1 = phi <2 x i8> [%a, %entry], [%b, %then]
145  %phi2 = phi <2 x i8> [%b, %entry], [%a, %then]
146  %ret = mul <2 x i8> %phi1, %phi2
147  ret <2 x i8> %ret
148}
149
150define <vscale x 2 x i8> @fold_phi_mul_scale_vec(i1 %c, <vscale x 2 x i8> %a, <vscale x 2 x i8> %b)  {
151; CHECK-LABEL: define <vscale x 2 x i8> @fold_phi_mul_scale_vec(
152; CHECK-SAME: i1 [[C:%.*]], <vscale x 2 x i8> [[A:%.*]], <vscale x 2 x i8> [[B:%.*]]) {
153; CHECK-NEXT:  entry:
154; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
155; CHECK:       then:
156; CHECK-NEXT:    call void @dummy()
157; CHECK-NEXT:    br label [[END]]
158; CHECK:       end:
159; CHECK-NEXT:    [[RET:%.*]] = mul <vscale x 2 x i8> [[A]], [[B]]
160; CHECK-NEXT:    ret <vscale x 2 x i8> [[RET]]
161;
162entry:
163  br i1 %c, label %then, label %end
164then:
165  call void @dummy()
166  br label %end
167end:
168  %phi1 = phi <vscale x 2 x i8> [%a, %entry], [%b, %then]
169  %phi2 = phi <vscale x 2 x i8> [%b, %entry], [%a, %then]
170  %ret = mul <vscale x 2 x i8> %phi1, %phi2
171  ret <vscale x 2 x i8> %ret
172}
173
174define i8 @fold_phi_mul_commute(i1 %c, i8 %a, i8 %b)  {
175; CHECK-LABEL: define i8 @fold_phi_mul_commute(
176; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
177; CHECK-NEXT:  entry:
178; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
179; CHECK:       then:
180; CHECK-NEXT:    call void @dummy()
181; CHECK-NEXT:    br label [[END]]
182; CHECK:       end:
183; CHECK-NEXT:    [[RET:%.*]] = mul i8 [[A]], [[B]]
184; CHECK-NEXT:    ret i8 [[RET]]
185;
186entry:
187  br i1 %c, label %then, label %end
188then:
189  call void @dummy()
190  br label %end
191end:
192  %phi1 = phi i8 [%a, %entry], [%b, %then]
193  %phi2 = phi i8 [%a, %then], [%b, %entry]
194  %ret = mul i8 %phi1, %phi2
195  ret i8 %ret
196}
197
198
199define i8 @fold_phi_mul_notopt(i1 %c, i8 %a, i8 %b, i8 %d)  {
200; CHECK-LABEL: define i8 @fold_phi_mul_notopt(
201; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]], i8 [[D:%.*]]) {
202; CHECK-NEXT:  entry:
203; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
204; CHECK:       then:
205; CHECK-NEXT:    call void @dummy()
206; CHECK-NEXT:    br label [[END]]
207; CHECK:       end:
208; CHECK-NEXT:    [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ]
209; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[D]], [[THEN]] ]
210; CHECK-NEXT:    [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]]
211; CHECK-NEXT:    ret i8 [[RET]]
212;
213entry:
214  br i1 %c, label %then, label %end
215then:
216  call void @dummy()
217  br label %end
218end:
219  %phi1 = phi i8 [%a, %entry], [%b, %then]
220  %phi2 = phi i8 [%b, %entry], [%d, %then]
221  %ret = mul i8 %phi1, %phi2
222  ret i8 %ret
223}
224
225
226define i8 @fold_phi_sub(i1 %c, i8 %a, i8 %b)  {
227; CHECK-LABEL: define i8 @fold_phi_sub(
228; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
229; CHECK-NEXT:  entry:
230; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
231; CHECK:       then:
232; CHECK-NEXT:    call void @dummy()
233; CHECK-NEXT:    br label [[END]]
234; CHECK:       end:
235; CHECK-NEXT:    [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ]
236; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ]
237; CHECK-NEXT:    [[RET:%.*]] = sub i8 [[PHI1]], [[PHI2]]
238; CHECK-NEXT:    ret i8 [[RET]]
239;
240entry:
241  br i1 %c, label %then, label %end
242then:
243  call void @dummy()
244  br label %end
245end:
246  %phi1 = phi i8 [%a, %entry], [%b, %then]
247  %phi2 = phi i8 [%b, %entry], [%a, %then]
248  %ret = sub i8 %phi1, %phi2
249  ret i8 %ret
250}
251
252
253define i8 @fold_phi_add(i1 %c, i8 %a, i8 %b)  {
254; CHECK-LABEL: define i8 @fold_phi_add(
255; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
256; CHECK-NEXT:  entry:
257; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
258; CHECK:       then:
259; CHECK-NEXT:    call void @dummy()
260; CHECK-NEXT:    br label [[END]]
261; CHECK:       end:
262; CHECK-NEXT:    [[RET:%.*]] = add i8 [[A]], [[B]]
263; CHECK-NEXT:    ret i8 [[RET]]
264;
265entry:
266  br i1 %c, label %then, label %end
267then:
268  call void @dummy()
269  br label %end
270end:
271  %phi1 = phi i8 [%a, %entry], [%b, %then]
272  %phi2 = phi i8 [%b, %entry], [%a, %then]
273  %ret = add i8 %phi1, %phi2
274  ret i8 %ret
275}
276
277define i8 @fold_phi_and(i1 %c, i8 %a, i8 %b)  {
278; CHECK-LABEL: define i8 @fold_phi_and(
279; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
280; CHECK-NEXT:  entry:
281; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
282; CHECK:       then:
283; CHECK-NEXT:    call void @dummy()
284; CHECK-NEXT:    br label [[END]]
285; CHECK:       end:
286; CHECK-NEXT:    [[RET:%.*]] = and i8 [[A]], [[B]]
287; CHECK-NEXT:    ret i8 [[RET]]
288;
289entry:
290  br i1 %c, label %then, label %end
291then:
292  call void @dummy()
293  br label %end
294end:
295  %phi1 = phi i8 [%a, %entry], [%b, %then]
296  %phi2 = phi i8 [%b, %entry], [%a, %then]
297  %ret = and i8 %phi1, %phi2
298  ret i8 %ret
299}
300
301define i8 @fold_phi_or(i1 %c, i8 %a, i8 %b)  {
302; CHECK-LABEL: define i8 @fold_phi_or(
303; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
304; CHECK-NEXT:  entry:
305; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
306; CHECK:       then:
307; CHECK-NEXT:    call void @dummy()
308; CHECK-NEXT:    br label [[END]]
309; CHECK:       end:
310; CHECK-NEXT:    [[RET:%.*]] = or i8 [[A]], [[B]]
311; CHECK-NEXT:    ret i8 [[RET]]
312;
313entry:
314  br i1 %c, label %then, label %end
315then:
316  call void @dummy()
317  br label %end
318end:
319  %phi1 = phi i8 [%a, %entry], [%b, %then]
320  %phi2 = phi i8 [%b, %entry], [%a, %then]
321  %ret = or i8 %phi1, %phi2
322  ret i8 %ret
323}
324
325
326define i8 @fold_phi_xor(i1 %c, i8 %a, i8 %b)  {
327; CHECK-LABEL: define i8 @fold_phi_xor(
328; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
329; CHECK-NEXT:  entry:
330; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
331; CHECK:       then:
332; CHECK-NEXT:    call void @dummy()
333; CHECK-NEXT:    br label [[END]]
334; CHECK:       end:
335; CHECK-NEXT:    [[RET:%.*]] = xor i8 [[A]], [[B]]
336; CHECK-NEXT:    ret i8 [[RET]]
337;
338entry:
339  br i1 %c, label %then, label %end
340then:
341  call void @dummy()
342  br label %end
343end:
344  %phi1 = phi i8 [%a, %entry], [%b, %then]
345  %phi2 = phi i8 [%b, %entry], [%a, %then]
346  %ret = xor i8 %phi1, %phi2
347  ret i8 %ret
348}
349
350
351define float @fold_phi_fadd(i1 %c, float %a, float %b)  {
352; CHECK-LABEL: define float @fold_phi_fadd(
353; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
354; CHECK-NEXT:  entry:
355; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
356; CHECK:       then:
357; CHECK-NEXT:    call void @dummy()
358; CHECK-NEXT:    br label [[END]]
359; CHECK:       end:
360; CHECK-NEXT:    [[RET:%.*]] = fadd float [[A]], [[B]]
361; CHECK-NEXT:    ret float [[RET]]
362;
363entry:
364  br i1 %c, label %then, label %end
365then:
366  call void @dummy()
367  br label %end
368end:
369  %phi1 = phi float [%a, %entry], [%b, %then]
370  %phi2 = phi float [%b, %entry], [%a, %then]
371  %ret = fadd float %phi1, %phi2
372  ret float %ret
373}
374
375define float @fold_phi_fadd_nnan(i1 %c, float %a, float %b)  {
376; CHECK-LABEL: define float @fold_phi_fadd_nnan(
377; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
378; CHECK-NEXT:  entry:
379; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
380; CHECK:       then:
381; CHECK-NEXT:    call void @dummy()
382; CHECK-NEXT:    br label [[END]]
383; CHECK:       end:
384; CHECK-NEXT:    [[RET:%.*]] = fadd nnan float [[A]], [[B]]
385; CHECK-NEXT:    ret float [[RET]]
386;
387entry:
388  br i1 %c, label %then, label %end
389then:
390  call void @dummy()
391  br label %end
392end:
393  %phi1 = phi float [%a, %entry], [%b, %then]
394  %phi2 = phi float [%b, %entry], [%a, %then]
395  %ret = fadd nnan float %phi1, %phi2
396  ret float %ret
397}
398
399
400define float @fold_phi_fmul(i1 %c, float %a, float %b)  {
401; CHECK-LABEL: define float @fold_phi_fmul(
402; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
403; CHECK-NEXT:  entry:
404; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
405; CHECK:       then:
406; CHECK-NEXT:    call void @dummy()
407; CHECK-NEXT:    br label [[END]]
408; CHECK:       end:
409; CHECK-NEXT:    [[RET:%.*]] = fmul float [[A]], [[B]]
410; CHECK-NEXT:    ret float [[RET]]
411;
412entry:
413  br i1 %c, label %then, label %end
414then:
415  call void @dummy()
416  br label %end
417end:
418  %phi1 = phi float [%a, %entry], [%b, %then]
419  %phi2 = phi float [%b, %entry], [%a, %then]
420  %ret = fmul float %phi1, %phi2
421  ret float %ret
422}
423
424
425define i32 @fold_phi_smax(i1 %c, i32 %a, i32 %b)  {
426; CHECK-LABEL: define i32 @fold_phi_smax(
427; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
428; CHECK-NEXT:  entry:
429; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
430; CHECK:       then:
431; CHECK-NEXT:    call void @dummy()
432; CHECK-NEXT:    br label [[END]]
433; CHECK:       end:
434; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 [[B]])
435; CHECK-NEXT:    ret i32 [[RET]]
436;
437entry:
438  br i1 %c, label %then, label %end
439then:
440  call void @dummy()
441  br label %end
442end:
443  %phi1 = phi i32 [%a, %entry], [%b, %then]
444  %phi2 = phi i32 [%b, %entry], [%a, %then]
445  %ret = call i32 @llvm.smax.i32(i32  %phi1, i32 %phi2)
446  ret i32 %ret
447}
448
449
450define i32 @fold_phi_smin(i1 %c, i32 %a, i32 %b)  {
451; CHECK-LABEL: define i32 @fold_phi_smin(
452; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
453; CHECK-NEXT:  entry:
454; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
455; CHECK:       then:
456; CHECK-NEXT:    call void @dummy()
457; CHECK-NEXT:    br label [[END]]
458; CHECK:       end:
459; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 [[B]])
460; CHECK-NEXT:    ret i32 [[RET]]
461;
462entry:
463  br i1 %c, label %then, label %end
464then:
465  call void @dummy()
466  br label %end
467end:
468  %phi1 = phi i32 [%a, %entry], [%b, %then]
469  %phi2 = phi i32 [%b, %entry], [%a, %then]
470  %ret = call i32 @llvm.smin.i32(i32  %phi1, i32 %phi2)
471  ret i32 %ret
472}
473
474
475define i32 @fold_phi_umax(i1 %c, i32 %a, i32 %b)  {
476; CHECK-LABEL: define i32 @fold_phi_umax(
477; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
478; CHECK-NEXT:  entry:
479; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
480; CHECK:       then:
481; CHECK-NEXT:    call void @dummy()
482; CHECK-NEXT:    br label [[END]]
483; CHECK:       end:
484; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 [[B]])
485; CHECK-NEXT:    ret i32 [[RET]]
486;
487entry:
488  br i1 %c, label %then, label %end
489then:
490  call void @dummy()
491  br label %end
492end:
493  %phi1 = phi i32 [%a, %entry], [%b, %then]
494  %phi2 = phi i32 [%b, %entry], [%a, %then]
495  %ret = call i32 @llvm.umax.i32(i32  %phi1, i32 %phi2)
496  ret i32 %ret
497}
498
499define i32 @fold_phi_umin(i1 %c, i32 %a, i32 %b)  {
500; CHECK-LABEL: define i32 @fold_phi_umin(
501; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
502; CHECK-NEXT:  entry:
503; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
504; CHECK:       then:
505; CHECK-NEXT:    call void @dummy()
506; CHECK-NEXT:    br label [[END]]
507; CHECK:       end:
508; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 [[B]])
509; CHECK-NEXT:    ret i32 [[RET]]
510;
511entry:
512  br i1 %c, label %then, label %end
513then:
514  call void @dummy()
515  br label %end
516end:
517  %phi1 = phi i32 [%a, %entry], [%b, %then]
518  %phi2 = phi i32 [%b, %entry], [%a, %then]
519  %ret = call i32 @llvm.umin.i32(i32  %phi1, i32 %phi2)
520  ret i32 %ret
521}
522
523
524define float @fold_phi_maxnum(i1 %c, float %a, float %b)  {
525; CHECK-LABEL: define float @fold_phi_maxnum(
526; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
527; CHECK-NEXT:  entry:
528; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
529; CHECK:       then:
530; CHECK-NEXT:    call void @dummy()
531; CHECK-NEXT:    br label [[END]]
532; CHECK:       end:
533; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[B]])
534; CHECK-NEXT:    ret float [[RET]]
535;
536entry:
537  br i1 %c, label %then, label %end
538then:
539  call void @dummy()
540  br label %end
541end:
542  %phi1 = phi float [%a, %entry], [%b, %then]
543  %phi2 = phi float [%b, %entry], [%a, %then]
544  %ret = call float @llvm.maxnum.f32(float  %phi1, float %phi2)
545  ret float %ret
546}
547
548define float @fold_phi_pow(i1 %c, float %a, float %b)  {
549; CHECK-LABEL: define float @fold_phi_pow(
550; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
551; CHECK-NEXT:  entry:
552; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
553; CHECK:       then:
554; CHECK-NEXT:    call void @dummy()
555; CHECK-NEXT:    br label [[END]]
556; CHECK:       end:
557; CHECK-NEXT:    [[PHI1:%.*]] = phi float [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ]
558; CHECK-NEXT:    [[PHI2:%.*]] = phi float [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ]
559; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.pow.f32(float [[PHI1]], float [[PHI2]])
560; CHECK-NEXT:    ret float [[RET]]
561;
562entry:
563  br i1 %c, label %then, label %end
564then:
565  call void @dummy()
566  br label %end
567end:
568  %phi1 = phi float [%a, %entry], [%b, %then]
569  %phi2 = phi float [%b, %entry], [%a, %then]
570  %ret = call float @llvm.pow.f32(float  %phi1, float %phi2)
571  ret float %ret
572}
573
574define float @fold_phi_minnum(i1 %c, float %a, float %b)  {
575; CHECK-LABEL: define float @fold_phi_minnum(
576; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
577; CHECK-NEXT:  entry:
578; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
579; CHECK:       then:
580; CHECK-NEXT:    call void @dummy()
581; CHECK-NEXT:    br label [[END]]
582; CHECK:       end:
583; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[B]])
584; CHECK-NEXT:    ret float [[RET]]
585;
586entry:
587  br i1 %c, label %then, label %end
588then:
589  call void @dummy()
590  br label %end
591end:
592  %phi1 = phi float [%a, %entry], [%b, %then]
593  %phi2 = phi float [%b, %entry], [%a, %then]
594  %ret = call float @llvm.minnum.f32(float  %phi1, float %phi2)
595  ret float %ret
596}
597
598define float @fold_phi_maximum(i1 %c, float %a, float %b)  {
599; CHECK-LABEL: define float @fold_phi_maximum(
600; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
601; CHECK-NEXT:  entry:
602; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
603; CHECK:       then:
604; CHECK-NEXT:    call void @dummy()
605; CHECK-NEXT:    br label [[END]]
606; CHECK:       end:
607; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[B]])
608; CHECK-NEXT:    ret float [[RET]]
609;
610entry:
611  br i1 %c, label %then, label %end
612then:
613  call void @dummy()
614  br label %end
615end:
616  %phi1 = phi float [%a, %entry], [%b, %then]
617  %phi2 = phi float [%b, %entry], [%a, %then]
618  %ret = call float @llvm.maximum.f32(float  %phi1, float %phi2)
619  ret float %ret
620}
621
622define float @fold_phi_minimum(i1 %c, float %a, float %b)  {
623; CHECK-LABEL: define float @fold_phi_minimum(
624; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {
625; CHECK-NEXT:  entry:
626; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]]
627; CHECK:       then:
628; CHECK-NEXT:    call void @dummy()
629; CHECK-NEXT:    br label [[END]]
630; CHECK:       end:
631; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[B]])
632; CHECK-NEXT:    ret float [[RET]]
633;
634entry:
635  br i1 %c, label %then, label %end
636then:
637  call void @dummy()
638  br label %end
639end:
640  %phi1 = phi float [%a, %entry], [%b, %then]
641  %phi2 = phi float [%b, %entry], [%a, %then]
642  %ret = call float @llvm.minimum.f32(float  %phi1, float %phi2)
643  ret float %ret
644}
645
646