[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / sink_sideeffecting_instruction.ll
blob0a13742e634788a42048e55831174fc34544cc74
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 ; Function Attrs: noinline uwtable
5 define i32 @foo(i32* nocapture writeonly %arg) {
6 ; CHECK-LABEL: @foo(
7 ; CHECK-NEXT:  bb:
8 ; CHECK-NEXT:    [[VAR:%.*]] = call i32 @baz()
9 ; CHECK-NEXT:    store i32 [[VAR]], i32* [[ARG:%.*]], align 4
10 ; CHECK-NEXT:    [[VAR1:%.*]] = call i32 @baz()
11 ; CHECK-NEXT:    ret i32 [[VAR1]]
13 bb:
14   %var = call i32 @baz()
15   store i32 %var, i32* %arg, align 4
16   %var1 = call i32 @baz()
17   ret i32 %var1
19 declare i32 @baz()
21 ; Function Attrs: uwtable
22 ; This is an equivalent IR for a c-style example with a large function (foo)
23 ; with out-params which are unused in the caller(test8). Note that foo is
24 ; marked noinline to prevent IPO transforms.
25 ; int foo();
27 ; extern int foo(int *out) __attribute__((noinline));
28 ; int foo(int *out) {
29 ;   *out = baz();
30 ;   return baz();
31 ; }
33 ; int test() {
35 ;   int notdead;
36 ;   if (foo(&notdead))
37 ;     return 0;
39 ;   int dead;
40 ;   int tmp = foo(&dead);
41 ;   if (notdead)
42 ;     return tmp;
43 ;   return bar();
44 ; }
46 ; TODO: We should be able to sink the second call @foo at bb5 down to bb_crit_edge
47 define i32 @test() {
48 ; CHECK-LABEL: @test(
49 ; CHECK-NEXT:  bb:
50 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
51 ; CHECK-NEXT:    [[VAR1:%.*]] = alloca i32, align 4
52 ; CHECK-NEXT:    [[VAR2:%.*]] = bitcast i32* [[VAR]] to i8*
53 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[VAR2]])
54 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @foo(i32* nonnull writeonly [[VAR]])
55 ; CHECK-NEXT:    [[VAR4:%.*]] = icmp eq i32 [[VAR3]], 0
56 ; CHECK-NEXT:    br i1 [[VAR4]], label [[BB5:%.*]], label [[BB14:%.*]]
57 ; CHECK:       bb5:
58 ; CHECK-NEXT:    [[VAR6:%.*]] = bitcast i32* [[VAR1]] to i8*
59 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[VAR6]])
60 ; CHECK-NEXT:    [[VAR8:%.*]] = load i32, i32* [[VAR]], align 4
61 ; CHECK-NEXT:    [[VAR9:%.*]] = icmp eq i32 [[VAR8]], 0
62 ; CHECK-NEXT:    [[VAR7:%.*]] = call i32 @foo(i32* nonnull writeonly [[VAR1]])
63 ; CHECK-NEXT:    br i1 [[VAR9]], label [[BB10:%.*]], label [[BB_CRIT_EDGE:%.*]]
64 ; CHECK:       bb10:
65 ; CHECK-NEXT:    [[VAR11:%.*]] = call i32 @bar()
66 ; CHECK-NEXT:    br label [[BB12:%.*]]
67 ; CHECK:       bb_crit_edge:
68 ; CHECK-NEXT:    br label [[BB12]]
69 ; CHECK:       bb12:
70 ; CHECK-NEXT:    [[VAR13:%.*]] = phi i32 [ [[VAR11]], [[BB10]] ], [ [[VAR7]], [[BB_CRIT_EDGE]] ]
71 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[VAR6]])
72 ; CHECK-NEXT:    br label [[BB14]]
73 ; CHECK:       bb14:
74 ; CHECK-NEXT:    [[VAR15:%.*]] = phi i32 [ [[VAR13]], [[BB12]] ], [ 0, [[BB:%.*]] ]
75 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[VAR2]])
76 ; CHECK-NEXT:    ret i32 [[VAR15]]
78 bb:
79   %var = alloca i32, align 4
80   %var1 = alloca i32, align 4
81   %var2 = bitcast i32* %var to i8*
82   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %var2) #4
83   %var3 = call i32 @foo(i32* nonnull writeonly %var)
84   %var4 = icmp eq i32 %var3, 0
85   br i1 %var4, label %bb5, label %bb14
87 bb5:                                              ; preds = %bb
88   %var6 = bitcast i32* %var1 to i8*
89   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %var6) #4
90   %var8 = load i32, i32* %var, align 4
91   %var9 = icmp eq i32 %var8, 0
92   %var7 = call i32 @foo(i32* nonnull writeonly %var1)
93   br i1 %var9, label %bb10, label %bb_crit_edge
95 bb10:                                             ; preds = %bb5
96   %var11 = call i32 @bar()
97   br label %bb12
99 bb_crit_edge:
100   br label %bb12
102 bb12:                                             ; preds = %bb10, %bb5
103   %var13 = phi i32 [ %var11, %bb10 ], [ %var7, %bb_crit_edge ]
104   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %var6) #4
105   br label %bb14
107 bb14:                                             ; preds = %bb12, %bb
108   %var15 = phi i32 [ %var13, %bb12 ], [ 0, %bb ]
109   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %var2)
110   ret i32 %var15
113 declare i32 @unknown(i32* %dest)
114 declare i32 @unknown.as2(i32 addrspace(2)* %dest)
116 define i32 @sink_write_to_use(i1 %c) {
117 ; CHECK-LABEL: @sink_write_to_use(
118 ; CHECK-NEXT:  entry:
119 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
120 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
121 ; CHECK:       early_return:
122 ; CHECK-NEXT:    ret i32 0
123 ; CHECK:       use_block:
124 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull writeonly [[VAR]]) #[[ATTR1:[0-9]+]]
125 ; CHECK-NEXT:    ret i32 [[VAR3]]
127 entry:
128   %var = alloca i32, align 4
129   %var3 = call i32 @unknown(i32* writeonly %var) argmemonly nounwind willreturn
130   br i1 %c, label %early_return, label %use_block
132 early_return:
133   ret i32 0
135 use_block:
136   ret i32 %var3
139 define i32 @sink_readwrite_to_use(i1 %c) {
140 ; CHECK-LABEL: @sink_readwrite_to_use(
141 ; CHECK-NEXT:  entry:
142 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
143 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
144 ; CHECK:       early_return:
145 ; CHECK-NEXT:    ret i32 0
146 ; CHECK:       use_block:
147 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
148 ; CHECK-NEXT:    ret i32 [[VAR3]]
150 entry:
151   %var = alloca i32, align 4
152   %var3 = call i32 @unknown(i32* %var) argmemonly nounwind willreturn
153   br i1 %c, label %early_return, label %use_block
155 early_return:
156   ret i32 0
158 use_block:
159   ret i32 %var3
162 define i32 @sink_bitcast(i1 %c) {
163 ; CHECK-LABEL: @sink_bitcast(
164 ; CHECK-NEXT:  entry:
165 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i8, align 8
166 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
167 ; CHECK:       early_return:
168 ; CHECK-NEXT:    ret i32 0
169 ; CHECK:       use_block:
170 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i8* [[VAR]] to i32*
171 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[BITCAST]]) #[[ATTR1]]
172 ; CHECK-NEXT:    ret i32 [[VAR3]]
174 entry:
175   %var = alloca i8, align 8
176   %bitcast = bitcast i8* %var to i32*
177   %var3 = call i32 @unknown(i32* %bitcast) argmemonly nounwind willreturn
178   br i1 %c, label %early_return, label %use_block
180 early_return:
181   ret i32 0
183 use_block:
184   ret i32 %var3
188 define i32 @sink_gep1(i1 %c) {
189 ; CHECK-LABEL: @sink_gep1(
190 ; CHECK-NEXT:  entry:
191 ; CHECK-NEXT:    [[VAR1:%.*]] = alloca [2 x i32], align 8
192 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
193 ; CHECK:       early_return:
194 ; CHECK-NEXT:    ret i32 0
195 ; CHECK:       use_block:
196 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VAR1]], i64 0, i64 1
197 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[GEP]]) #[[ATTR1]]
198 ; CHECK-NEXT:    ret i32 [[VAR3]]
200 entry:
201   %var = alloca i64, align 8
202   %bitcast = bitcast i64* %var to i32*
203   %gep = getelementptr i32, i32* %bitcast, i32 1
204   %var3 = call i32 @unknown(i32* %gep) argmemonly nounwind willreturn
205   br i1 %c, label %early_return, label %use_block
207 early_return:
208   ret i32 0
210 use_block:
211   ret i32 %var3
214 define i32 @sink_gep2(i1 %c) {
215 ; CHECK-LABEL: @sink_gep2(
216 ; CHECK-NEXT:  entry:
217 ; CHECK-NEXT:    [[VAR1:%.*]] = alloca [2 x i32], align 8
218 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
219 ; CHECK:       early_return:
220 ; CHECK-NEXT:    ret i32 0
221 ; CHECK:       use_block:
222 ; CHECK-NEXT:    [[VAR1_SUB:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VAR1]], i64 0, i64 0
223 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR1_SUB]]) #[[ATTR1]]
224 ; CHECK-NEXT:    ret i32 [[VAR3]]
226 entry:
227   %var = alloca i64, align 8
228   %bitcast = bitcast i64* %var to i32*
229   %var3 = call i32 @unknown(i32* %bitcast) argmemonly nounwind willreturn
230   br i1 %c, label %early_return, label %use_block
232 early_return:
233   ret i32 0
235 use_block:
236   ret i32 %var3
239 define i32 @sink_addrspacecast(i1 %c) {
240 ; CHECK-LABEL: @sink_addrspacecast(
241 ; CHECK-NEXT:  entry:
242 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 8
243 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
244 ; CHECK:       early_return:
245 ; CHECK-NEXT:    ret i32 0
246 ; CHECK:       use_block:
247 ; CHECK-NEXT:    [[CAST:%.*]] = addrspacecast i32* [[VAR]] to i32 addrspace(2)*
248 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown.as2(i32 addrspace(2)* [[CAST]]) #[[ATTR1]]
249 ; CHECK-NEXT:    ret i32 [[VAR3]]
251 entry:
252   %var = alloca i32, align 8
253   %cast = addrspacecast i32* %var to i32 addrspace(2)*
254   %var3 = call i32 @unknown.as2(i32 addrspace(2)* %cast) argmemonly nounwind willreturn
255   br i1 %c, label %early_return, label %use_block
257 early_return:
258   ret i32 0
260 use_block:
261   ret i32 %var3
264 define i32 @neg_infinite_loop(i1 %c) {
265 ; CHECK-LABEL: @neg_infinite_loop(
266 ; CHECK-NEXT:  entry:
267 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
268 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR2:[0-9]+]]
269 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
270 ; CHECK:       early_return:
271 ; CHECK-NEXT:    ret i32 0
272 ; CHECK:       use_block:
273 ; CHECK-NEXT:    ret i32 [[VAR3]]
275 entry:
276   %var = alloca i32, align 4
277   %var3 = call i32 @unknown(i32* %var) argmemonly nounwind
278   br i1 %c, label %early_return, label %use_block
280 early_return:
281   ret i32 0
283 use_block:
284   ret i32 %var3
287 define i32 @neg_throw(i1 %c) {
288 ; CHECK-LABEL: @neg_throw(
289 ; CHECK-NEXT:  entry:
290 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
291 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR3:[0-9]+]]
292 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
293 ; CHECK:       early_return:
294 ; CHECK-NEXT:    ret i32 0
295 ; CHECK:       use_block:
296 ; CHECK-NEXT:    ret i32 [[VAR3]]
298 entry:
299   %var = alloca i32, align 4
300   %var3 = call i32 @unknown(i32* %var) argmemonly willreturn
301   br i1 %c, label %early_return, label %use_block
303 early_return:
304   ret i32 0
306 use_block:
307   ret i32 %var3
310 define i32 @neg_unknown_write(i1 %c) {
311 ; CHECK-LABEL: @neg_unknown_write(
312 ; CHECK-NEXT:  entry:
313 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
314 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR4:[0-9]+]]
315 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
316 ; CHECK:       early_return:
317 ; CHECK-NEXT:    ret i32 0
318 ; CHECK:       use_block:
319 ; CHECK-NEXT:    ret i32 [[VAR3]]
321 entry:
322   %var = alloca i32, align 4
323   %var3 = call i32 @unknown(i32* %var) nounwind willreturn
324   br i1 %c, label %early_return, label %use_block
326 early_return:
327   ret i32 0
329 use_block:
330   ret i32 %var3
333 define i32 @sink_lifetime1(i1 %c) {
334 ; CHECK-LABEL: @sink_lifetime1(
335 ; CHECK-NEXT:  entry:
336 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
337 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
338 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
339 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
340 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
341 ; CHECK:       early_return:
342 ; CHECK-NEXT:    ret i32 0
343 ; CHECK:       use_block:
344 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
345 ; CHECK-NEXT:    ret i32 [[VAR3]]
347 entry:
348   %var = alloca i32, align 4
349   %bitcast = bitcast i32* %var to i8*
350   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
351   %var3 = call i32 @unknown(i32* %var) argmemonly nounwind willreturn
352   br i1 %c, label %early_return, label %use_block
354 early_return:
355   ret i32 0
357 use_block:
358   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
359   ret i32 %var3
362 define i32 @sink_lifetime2(i1 %c) {
363 ; CHECK-LABEL: @sink_lifetime2(
364 ; CHECK-NEXT:  entry:
365 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
366 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
367 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
368 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
369 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[MERGE:%.*]], label [[USE_BLOCK:%.*]]
370 ; CHECK:       merge:
371 ; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAR3]], [[USE_BLOCK]] ]
372 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
373 ; CHECK-NEXT:    ret i32 [[RET]]
374 ; CHECK:       use_block:
375 ; CHECK-NEXT:    br label [[MERGE]]
377 entry:
378   %var = alloca i32, align 4
379   %bitcast = bitcast i32* %var to i8*
380   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
381   %var3 = call i32 @unknown(i32* %var) argmemonly nounwind willreturn
382   br i1 %c, label %merge, label %use_block
384 merge:
385   %ret = phi i32 [0, %entry], [%var3, %use_block]
386   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
387   ret i32 %ret
389 use_block:
390   br label %merge
393 define i32 @sink_lifetime3(i1 %c) {
394 ; CHECK-LABEL: @sink_lifetime3(
395 ; CHECK-NEXT:  entry:
396 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
397 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
398 ; CHECK:       early_return:
399 ; CHECK-NEXT:    ret i32 0
400 ; CHECK:       use_block:
401 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
402 ; CHECK-NEXT:    ret i32 [[VAR3]]
404 entry:
405   %var = alloca i32, align 4
406   %bitcast = bitcast i32* %var to i8*
407   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
408   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
409   ; If unknown accesses %var, that's UB
410   %var3 = call i32 @unknown(i32* %var) argmemonly nounwind willreturn
411   br i1 %c, label %early_return, label %use_block
413 early_return:
414   ret i32 0
416 use_block:
417   ret i32 %var3
420 define i32 @sink_lifetime4a(i1 %c) {
421 ; CHECK-LABEL: @sink_lifetime4a(
422 ; CHECK-NEXT:  entry:
423 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
424 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
425 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
426 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
427 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
428 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
429 ; CHECK:       early_return:
430 ; CHECK-NEXT:    ret i32 0
431 ; CHECK:       use_block:
432 ; CHECK-NEXT:    ret i32 [[VAR3]]
434 entry:
435   %var = alloca i32, align 4
436   %bitcast = bitcast i32* %var to i8*
437   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
438   %var3 = call i32 @unknown(i32* %var) argmemonly nounwind willreturn
439   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
440   br i1 %c, label %early_return, label %use_block
442 early_return:
443   ret i32 0
445 use_block:
446   ret i32 %var3
449 ; Version which only writes to var, and thus can't rely on may-read scan for
450 ; clobbers to prevent the transform
451 define i32 @sink_lifetime4b(i1 %c) {
452 ; CHECK-LABEL: @sink_lifetime4b(
453 ; CHECK-NEXT:  entry:
454 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
455 ; CHECK-NEXT:    [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
456 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
457 ; CHECK-NEXT:    [[VAR3:%.*]] = call i32 @unknown(i32* nonnull writeonly [[VAR]]) #[[ATTR1]]
458 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
459 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
460 ; CHECK:       early_return:
461 ; CHECK-NEXT:    ret i32 0
462 ; CHECK:       use_block:
463 ; CHECK-NEXT:    ret i32 [[VAR3]]
465 entry:
466   %var = alloca i32, align 4
467   %bitcast = bitcast i32* %var to i8*
468   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
469   %var3 = call i32 @unknown(i32* writeonly %var) argmemonly nounwind willreturn
470   call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
471   br i1 %c, label %early_return, label %use_block
473 early_return:
474   ret i32 0
476 use_block:
477   ret i32 %var3
479 ; Mostly checking that trying to sink a non-call doesn't crash (i.e. prior bug)
480 define i32 @sink_atomicrmw_to_use(i1 %c) {
481 ; CHECK-LABEL: @sink_atomicrmw_to_use(
482 ; CHECK-NEXT:  entry:
483 ; CHECK-NEXT:    [[VAR:%.*]] = alloca i32, align 4
484 ; CHECK-NEXT:    store i32 0, i32* [[VAR]], align 4
485 ; CHECK-NEXT:    [[VAR3:%.*]] = atomicrmw add i32* [[VAR]], i32 1 seq_cst, align 4
486 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
487 ; CHECK:       early_return:
488 ; CHECK-NEXT:    ret i32 0
489 ; CHECK:       use_block:
490 ; CHECK-NEXT:    ret i32 [[VAR3]]
492 entry:
493   %var = alloca i32, align 4
494   store i32 0, i32* %var
495   %var3 = atomicrmw add i32* %var, i32 1 seq_cst, align 4
496   br i1 %c, label %early_return, label %use_block
498 early_return:
499   ret i32 0
501 use_block:
502   ret i32 %var3
506 declare i32 @bar()
507 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
508 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)