[ConstraintElim] Add support for decomposing gep nuw (#118639)
[llvm-project.git] / llvm / test / Transforms / AggressiveInstCombine / funnel.ll
blobb1bc5f44598174f71b338689da49bba107abb333
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
4 define i32 @fshl(i32 %a, i32 %b, i32 %c) {
5 ; CHECK-LABEL: @fshl(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
8 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
9 ; CHECK:       fshbb:
10 ; CHECK-NEXT:    br label [[END]]
11 ; CHECK:       end:
12 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[B:%.*]]
13 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]])
14 ; CHECK-NEXT:    ret i32 [[TMP1]]
16 entry:
17   %cmp = icmp eq i32 %c, 0
18   br i1 %cmp, label %end, label %fshbb
20 fshbb:
21   %sub = sub i32 32, %c
22   %shr = lshr i32 %b, %sub
23   %shl = shl i32 %a, %c
24   %or = or i32 %shr, %shl
25   br label %end
27 end:
28   %cond = phi i32 [ %or, %fshbb ], [ %a, %entry ]
29   ret i32 %cond
32 define i32 @fshl_commute_phi(i32 %a, i32 %b, i32 %c) {
33 ; CHECK-LABEL: @fshl_commute_phi(
34 ; CHECK-NEXT:  entry:
35 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
36 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
37 ; CHECK:       fshbb:
38 ; CHECK-NEXT:    br label [[END]]
39 ; CHECK:       end:
40 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[B:%.*]]
41 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]])
42 ; CHECK-NEXT:    ret i32 [[TMP1]]
44 entry:
45   %cmp = icmp eq i32 %c, 0
46   br i1 %cmp, label %end, label %fshbb
48 fshbb:
49   %sub = sub i32 32, %c
50   %shr = lshr i32 %b, %sub
51   %shl = shl i32 %a, %c
52   %or = or i32 %shr, %shl
53   br label %end
55 end:
56   %cond = phi i32 [ %a, %entry ], [ %or, %fshbb ]
57   ret i32 %cond
60 define i32 @fshl_commute_or(i32 %a, i32 %b, i32 %c) {
61 ; CHECK-LABEL: @fshl_commute_or(
62 ; CHECK-NEXT:  entry:
63 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
64 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
65 ; CHECK:       fshbb:
66 ; CHECK-NEXT:    br label [[END]]
67 ; CHECK:       end:
68 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[B:%.*]]
69 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]])
70 ; CHECK-NEXT:    ret i32 [[TMP1]]
72 entry:
73   %cmp = icmp eq i32 %c, 0
74   br i1 %cmp, label %end, label %fshbb
76 fshbb:
77   %sub = sub i32 32, %c
78   %shr = lshr i32 %b, %sub
79   %shl = shl i32 %a, %c
80   %or = or i32 %shl, %shr
81   br label %end
83 end:
84   %cond = phi i32 [ %a, %entry ], [ %or, %fshbb ]
85   ret i32 %cond
88 ; Verify that the intrinsic is inserted into a valid position.
90 define i32 @fshl_insert_valid_location(i32 %a, i32 %b, i32 %c) {
91 ; CHECK-LABEL: @fshl_insert_valid_location(
92 ; CHECK-NEXT:  entry:
93 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
94 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
95 ; CHECK:       fshbb:
96 ; CHECK-NEXT:    br label [[END]]
97 ; CHECK:       end:
98 ; CHECK-NEXT:    [[OTHER:%.*]] = phi i32 [ 1, [[FSHBB]] ], [ 2, [[ENTRY:%.*]] ]
99 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[B:%.*]]
100 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 [[TMP0]], i32 [[C]])
101 ; CHECK-NEXT:    [[RES:%.*]] = or i32 [[TMP1]], [[OTHER]]
102 ; CHECK-NEXT:    ret i32 [[RES]]
104 entry:
105   %cmp = icmp eq i32 %c, 0
106   br i1 %cmp, label %end, label %fshbb
108 fshbb:
109   %sub = sub i32 32, %c
110   %shr = lshr i32 %b, %sub
111   %shl = shl i32 %a, %c
112   %or = or i32 %shr, %shl
113   br label %end
115 end:
116   %cond = phi i32 [ %or, %fshbb ], [ %a, %entry ]
117   %other = phi i32 [ 1, %fshbb ], [ 2, %entry ]
118   %res = or i32 %cond, %other
119   ret i32 %res
122 define i32 @fshr(i32 %a, i32 %b, i32 %c) {
123 ; CHECK-LABEL: @fshr(
124 ; CHECK-NEXT:  entry:
125 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
126 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
127 ; CHECK:       fshbb:
128 ; CHECK-NEXT:    br label [[END]]
129 ; CHECK:       end:
130 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[A:%.*]]
131 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP0]], i32 [[B:%.*]], i32 [[C]])
132 ; CHECK-NEXT:    ret i32 [[TMP1]]
134 entry:
135   %cmp = icmp eq i32 %c, 0
136   br i1 %cmp, label %end, label %fshbb
138 fshbb:
139   %sub = sub i32 32, %c
140   %shl = shl i32 %a, %sub
141   %shr = lshr i32 %b, %c
142   %or = or i32 %shr, %shl
143   br label %end
145 end:
146   %cond = phi i32 [ %or, %fshbb ], [ %b, %entry ]
147   ret i32 %cond
150 define i32 @fshr_commute_phi(i32 %a, i32 %b, i32 %c) {
151 ; CHECK-LABEL: @fshr_commute_phi(
152 ; CHECK-NEXT:  entry:
153 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
154 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
155 ; CHECK:       fshbb:
156 ; CHECK-NEXT:    br label [[END]]
157 ; CHECK:       end:
158 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[A:%.*]]
159 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP0]], i32 [[B:%.*]], i32 [[C]])
160 ; CHECK-NEXT:    ret i32 [[TMP1]]
162 entry:
163   %cmp = icmp eq i32 %c, 0
164   br i1 %cmp, label %end, label %fshbb
166 fshbb:
167   %sub = sub i32 32, %c
168   %shl = shl i32 %a, %sub
169   %shr = lshr i32 %b, %c
170   %or = or i32 %shr, %shl
171   br label %end
173 end:
174   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
175   ret i32 %cond
178 define i32 @fshr_commute_or(i32 %a, i32 %b, i32 %c) {
179 ; CHECK-LABEL: @fshr_commute_or(
180 ; CHECK-NEXT:  entry:
181 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
182 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
183 ; CHECK:       fshbb:
184 ; CHECK-NEXT:    br label [[END]]
185 ; CHECK:       end:
186 ; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 [[A:%.*]]
187 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP0]], i32 [[B:%.*]], i32 [[C]])
188 ; CHECK-NEXT:    ret i32 [[TMP1]]
190 entry:
191   %cmp = icmp eq i32 %c, 0
192   br i1 %cmp, label %end, label %fshbb
194 fshbb:
195   %sub = sub i32 32, %c
196   %shl = shl i32 %a, %sub
197   %shr = lshr i32 %b, %c
198   %or = or i32 %shl, %shr
199   br label %end
201 end:
202   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
203   ret i32 %cond
206 ; Negative test - non-power-of-2 might require urem expansion in the backend.
208 define i12 @could_be_fshr_weird_type(i12 %a, i12 %b, i12 %c) {
209 ; CHECK-LABEL: @could_be_fshr_weird_type(
210 ; CHECK-NEXT:  entry:
211 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i12 [[C:%.*]], 0
212 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
213 ; CHECK:       fshbb:
214 ; CHECK-NEXT:    [[SUB:%.*]] = sub i12 12, [[C]]
215 ; CHECK-NEXT:    [[SHL:%.*]] = shl i12 [[A:%.*]], [[SUB]]
216 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i12 [[B:%.*]], [[C]]
217 ; CHECK-NEXT:    [[OR:%.*]] = or i12 [[SHL]], [[SHR]]
218 ; CHECK-NEXT:    br label [[END]]
219 ; CHECK:       end:
220 ; CHECK-NEXT:    [[COND:%.*]] = phi i12 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ]
221 ; CHECK-NEXT:    ret i12 [[COND]]
223 entry:
224   %cmp = icmp eq i12 %c, 0
225   br i1 %cmp, label %end, label %fshbb
227 fshbb:
228   %sub = sub i12 12, %c
229   %shl = shl i12 %a, %sub
230   %shr = lshr i12 %b, %c
231   %or = or i12 %shl, %shr
232   br label %end
234 end:
235   %cond = phi i12 [ %b, %entry ], [ %or, %fshbb ]
236   ret i12 %cond
239 ; Negative test - wrong phi ops.
241 define i32 @not_fshr_1(i32 %a, i32 %b, i32 %c) {
242 ; CHECK-LABEL: @not_fshr_1(
243 ; CHECK-NEXT:  entry:
244 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
245 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
246 ; CHECK:       fshbb:
247 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 32, [[C]]
248 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
249 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]]
250 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR]]
251 ; CHECK-NEXT:    br label [[END]]
252 ; CHECK:       end:
253 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[C]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ]
254 ; CHECK-NEXT:    ret i32 [[COND]]
256 entry:
257   %cmp = icmp eq i32 %c, 0
258   br i1 %cmp, label %end, label %fshbb
260 fshbb:
261   %sub = sub i32 32, %c
262   %shl = shl i32 %a, %sub
263   %shr = lshr i32 %b, %c
264   %or = or i32 %shl, %shr
265   br label %end
267 end:
268   %cond = phi i32 [ %c, %entry ], [ %or, %fshbb ]
269   ret i32 %cond
272 ; Negative test - too many phi ops.
274 define i32 @not_fshr_2(i32 %a, i32 %b, i32 %c, i32 %d) {
275 ; CHECK-LABEL: @not_fshr_2(
276 ; CHECK-NEXT:  entry:
277 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
278 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
279 ; CHECK:       fshbb:
280 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 32, [[C]]
281 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
282 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]]
283 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR]]
284 ; CHECK-NEXT:    [[CMP42:%.*]] = icmp ugt i32 [[OR]], 42
285 ; CHECK-NEXT:    br i1 [[CMP42]], label [[END]], label [[BOGUS:%.*]]
286 ; CHECK:       bogus:
287 ; CHECK-NEXT:    br label [[END]]
288 ; CHECK:       end:
289 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ], [ [[D:%.*]], [[BOGUS]] ]
290 ; CHECK-NEXT:    ret i32 [[COND]]
292 entry:
293   %cmp = icmp eq i32 %c, 0
294   br i1 %cmp, label %end, label %fshbb
296 fshbb:
297   %sub = sub i32 32, %c
298   %shl = shl i32 %a, %sub
299   %shr = lshr i32 %b, %c
300   %or = or i32 %shl, %shr
301   %cmp42 = icmp ugt i32 %or, 42
302   br i1 %cmp42, label %end, label %bogus
304 bogus:
305   br label %end
307 end:
308   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ], [ %d, %bogus ]
309   ret i32 %cond
312 ; Negative test - wrong cmp (but this should match?).
314 define i32 @not_fshr_3(i32 %a, i32 %b, i32 %c) {
315 ; CHECK-LABEL: @not_fshr_3(
316 ; CHECK-NEXT:  entry:
317 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[C:%.*]], 0
318 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
319 ; CHECK:       fshbb:
320 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 32, [[C]]
321 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
322 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]]
323 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR]]
324 ; CHECK-NEXT:    br label [[END]]
325 ; CHECK:       end:
326 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ]
327 ; CHECK-NEXT:    ret i32 [[COND]]
329 entry:
330   %cmp = icmp sle i32 %c, 0
331   br i1 %cmp, label %end, label %fshbb
333 fshbb:
334   %sub = sub i32 32, %c
335   %shl = shl i32 %a, %sub
336   %shr = lshr i32 %b, %c
337   %or = or i32 %shl, %shr
338   br label %end
340 end:
341   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
342   ret i32 %cond
345 ; Negative test - wrong shift.
347 define i32 @not_fshr_4(i32 %a, i32 %b, i32 %c) {
348 ; CHECK-LABEL: @not_fshr_4(
349 ; CHECK-NEXT:  entry:
350 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
351 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
352 ; CHECK:       fshbb:
353 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 32, [[C]]
354 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
355 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[B:%.*]], [[C]]
356 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR]]
357 ; CHECK-NEXT:    br label [[END]]
358 ; CHECK:       end:
359 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ]
360 ; CHECK-NEXT:    ret i32 [[COND]]
362 entry:
363   %cmp = icmp eq i32 %c, 0
364   br i1 %cmp, label %end, label %fshbb
366 fshbb:
367   %sub = sub i32 32, %c
368   %shl = shl i32 %a, %sub
369   %shr = ashr i32 %b, %c
370   %or = or i32 %shl, %shr
371   br label %end
373 end:
374   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
375   ret i32 %cond
378 ; Negative test - wrong shift for rotate (but can be folded to a generic funnel shift).
380 define i32 @not_fshr_5(i32 %a, i32 %b, i32 %c) {
381 ; CHECK-LABEL: @not_fshr_5(
382 ; CHECK-NEXT:  entry:
383 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
384 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
385 ; CHECK:       fshbb:
386 ; CHECK-NEXT:    br label [[END]]
387 ; CHECK:       end:
388 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.fshr.i32(i32 [[C]], i32 [[B:%.*]], i32 [[C]])
389 ; CHECK-NEXT:    ret i32 [[TMP0]]
391 entry:
392   %cmp = icmp eq i32 %c, 0
393   br i1 %cmp, label %end, label %fshbb
395 fshbb:
396   %sub = sub i32 32, %c
397   %shl = shl i32 %c, %sub
398   %shr = lshr i32 %b, %c
399   %or = or i32 %shl, %shr
400   br label %end
402 end:
403   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
404   ret i32 %cond
407 ; Negative test - wrong sub.
409 define i32 @not_fshr_6(i32 %a, i32 %b, i32 %c) {
410 ; CHECK-LABEL: @not_fshr_6(
411 ; CHECK-NEXT:  entry:
412 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
413 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
414 ; CHECK:       fshbb:
415 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 8, [[C]]
416 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
417 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]]
418 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR]]
419 ; CHECK-NEXT:    br label [[END]]
420 ; CHECK:       end:
421 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ]
422 ; CHECK-NEXT:    ret i32 [[COND]]
424 entry:
425   %cmp = icmp eq i32 %c, 0
426   br i1 %cmp, label %end, label %fshbb
428 fshbb:
429   %sub = sub i32 8, %c
430   %shl = shl i32 %a, %sub
431   %shr = lshr i32 %b, %c
432   %or = or i32 %shl, %shr
433   br label %end
435 end:
436   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
437   ret i32 %cond
440 ; Negative test - extra use. Technically, we could transform this
441 ; because it doesn't increase the instruction count, but we're
442 ; being cautious not to cause a potential perf pessimization for
443 ; targets that do not have a fshate instruction.
445 define i32 @could_be_fshr(i32 %a, i32 %b, i32 %c, ptr %p) {
446 ; CHECK-LABEL: @could_be_fshr(
447 ; CHECK-NEXT:  entry:
448 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
449 ; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[FSHBB:%.*]]
450 ; CHECK:       fshbb:
451 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 32, [[C]]
452 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], [[SUB]]
453 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[B:%.*]], [[C]]
454 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR]]
455 ; CHECK-NEXT:    store i32 [[OR]], ptr [[P:%.*]], align 4
456 ; CHECK-NEXT:    br label [[END]]
457 ; CHECK:       end:
458 ; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[OR]], [[FSHBB]] ]
459 ; CHECK-NEXT:    ret i32 [[COND]]
461 entry:
462   %cmp = icmp eq i32 %c, 0
463   br i1 %cmp, label %end, label %fshbb
465 fshbb:
466   %sub = sub i32 32, %c
467   %shl = shl i32 %a, %sub
468   %shr = lshr i32 %b, %c
469   %or = or i32 %shl, %shr
470   store i32 %or, ptr %p
471   br label %end
473 end:
474   %cond = phi i32 [ %b, %entry ], [ %or, %fshbb ]
475   ret i32 %cond
478 ; PR48068 - Ensure we don't fold a funnel shift that depends on a shift value that
479 ; can't be hoisted out of a basic block.
480 @a = global i32 0, align 4
481 declare i32 @i(...)
482 declare i32 @f(...)
484 define i32 @PR48068() {
485 ; CHECK-LABEL: @PR48068(
486 ; CHECK-NEXT:  entry:
487 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @i()
488 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
489 ; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
490 ; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
491 ; CHECK:       if.then:
492 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CALL]], [[TMP0]]
493 ; CHECK-NEXT:    [[CALL_I:%.*]] = call i32 @f()
494 ; CHECK-NEXT:    [[SUB_I:%.*]] = sub nsw i32 32, [[TMP0]]
495 ; CHECK-NEXT:    [[SHR_I:%.*]] = lshr i32 [[CALL_I]], [[SUB_I]]
496 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHL]], [[SHR_I]]
497 ; CHECK-NEXT:    br label [[IF_END]]
498 ; CHECK:       if.end:
499 ; CHECK-NEXT:    [[H_0:%.*]] = phi i32 [ [[OR]], [[IF_THEN]] ], [ [[CALL]], [[ENTRY:%.*]] ]
500 ; CHECK-NEXT:    ret i32 [[H_0]]
502 entry:
503   %call = call i32 @i()
504   %0 = load i32, ptr @a, align 4
505   %tobool.not = icmp eq i32 %0, 0
506   br i1 %tobool.not, label %if.end, label %if.then
508 if.then:                                          ; preds = %entry
509   %shl = shl i32 %call, %0
510   %call.i = call i32 @f()
511   %sub.i = sub nsw i32 32, %0
512   %shr.i = lshr i32 %call.i, %sub.i
513   %or = or i32 %shl, %shr.i
514   br label %if.end
516 if.end:                                           ; preds = %if.then, %entry
517   %h.0 = phi i32 [ %or, %if.then ], [ %call, %entry ]
518   ret i32 %h.0