[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / GVNHoist / hoist.ll
blob6249111d600ef044630c1b126ca836c4dbe2dd0d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=gvn-hoist -S < %s | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
6 @GlobalVar = internal global float 1.000000e+00
8 ; Check that all scalar expressions are hoisted.
9 define float @scalarsHoisting(float %d, float %min, float %max, float %a) {
10 ; CHECK-LABEL: @scalarsHoisting(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
13 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
14 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[MIN:%.*]], [[A:%.*]]
15 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
16 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[MAX:%.*]], [[A]]
17 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
18 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
19 ; CHECK:       if.then:
20 ; CHECK-NEXT:    br label [[IF_END:%.*]]
21 ; CHECK:       if.else:
22 ; CHECK-NEXT:    br label [[IF_END]]
23 ; CHECK:       if.end:
24 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]
25 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL2]], [[IF_ELSE]] ]
26 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
27 ; CHECK-NEXT:    ret float [[ADD]]
29 entry:
30   %div = fdiv float 1.000000e+00, %d
31   %cmp = fcmp oge float %div, 0.000000e+00
32   br i1 %cmp, label %if.then, label %if.else
34 if.then:                                          ; preds = %entry
35   %sub = fsub float %min, %a
36   %mul = fmul float %sub, %div
37   %sub1 = fsub float %max, %a
38   %mul2 = fmul float %sub1, %div
39   br label %if.end
41 if.else:                                          ; preds = %entry
42   %sub3 = fsub float %max, %a
43   %mul4 = fmul float %sub3, %div
44   %sub5 = fsub float %min, %a
45   %mul6 = fmul float %sub5, %div
46   br label %if.end
48 if.end:                                           ; preds = %if.else, %if.then
49   %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]
50   %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]
51   %add = fadd float %tmax.0, %tmin.0
52   ret float %add
55 ; Check that all loads and scalars depending on the loads are hoisted.
56 ; Check that getelementptr computation gets hoisted before the load.
57 define float @readsAndScalarsHoisting(float %d, ptr %min, ptr %max, ptr %a) {
58 ; CHECK-LABEL: @readsAndScalarsHoisting(
59 ; CHECK-NEXT:  entry:
60 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
61 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
62 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr float, ptr [[MIN:%.*]], i32 1
63 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4
64 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[A:%.*]], align 4
65 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX:%.*]], align 4
66 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP1]], [[TMP2]]
67 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
68 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP3]], [[TMP2]]
69 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
70 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
71 ; CHECK:       if.then:
72 ; CHECK-NEXT:    [[A:%.*]] = getelementptr float, ptr [[MIN]], i32 1
73 ; CHECK-NEXT:    br label [[IF_END:%.*]]
74 ; CHECK:       if.else:
75 ; CHECK-NEXT:    [[B:%.*]] = getelementptr float, ptr [[MIN]], i32 1
76 ; CHECK-NEXT:    br label [[IF_END]]
77 ; CHECK:       if.end:
78 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]
79 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL2]], [[IF_ELSE]] ]
80 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
81 ; CHECK-NEXT:    ret float [[ADD]]
83 entry:
84   %div = fdiv float 1.000000e+00, %d
85   %cmp = fcmp oge float %div, 0.000000e+00
86   br i1 %cmp, label %if.then, label %if.else
88 if.then:                                          ; preds = %entry
89   %A = getelementptr float, ptr %min, i32 1
90   %0 = load float, ptr %A, align 4
91   %1 = load float, ptr %a, align 4
92   %sub = fsub float %0, %1
93   %mul = fmul float %sub, %div
94   %2 = load float, ptr %max, align 4
95   %sub1 = fsub float %2, %1
96   %mul2 = fmul float %sub1, %div
97   br label %if.end
99 if.else:                                          ; preds = %entry
100   %3 = load float, ptr %max, align 4
101   %4 = load float, ptr %a, align 4
102   %sub3 = fsub float %3, %4
103   %mul4 = fmul float %sub3, %div
104   %B = getelementptr float, ptr %min, i32 1
105   %5 = load float, ptr %B, align 4
106   %sub5 = fsub float %5, %4
107   %mul6 = fmul float %sub5, %div
108   br label %if.end
110 if.end:                                           ; preds = %if.else, %if.then
111   %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]
112   %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]
113   %add = fadd float %tmax.0, %tmin.0
114   ret float %add
117 ; Check that we do not hoist loads after a store: the first two loads will be
118 ; hoisted, and then the third load will not be hoisted.
119 define float @readsAndWrites(float %d, ptr %min, ptr %max, ptr %a) {
120 ; CHECK-LABEL: @readsAndWrites(
121 ; CHECK-NEXT:  entry:
122 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
123 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
124 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
125 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
126 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]
127 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
128 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
129 ; CHECK:       if.then:
130 ; CHECK-NEXT:    store float [[TMP0]], ptr @GlobalVar, align 4
131 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
132 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]
133 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
134 ; CHECK-NEXT:    br label [[IF_END:%.*]]
135 ; CHECK:       if.else:
136 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4
137 ; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP1]]
138 ; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]
139 ; CHECK-NEXT:    br label [[IF_END]]
140 ; CHECK:       if.end:
141 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]
142 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL4]], [[IF_ELSE]] ]
143 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
144 ; CHECK-NEXT:    ret float [[ADD]]
146 entry:
147   %div = fdiv float 1.000000e+00, %d
148   %cmp = fcmp oge float %div, 0.000000e+00
149   br i1 %cmp, label %if.then, label %if.else
151 if.then:                                          ; preds = %entry
152   %0 = load float, ptr %min, align 4
153   %1 = load float, ptr %a, align 4
154   store float %0, ptr @GlobalVar
155   %sub = fsub float %0, %1
156   %mul = fmul float %sub, %div
157   %2 = load float, ptr %max, align 4
158   %sub1 = fsub float %2, %1
159   %mul2 = fmul float %sub1, %div
160   br label %if.end
162 if.else:                                          ; preds = %entry
163   %3 = load float, ptr %max, align 4
164   %4 = load float, ptr %a, align 4
165   %sub3 = fsub float %3, %4
166   %mul4 = fmul float %sub3, %div
167   %5 = load float, ptr %min, align 4
168   %sub5 = fsub float %5, %4
169   %mul6 = fmul float %sub5, %div
170   br label %if.end
172 if.end:                                           ; preds = %if.else, %if.then
173   %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]
174   %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]
175   %add = fadd float %tmax.0, %tmin.0
176   ret float %add
179 ; Check that we do hoist loads when the store is above the insertion point.
180 define float @readsAndWriteAboveInsertPt(float %d, ptr %min, ptr %max, ptr %a) {
181 ; CHECK-LABEL: @readsAndWriteAboveInsertPt(
182 ; CHECK-NEXT:  entry:
183 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
184 ; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4
185 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
186 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
187 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
188 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
189 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]
190 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
191 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]
192 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
193 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
194 ; CHECK:       if.then:
195 ; CHECK-NEXT:    br label [[IF_END:%.*]]
196 ; CHECK:       if.else:
197 ; CHECK-NEXT:    br label [[IF_END]]
198 ; CHECK:       if.end:
199 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL]], [[IF_ELSE]] ]
200 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL2]], [[IF_ELSE]] ]
201 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
202 ; CHECK-NEXT:    ret float [[ADD]]
204 entry:
205   %div = fdiv float 1.000000e+00, %d
206   store float 0.000000e+00, ptr @GlobalVar
207   %cmp = fcmp oge float %div, 0.000000e+00
208   br i1 %cmp, label %if.then, label %if.else
210 if.then:                                          ; preds = %entry
211   %0 = load float, ptr %min, align 4
212   %1 = load float, ptr %a, align 4
213   %sub = fsub float %0, %1
214   %mul = fmul float %sub, %div
215   %2 = load float, ptr %max, align 4
216   %sub1 = fsub float %2, %1
217   %mul2 = fmul float %sub1, %div
218   br label %if.end
220 if.else:                                          ; preds = %entry
221   %3 = load float, ptr %max, align 4
222   %4 = load float, ptr %a, align 4
223   %sub3 = fsub float %3, %4
224   %mul4 = fmul float %sub3, %div
225   %5 = load float, ptr %min, align 4
226   %sub5 = fsub float %5, %4
227   %mul6 = fmul float %sub5, %div
228   br label %if.end
230 if.end:                                           ; preds = %if.else, %if.then
231   %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]
232   %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]
233   %add = fadd float %tmax.0, %tmin.0
234   ret float %add
237 ; Check that dependent expressions are hoisted.
238 define float @dependentScalarsHoisting(float %a, float %b, i1 %c) {
239 ; CHECK-LABEL: @dependentScalarsHoisting(
240 ; CHECK-NEXT:  entry:
241 ; CHECK-NEXT:    [[D:%.*]] = fsub float [[B:%.*]], [[A:%.*]]
242 ; CHECK-NEXT:    [[E:%.*]] = fadd float [[D]], [[A]]
243 ; CHECK-NEXT:    [[F:%.*]] = fdiv float [[E]], [[A]]
244 ; CHECK-NEXT:    [[G:%.*]] = fmul float [[F]], [[A]]
245 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
246 ; CHECK:       if.then:
247 ; CHECK-NEXT:    br label [[IF_END:%.*]]
248 ; CHECK:       if.else:
249 ; CHECK-NEXT:    br label [[IF_END]]
250 ; CHECK:       if.end:
251 ; CHECK-NEXT:    [[R:%.*]] = phi float [ [[G]], [[IF_THEN]] ], [ [[G]], [[IF_ELSE]] ]
252 ; CHECK-NEXT:    ret float [[R]]
254 entry:
255   br i1 %c, label %if.then, label %if.else
257 if.then:
258   %d = fsub float %b, %a
259   %e = fadd float %d, %a
260   %f = fdiv float %e, %a
261   %g = fmul float %f, %a
262   br label %if.end
264 if.else:
265   %h = fsub float %b, %a
266   %i = fadd float %h, %a
267   %j = fdiv float %i, %a
268   %k = fmul float %j, %a
269   br label %if.end
271 if.end:
272   %r = phi float [ %g, %if.then ], [ %k, %if.else ]
273   ret float %r
276 ; Check that all independent expressions are hoisted.
277 define float @independentScalarsHoisting(float %a, float %b, i1 %c) {
278 ; CHECK-LABEL: @independentScalarsHoisting(
279 ; CHECK-NEXT:  entry:
280 ; CHECK-NEXT:    [[D:%.*]] = fadd float [[B:%.*]], [[A:%.*]]
281 ; CHECK-NEXT:    [[E:%.*]] = fsub float [[B]], [[A]]
282 ; CHECK-NEXT:    [[F:%.*]] = fdiv float [[B]], [[A]]
283 ; CHECK-NEXT:    [[G:%.*]] = fmul float [[B]], [[A]]
284 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
285 ; CHECK:       if.then:
286 ; CHECK-NEXT:    br label [[IF_END:%.*]]
287 ; CHECK:       if.else:
288 ; CHECK-NEXT:    br label [[IF_END]]
289 ; CHECK:       if.end:
290 ; CHECK-NEXT:    [[P:%.*]] = phi float [ [[D]], [[IF_THEN]] ], [ [[D]], [[IF_ELSE]] ]
291 ; CHECK-NEXT:    [[Q:%.*]] = phi float [ [[E]], [[IF_THEN]] ], [ [[E]], [[IF_ELSE]] ]
292 ; CHECK-NEXT:    [[R:%.*]] = phi float [ [[F]], [[IF_THEN]] ], [ [[F]], [[IF_ELSE]] ]
293 ; CHECK-NEXT:    [[S:%.*]] = phi float [ [[G]], [[IF_THEN]] ], [ [[G]], [[IF_ELSE]] ]
294 ; CHECK-NEXT:    [[T:%.*]] = fadd float [[P]], [[Q]]
295 ; CHECK-NEXT:    [[U:%.*]] = fadd float [[R]], [[S]]
296 ; CHECK-NEXT:    [[V:%.*]] = fadd float [[T]], [[U]]
297 ; CHECK-NEXT:    ret float [[V]]
299 entry:
300   br i1 %c, label %if.then, label %if.else
302 if.then:
303   %d = fadd float %b, %a
304   %e = fsub float %b, %a
305   %f = fdiv float %b, %a
306   %g = fmul float %b, %a
307   br label %if.end
309 if.else:
310   %i = fadd float %b, %a
311   %h = fsub float %b, %a
312   %j = fdiv float %b, %a
313   %k = fmul float %b, %a
314   br label %if.end
316 if.end:
317   %p = phi float [ %d, %if.then ], [ %i, %if.else ]
318   %q = phi float [ %e, %if.then ], [ %h, %if.else ]
319   %r = phi float [ %f, %if.then ], [ %j, %if.else ]
320   %s = phi float [ %g, %if.then ], [ %k, %if.else ]
321   %t = fadd float %p, %q
322   %u = fadd float %r, %s
323   %v = fadd float %t, %u
324   ret float %v
327 ; Check that we hoist load and scalar expressions in triangles.
328 define float @triangleHoisting(float %d, ptr %min, ptr %max, ptr %a) {
329 ; CHECK-LABEL: @triangleHoisting(
330 ; CHECK-NEXT:  entry:
331 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
332 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
333 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
334 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
335 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
336 ; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP0]], [[TMP1]]
337 ; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]
338 ; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP2]], [[TMP1]]
339 ; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]
340 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
341 ; CHECK:       if.then:
342 ; CHECK-NEXT:    br label [[IF_END]]
343 ; CHECK:       if.end:
344 ; CHECK-NEXT:    [[P1:%.*]] = phi float [ [[MUL4]], [[IF_THEN]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
345 ; CHECK-NEXT:    [[P2:%.*]] = phi float [ [[MUL6]], [[IF_THEN]] ], [ 0.000000e+00, [[ENTRY]] ]
346 ; CHECK-NEXT:    [[X:%.*]] = fadd float [[P1]], [[MUL6]]
347 ; CHECK-NEXT:    [[Y:%.*]] = fadd float [[P2]], [[MUL4]]
348 ; CHECK-NEXT:    [[Z:%.*]] = fadd float [[X]], [[Y]]
349 ; CHECK-NEXT:    ret float [[Z]]
351 entry:
352   %div = fdiv float 1.000000e+00, %d
353   %cmp = fcmp oge float %div, 0.000000e+00
354   br i1 %cmp, label %if.then, label %if.end
356 if.then:                                          ; preds = %entry
357   %0 = load float, ptr %min, align 4
358   %1 = load float, ptr %a, align 4
359   %sub = fsub float %0, %1
360   %mul = fmul float %sub, %div
361   %2 = load float, ptr %max, align 4
362   %sub1 = fsub float %2, %1
363   %mul2 = fmul float %sub1, %div
364   br label %if.end
366 if.end:                                          ; preds = %entry
367   %p1 = phi float [ %mul2, %if.then ], [ 0.000000e+00, %entry ]
368   %p2 = phi float [ %mul, %if.then ], [ 0.000000e+00, %entry ]
369   %3 = load float, ptr %max, align 4
370   %4 = load float, ptr %a, align 4
371   %sub3 = fsub float %3, %4
372   %mul4 = fmul float %sub3, %div
373   %5 = load float, ptr %min, align 4
374   %sub5 = fsub float %5, %4
375   %mul6 = fmul float %sub5, %div
377   %x = fadd float %p1, %mul6
378   %y = fadd float %p2, %mul4
379   %z = fadd float %x, %y
380   ret float %z
383 ; Check that we do not hoist loads past stores within a same basic block.
384 define i32 @noHoistInSingleBBWithStore() {
385 ; CHECK-LABEL: @noHoistInSingleBBWithStore(
386 ; CHECK-NEXT:  entry:
387 ; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
388 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast ptr [[D]] to ptr
389 ; CHECK-NEXT:    [[BF:%.*]] = load i8, ptr [[TMP0]], align 4
390 ; CHECK-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF]], -3
391 ; CHECK-NEXT:    store i8 [[BF_CLEAR]], ptr [[TMP0]], align 4
392 ; CHECK-NEXT:    [[BF1:%.*]] = load i8, ptr [[TMP0]], align 4
393 ; CHECK-NEXT:    [[BF_CLEAR1:%.*]] = and i8 [[BF1]], 1
394 ; CHECK-NEXT:    store i8 [[BF_CLEAR1]], ptr [[TMP0]], align 4
395 ; CHECK-NEXT:    ret i32 0
397 entry:
398   %D = alloca i32, align 4
399   %0 = bitcast ptr %D to ptr
400   %bf = load i8, ptr %0, align 4
401   %bf.clear = and i8 %bf, -3
402   store i8 %bf.clear, ptr %0, align 4
403   %bf1 = load i8, ptr %0, align 4
404   %bf.clear1 = and i8 %bf1, 1
405   store i8 %bf.clear1, ptr %0, align 4
406   ret i32 0
409 ; Check that we do not hoist loads past calls within a same basic block.
410 declare void @foo()
411 define i32 @noHoistInSingleBBWithCall() {
412 ; CHECK-LABEL: @noHoistInSingleBBWithCall(
413 ; CHECK-NEXT:  entry:
414 ; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
415 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast ptr [[D]] to ptr
416 ; CHECK-NEXT:    [[BF:%.*]] = load i8, ptr [[TMP0]], align 4
417 ; CHECK-NEXT:    [[BF_CLEAR:%.*]] = and i8 [[BF]], -3
418 ; CHECK-NEXT:    call void @foo()
419 ; CHECK-NEXT:    [[BF1:%.*]] = load i8, ptr [[TMP0]], align 4
420 ; CHECK-NEXT:    [[BF_CLEAR1:%.*]] = and i8 [[BF1]], 1
421 ; CHECK-NEXT:    ret i32 0
423 entry:
424   %D = alloca i32, align 4
425   %0 = bitcast ptr %D to ptr
426   %bf = load i8, ptr %0, align 4
427   %bf.clear = and i8 %bf, -3
428   call void @foo()
429   %bf1 = load i8, ptr %0, align 4
430   %bf.clear1 = and i8 %bf1, 1
431   ret i32 0
434 ; Check that we do not hoist loads past stores in any branch of a diamond.
435 define float @noHoistInDiamondWithOneStore1(float %d, ptr %min, ptr %max, ptr %a) {
436 ; CHECK-LABEL: @noHoistInDiamondWithOneStore1(
437 ; CHECK-NEXT:  entry:
438 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
439 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
440 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
441 ; CHECK:       if.then:
442 ; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4
443 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
444 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
445 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]
446 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
447 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
448 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]
449 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
450 ; CHECK-NEXT:    br label [[IF_END:%.*]]
451 ; CHECK:       if.else:
452 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4
453 ; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[A]], align 4
454 ; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP4]]
455 ; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]
456 ; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[MIN]], align 4
457 ; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP5]], [[TMP4]]
458 ; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]
459 ; CHECK-NEXT:    br label [[IF_END]]
460 ; CHECK:       if.end:
461 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL6]], [[IF_ELSE]] ]
462 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL4]], [[IF_ELSE]] ]
463 ; CHECK-NEXT:    [[TMP6:%.*]] = load float, ptr [[MAX]], align 4
464 ; CHECK-NEXT:    [[TMP7:%.*]] = load float, ptr [[A]], align 4
465 ; CHECK-NEXT:    [[SUB6:%.*]] = fsub float [[TMP6]], [[TMP7]]
466 ; CHECK-NEXT:    [[MUL7:%.*]] = fmul float [[SUB6]], [[DIV]]
467 ; CHECK-NEXT:    [[TMP8:%.*]] = load float, ptr [[MIN]], align 4
468 ; CHECK-NEXT:    [[SUB8:%.*]] = fsub float [[TMP8]], [[TMP7]]
469 ; CHECK-NEXT:    [[MUL9:%.*]] = fmul float [[SUB8]], [[DIV]]
470 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
471 ; CHECK-NEXT:    ret float [[ADD]]
473 entry:
474   %div = fdiv float 1.000000e+00, %d
475   %cmp = fcmp oge float %div, 0.000000e+00
476   br i1 %cmp, label %if.then, label %if.else
478 if.then:                                          ; preds = %entry
479   store float 0.000000e+00, ptr @GlobalVar
480   %0 = load float, ptr %min, align 4
481   %1 = load float, ptr %a, align 4
482   %sub = fsub float %0, %1
483   %mul = fmul float %sub, %div
484   %2 = load float, ptr %max, align 4
485   %sub1 = fsub float %2, %1
486   %mul2 = fmul float %sub1, %div
487   br label %if.end
489 if.else:                                          ; preds = %entry
490   ; There are no side effects on the if.else branch.
491   %3 = load float, ptr %max, align 4
492   %4 = load float, ptr %a, align 4
493   %sub3 = fsub float %3, %4
494   %mul4 = fmul float %sub3, %div
495   %5 = load float, ptr %min, align 4
496   %sub5 = fsub float %5, %4
497   %mul6 = fmul float %sub5, %div
498   br label %if.end
500 if.end:                                           ; preds = %if.else, %if.then
501   %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]
502   %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]
504   %6 = load float, ptr %max, align 4
505   %7 = load float, ptr %a, align 4
506   %sub6 = fsub float %6, %7
507   %mul7 = fmul float %sub6, %div
508   %8 = load float, ptr %min, align 4
509   %sub8 = fsub float %8, %7
510   %mul9 = fmul float %sub8, %div
512   %add = fadd float %tmax.0, %tmin.0
513   ret float %add
516 ; Check that we do not hoist loads past stores from half diamond.
517 define float @noHoistInHalfDiamondPastStore(float %d, ptr %min, ptr %max, ptr %a) {
518 ; CHECK-LABEL: @noHoistInHalfDiamondPastStore(
519 ; CHECK-NEXT:  entry:
520 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
521 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
522 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
523 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
524 ; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4
525 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
526 ; CHECK:       if.then:
527 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
528 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[A]], align 4
529 ; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP2]], [[TMP3]]
530 ; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]
531 ; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[MIN]], align 4
532 ; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP4]], [[TMP3]]
533 ; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]
534 ; CHECK-NEXT:    br label [[IF_END]]
535 ; CHECK:       if.end:
536 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL4]], [[IF_THEN]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
537 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL6]], [[IF_THEN]] ], [ [[TMP1]], [[ENTRY]] ]
538 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
539 ; CHECK-NEXT:    ret float [[ADD]]
541 entry:
542   %div = fdiv float 1.000000e+00, %d
543   %cmp = fcmp oge float %div, 0.000000e+00
544   %0 = load float, ptr %min, align 4
545   %1 = load float, ptr %a, align 4
547   ; Loads should not be hoisted above this store.
548   store float 0.000000e+00, ptr @GlobalVar
550   br i1 %cmp, label %if.then, label %if.end
552 if.then:
553   ; There are no side effects on the if.then branch.
554   %2 = load float, ptr %max, align 4
555   %3 = load float, ptr %a, align 4
556   %sub3 = fsub float %2, %3
557   %mul4 = fmul float %sub3, %div
558   %4 = load float, ptr %min, align 4
559   %sub5 = fsub float %4, %3
560   %mul6 = fmul float %sub5, %div
561   br label %if.end
563 if.end:
564   %tmax.0 = phi float [ %mul4, %if.then ], [ %0, %entry ]
565   %tmin.0 = phi float [ %mul6, %if.then ], [ %1, %entry ]
567   %add = fadd float %tmax.0, %tmin.0
568   ret float %add
571 ; Check that we do not hoist loads past a store in any branch of a diamond.
572 define float @noHoistInDiamondWithOneStore2(float %d, ptr %min, ptr %max, ptr %a) {
573 ; CHECK-LABEL: @noHoistInDiamondWithOneStore2(
574 ; CHECK-NEXT:  entry:
575 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
576 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
577 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
578 ; CHECK:       if.then:
579 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
580 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
581 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]
582 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
583 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
584 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]
585 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
586 ; CHECK-NEXT:    br label [[IF_END:%.*]]
587 ; CHECK:       if.else:
588 ; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4
589 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4
590 ; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[A]], align 4
591 ; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP4]]
592 ; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]
593 ; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[MIN]], align 4
594 ; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP5]], [[TMP4]]
595 ; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]
596 ; CHECK-NEXT:    br label [[IF_END]]
597 ; CHECK:       if.end:
598 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[IF_THEN]] ], [ [[MUL6]], [[IF_ELSE]] ]
599 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[IF_THEN]] ], [ [[MUL4]], [[IF_ELSE]] ]
600 ; CHECK-NEXT:    [[TMP6:%.*]] = load float, ptr [[MAX]], align 4
601 ; CHECK-NEXT:    [[TMP7:%.*]] = load float, ptr [[A]], align 4
602 ; CHECK-NEXT:    [[SUB6:%.*]] = fsub float [[TMP6]], [[TMP7]]
603 ; CHECK-NEXT:    [[MUL7:%.*]] = fmul float [[SUB6]], [[DIV]]
604 ; CHECK-NEXT:    [[TMP8:%.*]] = load float, ptr [[MIN]], align 4
605 ; CHECK-NEXT:    [[SUB8:%.*]] = fsub float [[TMP8]], [[TMP7]]
606 ; CHECK-NEXT:    [[MUL9:%.*]] = fmul float [[SUB8]], [[DIV]]
607 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
608 ; CHECK-NEXT:    ret float [[ADD]]
610 entry:
611   %div = fdiv float 1.000000e+00, %d
612   %cmp = fcmp oge float %div, 0.000000e+00
613   br i1 %cmp, label %if.then, label %if.else
615 if.then:                                          ; preds = %entry
616   ; There are no side effects on the if.then branch.
617   %0 = load float, ptr %min, align 4
618   %1 = load float, ptr %a, align 4
619   %sub = fsub float %0, %1
620   %mul = fmul float %sub, %div
621   %2 = load float, ptr %max, align 4
622   %sub1 = fsub float %2, %1
623   %mul2 = fmul float %sub1, %div
624   br label %if.end
626 if.else:                                          ; preds = %entry
627   store float 0.000000e+00, ptr @GlobalVar
628   %3 = load float, ptr %max, align 4
629   %4 = load float, ptr %a, align 4
630   %sub3 = fsub float %3, %4
631   %mul4 = fmul float %sub3, %div
632   %5 = load float, ptr %min, align 4
633   %sub5 = fsub float %5, %4
634   %mul6 = fmul float %sub5, %div
635   br label %if.end
637 if.end:                                           ; preds = %if.else, %if.then
638   %tmax.0 = phi float [ %mul2, %if.then ], [ %mul6, %if.else ]
639   %tmin.0 = phi float [ %mul, %if.then ], [ %mul4, %if.else ]
641   %6 = load float, ptr %max, align 4
642   %7 = load float, ptr %a, align 4
643   %sub6 = fsub float %6, %7
644   %mul7 = fmul float %sub6, %div
645   %8 = load float, ptr %min, align 4
646   %sub8 = fsub float %8, %7
647   %mul9 = fmul float %sub8, %div
649   %add = fadd float %tmax.0, %tmin.0
650   ret float %add
653 ; Check that we do not hoist loads outside a loop containing stores.
654 define float @noHoistInLoopsWithStores(float %d, ptr %min, ptr %max, ptr %a) {
655 ; CHECK-LABEL: @noHoistInLoopsWithStores(
656 ; CHECK-NEXT:  entry:
657 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[D:%.*]]
658 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[DIV]], 0.000000e+00
659 ; CHECK-NEXT:    br i1 [[CMP]], label [[DO_BODY:%.*]], label [[IF_ELSE:%.*]]
660 ; CHECK:       do.body:
661 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[MIN:%.*]], align 4
662 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[A:%.*]], align 4
663 ; CHECK-NEXT:    store float 0.000000e+00, ptr @GlobalVar, align 4
664 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[TMP0]], [[TMP1]]
665 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[DIV]]
666 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[MAX:%.*]], align 4
667 ; CHECK-NEXT:    [[SUB1:%.*]] = fsub float [[TMP2]], [[TMP1]]
668 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[SUB1]], [[DIV]]
669 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
670 ; CHECK:       while.cond:
671 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oge float [[MUL2]], 0.000000e+00
672 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_END:%.*]], label [[DO_BODY]]
673 ; CHECK:       if.else:
674 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[MAX]], align 4
675 ; CHECK-NEXT:    [[TMP4:%.*]] = load float, ptr [[A]], align 4
676 ; CHECK-NEXT:    [[SUB3:%.*]] = fsub float [[TMP3]], [[TMP4]]
677 ; CHECK-NEXT:    [[MUL4:%.*]] = fmul float [[SUB3]], [[DIV]]
678 ; CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[MIN]], align 4
679 ; CHECK-NEXT:    [[SUB5:%.*]] = fsub float [[TMP5]], [[TMP4]]
680 ; CHECK-NEXT:    [[MUL6:%.*]] = fmul float [[SUB5]], [[DIV]]
681 ; CHECK-NEXT:    br label [[IF_END]]
682 ; CHECK:       if.end:
683 ; CHECK-NEXT:    [[TMAX_0:%.*]] = phi float [ [[MUL2]], [[WHILE_COND]] ], [ [[MUL6]], [[IF_ELSE]] ]
684 ; CHECK-NEXT:    [[TMIN_0:%.*]] = phi float [ [[MUL]], [[WHILE_COND]] ], [ [[MUL4]], [[IF_ELSE]] ]
685 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMAX_0]], [[TMIN_0]]
686 ; CHECK-NEXT:    ret float [[ADD]]
688 entry:
689   %div = fdiv float 1.000000e+00, %d
690   %cmp = fcmp oge float %div, 0.000000e+00
691   br i1 %cmp, label %do.body, label %if.else
693 do.body:
694   %0 = load float, ptr %min, align 4
695   %1 = load float, ptr %a, align 4
697   ; It is unsafe to hoist the loads outside the loop because of the store.
698   store float 0.000000e+00, ptr @GlobalVar
700   %sub = fsub float %0, %1
701   %mul = fmul float %sub, %div
702   %2 = load float, ptr %max, align 4
703   %sub1 = fsub float %2, %1
704   %mul2 = fmul float %sub1, %div
705   br label %while.cond
707 while.cond:
708   %cmp1 = fcmp oge float %mul2, 0.000000e+00
709   br i1 %cmp1, label %if.end, label %do.body
711 if.else:
712   %3 = load float, ptr %max, align 4
713   %4 = load float, ptr %a, align 4
714   %sub3 = fsub float %3, %4
715   %mul4 = fmul float %sub3, %div
716   %5 = load float, ptr %min, align 4
717   %sub5 = fsub float %5, %4
718   %mul6 = fmul float %sub5, %div
719   br label %if.end
721 if.end:
722   %tmax.0 = phi float [ %mul2, %while.cond ], [ %mul6, %if.else ]
723   %tmin.0 = phi float [ %mul, %while.cond ], [ %mul4, %if.else ]
725   %add = fadd float %tmax.0, %tmin.0
726   ret float %add
729 ; Check that we hoist stores: all the instructions from the then branch
730 ; should be hoisted.
732 %struct.foo = type { ptr }
734 define void @hoistStores(ptr %s, ptr %coord, i1 zeroext %delta) {
735 ; CHECK-LABEL: @hoistStores(
736 ; CHECK-NEXT:  entry:
737 ; CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[DELTA:%.*]] to i8
738 ; CHECK-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[FROMBOOL]] to i1
739 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[S:%.*]], i32 0, i32 0
740 ; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
741 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[S]], i32 0, i32 0
742 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 1
743 ; CHECK-NEXT:    store ptr [[TMP3]], ptr [[TMP2]], align 8
744 ; CHECK-NEXT:    [[TMP4:%.*]] = load i16, ptr [[TMP1]], align 2
745 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[COORD:%.*]], align 4
746 ; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[TMP4]] to i32
747 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP5]], [[CONV]]
748 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[COORD]], align 4
749 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
750 ; CHECK:       if.then:
751 ; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[S]], i32 0, i32 0
752 ; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 1
753 ; CHECK-NEXT:    br label [[IF_END:%.*]]
754 ; CHECK:       if.else:
755 ; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[S]], i32 0, i32 0
756 ; CHECK-NEXT:    [[INCDEC_PTR2:%.*]] = getelementptr inbounds i16, ptr [[TMP1]], i32 1
757 ; CHECK-NEXT:    [[TMP6:%.*]] = load ptr, ptr [[P1]], align 8
758 ; CHECK-NEXT:    [[INCDEC_PTR6:%.*]] = getelementptr inbounds i16, ptr [[TMP6]], i32 1
759 ; CHECK-NEXT:    store ptr [[INCDEC_PTR6]], ptr [[P1]], align 8
760 ; CHECK-NEXT:    [[TMP7:%.*]] = load i16, ptr [[TMP6]], align 2
761 ; CHECK-NEXT:    [[CONV7:%.*]] = zext i16 [[TMP7]] to i32
762 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV7]], 8
763 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[COORD]], align 4
764 ; CHECK-NEXT:    [[ADD8:%.*]] = add i32 [[TMP8]], [[SHL]]
765 ; CHECK-NEXT:    store i32 [[ADD8]], ptr [[COORD]], align 4
766 ; CHECK-NEXT:    br label [[IF_END]]
767 ; CHECK:       if.end:
768 ; CHECK-NEXT:    ret void
770 entry:
771   %frombool = zext i1 %delta to i8
772   %tobool = trunc i8 %frombool to i1
773   br i1 %tobool, label %if.then, label %if.else
775 if.then:                                          ; preds = %entry
776   %p = getelementptr inbounds %struct.foo, ptr %s, i32 0, i32 0
777   %0 = load ptr, ptr %p, align 8
778   %incdec.ptr = getelementptr inbounds i16, ptr %0, i32 1
779   store ptr %incdec.ptr, ptr %p, align 8
780   %1 = load i16, ptr %0, align 2
781   %conv = zext i16 %1 to i32
782   %2 = load i32, ptr %coord, align 4
783   %add = add i32 %2, %conv
784   store i32 %add, ptr %coord, align 4
785   br label %if.end
787 if.else:                                          ; preds = %entry
788   %p1 = getelementptr inbounds %struct.foo, ptr %s, i32 0, i32 0
789   %3 = load ptr, ptr %p1, align 8
790   %incdec.ptr2 = getelementptr inbounds i16, ptr %3, i32 1
791   store ptr %incdec.ptr2, ptr %p1, align 8
792   %4 = load i16, ptr %3, align 2
793   %conv3 = zext i16 %4 to i32
794   %5 = load i32, ptr %coord, align 4
795   %add4 = add i32 %5, %conv3
796   store i32 %add4, ptr %coord, align 4
797   %6 = load ptr, ptr %p1, align 8
798   %incdec.ptr6 = getelementptr inbounds i16, ptr %6, i32 1
799   store ptr %incdec.ptr6, ptr %p1, align 8
800   %7 = load i16, ptr %6, align 2
801   %conv7 = zext i16 %7 to i32
802   %shl = shl i32 %conv7, 8
803   %8 = load i32, ptr %coord, align 4
804   %add8 = add i32 %8, %shl
805   store i32 %add8, ptr %coord, align 4
806   br label %if.end
808 if.end:                                           ; preds = %if.else, %if.then
809   ret void
812 define i32 @mergeAlignments(i1 %b, ptr %y) {
813 ; CHECK-LABEL: @mergeAlignments(
814 ; CHECK-NEXT:  entry:
815 ; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[Y:%.*]], align 1
816 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
817 ; CHECK:       if.then:
818 ; CHECK-NEXT:    br label [[RETURN:%.*]]
819 ; CHECK:       if.end:
820 ; CHECK-NEXT:    br label [[RETURN]]
821 ; CHECK:       return:
822 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[L1]], [[IF_THEN]] ], [ [[L1]], [[IF_END]] ]
823 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
825 entry:
826   br i1 %b, label %if.then, label %if.end
828 if.then:                                          ; preds = %entry
829   %l1 = load i32, ptr %y, align 4
830   br label %return
832 if.end:                                           ; preds = %entry
833   %l2 = load i32, ptr %y, align 1
834   br label %return
836 return:                                           ; preds = %if.end, %if.then
837   %retval.0 = phi i32 [ %l1, %if.then ], [ %l2, %if.end ]
838   ret i32 %retval.0
841 declare i8 @pr30991_f() nounwind readonly
842 declare void @pr30991_f1(i8)
843 define i8 @pr30991(ptr %sp, ptr %word, i1 %b1, i1 %b2) {
844 ; CHECK-LABEL: @pr30991(
845 ; CHECK-NEXT:  entry:
846 ; CHECK-NEXT:    [[R0:%.*]] = load i8, ptr [[WORD:%.*]], align 1
847 ; CHECK-NEXT:    br i1 [[B1:%.*]], label [[A:%.*]], label [[B:%.*]]
848 ; CHECK:       a:
849 ; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr i8, ptr [[SP:%.*]], i32 1
850 ; CHECK-NEXT:    [[RR0:%.*]] = call i8 @pr30991_f() #[[ATTR0:[0-9]+]]
851 ; CHECK-NEXT:    call void @pr30991_f1(i8 [[R0]])
852 ; CHECK-NEXT:    ret i8 [[RR0]]
853 ; CHECK:       b:
854 ; CHECK-NEXT:    br i1 [[B2:%.*]], label [[C:%.*]], label [[X:%.*]]
855 ; CHECK:       c:
856 ; CHECK-NEXT:    [[INCDEC_PTR115:%.*]] = getelementptr i8, ptr [[SP]], i32 1
857 ; CHECK-NEXT:    [[RR1:%.*]] = call i8 @pr30991_f() #[[ATTR0]]
858 ; CHECK-NEXT:    call void @pr30991_f1(i8 [[R0]])
859 ; CHECK-NEXT:    ret i8 [[RR1]]
860 ; CHECK:       x:
861 ; CHECK-NEXT:    ret i8 [[R0]]
863 entry:
864   br i1 %b1, label %a, label %b
867   %r0 = load i8, ptr %word, align 1
868   %incdec.ptr = getelementptr i8, ptr %sp, i32 1
869   %rr0 = call i8 @pr30991_f() nounwind readonly
870   call void @pr30991_f1(i8 %r0)
871   ret i8 %rr0
874   br i1 %b2, label %c, label %x
877   %r1 = load i8, ptr %word, align 1
878   %incdec.ptr115 = getelementptr i8, ptr %sp, i32 1
879   %rr1 = call i8 @pr30991_f() nounwind readonly
880   call void @pr30991_f1(i8 %r1)
881   ret i8 %rr1
884   %r2 = load i8, ptr %word, align 1
885   ret i8 %r2