1 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
3 ; RUN: opt -S -basicaa -licm -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
4 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(simplify-cfg,licm)' -verify-memoryssa -S < %s | FileCheck %s
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 target triple = "x86_64-unknown-linux-gnu"
9 ; This test represents the following function:
10 ; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) {
11 ; for (int i = 0; i < n; ++i)
15 ; and we want to hoist the load of %c out of the loop. This can be done only
16 ; because the dereferenceable attribute is on %c.
19 ; CHECK: load i32, i32* %c, align 4
22 define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 {
24 %cmp11 = icmp sgt i32 %n, 0
25 br i1 %cmp11, label %for.body, label %for.end
27 for.body: ; preds = %entry, %for.inc
28 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
29 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
30 %0 = load i32, i32* %arrayidx, align 4
31 %cmp1 = icmp sgt i32 %0, 0
32 br i1 %cmp1, label %if.then, label %for.inc
34 if.then: ; preds = %for.body
35 %1 = load i32, i32* %c, align 4
36 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
37 %2 = load i32, i32* %arrayidx3, align 4
38 %mul = mul nsw i32 %2, %1
39 store i32 %mul, i32* %arrayidx, align 4
42 for.inc: ; preds = %for.body, %if.then
43 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
44 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
45 %exitcond = icmp eq i32 %lftr.wideiv, %n
46 br i1 %exitcond, label %for.end, label %for.body
48 for.end: ; preds = %for.inc, %entry
52 ; This is the same as @test1, but without the dereferenceable attribute on %c.
53 ; Without this attribute, we should not hoist the load of %c.
57 ; CHECK: load i32, i32* %c, align 4
59 define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 {
61 %cmp11 = icmp sgt i32 %n, 0
62 br i1 %cmp11, label %for.body, label %for.end
64 for.body: ; preds = %entry, %for.inc
65 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
66 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
67 %0 = load i32, i32* %arrayidx, align 4
68 %cmp1 = icmp sgt i32 %0, 0
69 br i1 %cmp1, label %if.then, label %for.inc
71 if.then: ; preds = %for.body
72 %1 = load i32, i32* %c, align 4
73 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
74 %2 = load i32, i32* %arrayidx3, align 4
75 %mul = mul nsw i32 %2, %1
76 store i32 %mul, i32* %arrayidx, align 4
79 for.inc: ; preds = %for.body, %if.then
80 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
81 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
82 %exitcond = icmp eq i32 %lftr.wideiv, %n
83 br i1 %exitcond, label %for.end, label %for.body
85 for.end: ; preds = %for.inc, %entry
89 ; This test represents the following function:
90 ; void test3(int * restrict a, int * restrict b, int c[static 3], int n) {
91 ; for (int i = 0; i < n; ++i)
95 ; and we want to hoist the load of c[2] out of the loop. This can be done only
96 ; because the dereferenceable attribute is on %c.
99 ; CHECK: load i32, i32* %c2, align 4
102 define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 {
104 %cmp11 = icmp sgt i32 %n, 0
105 br i1 %cmp11, label %for.body, label %for.end
107 for.body: ; preds = %entry, %for.inc
108 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
109 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
110 %0 = load i32, i32* %arrayidx, align 4
111 %cmp1 = icmp sgt i32 %0, 0
112 br i1 %cmp1, label %if.then, label %for.inc
114 if.then: ; preds = %for.body
115 %c2 = getelementptr inbounds i32, i32* %c, i64 2
116 %1 = load i32, i32* %c2, align 4
117 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
118 %2 = load i32, i32* %arrayidx3, align 4
119 %mul = mul nsw i32 %2, %1
120 store i32 %mul, i32* %arrayidx, align 4
123 for.inc: ; preds = %for.body, %if.then
124 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
125 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
126 %exitcond = icmp eq i32 %lftr.wideiv, %n
127 br i1 %exitcond, label %for.end, label %for.body
129 for.end: ; preds = %for.inc, %entry
133 ; This is the same as @test3, but with a dereferenceable attribute on %c with a
134 ; size too small to cover c[2] (and so we should not hoist it).
136 ; CHECK-LABEL: @test4
138 ; CHECK: load i32, i32* %c2, align 4
140 define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 {
142 %cmp11 = icmp sgt i32 %n, 0
143 br i1 %cmp11, label %for.body, label %for.end
145 for.body: ; preds = %entry, %for.inc
146 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
147 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
148 %0 = load i32, i32* %arrayidx, align 4
149 %cmp1 = icmp sgt i32 %0, 0
150 br i1 %cmp1, label %if.then, label %for.inc
152 if.then: ; preds = %for.body
153 %c2 = getelementptr inbounds i32, i32* %c, i64 2
154 %1 = load i32, i32* %c2, align 4
155 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
156 %2 = load i32, i32* %arrayidx3, align 4
157 %mul = mul nsw i32 %2, %1
158 store i32 %mul, i32* %arrayidx, align 4
161 for.inc: ; preds = %for.body, %if.then
162 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
163 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
164 %exitcond = icmp eq i32 %lftr.wideiv, %n
165 br i1 %exitcond, label %for.end, label %for.body
167 for.end: ; preds = %for.inc, %entry
171 ; This test represents the following function:
172 ; void test1(int * __restrict__ a, int *b, int &c, int n) {
174 ; for (int i = 0; i < n; ++i)
178 ; and we want to hoist the load of %c out of the loop. This can be done only
179 ; because the dereferenceable_or_null attribute is on %c and there is a null
182 ; CHECK-LABEL: @test5
183 ; CHECK: load i32, i32* %c, align 4
186 define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
188 %not_null = icmp ne i32* %c, null
189 br i1 %not_null, label %not.null, label %for.end
192 %cmp11 = icmp sgt i32 %n, 0
193 br i1 %cmp11, label %for.body, label %for.end
195 for.body: ; preds = %not.null, %for.inc
196 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
197 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
198 %0 = load i32, i32* %arrayidx, align 4
199 %cmp1 = icmp sgt i32 %0, 0
200 br i1 %cmp1, label %if.then, label %for.inc
202 if.then: ; preds = %for.body
203 %1 = load i32, i32* %c, align 4
204 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
205 %2 = load i32, i32* %arrayidx3, align 4
206 %mul = mul nsw i32 %2, %1
207 store i32 %mul, i32* %arrayidx, align 4
210 for.inc: ; preds = %for.body, %if.then
211 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
212 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
213 %exitcond = icmp eq i32 %lftr.wideiv, %n
214 br i1 %exitcond, label %for.end, label %for.body
216 for.end: ; preds = %for.inc, %entry, %not.null
220 ; This is the same as @test5, but without the null check on %c.
221 ; Without this check, we should not hoist the load of %c.
223 ; This test case has an icmp on c but the use of this comparison is
226 ; CHECK-LABEL: @test6
228 ; CHECK: load i32, i32* %c, align 4
230 define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
232 %not_null = icmp ne i32* %c, null
233 %cmp11 = icmp sgt i32 %n, 0
234 br i1 %cmp11, label %for.body, label %for.end
236 for.body: ; preds = %entry, %for.inc
237 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
238 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
239 %0 = load i32, i32* %arrayidx, align 4
240 %cmp1 = icmp sgt i32 %0, 0
241 br i1 %cmp1, label %if.then, label %for.inc
243 if.then: ; preds = %for.body
244 %1 = load i32, i32* %c, align 4
245 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
246 %2 = load i32, i32* %arrayidx3, align 4
247 %mul = mul nsw i32 %2, %1
248 store i32 %mul, i32* %arrayidx, align 4
251 for.inc: ; preds = %for.body, %if.then
252 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
253 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
254 %exitcond = icmp eq i32 %lftr.wideiv, %n
255 br i1 %exitcond, label %for.end, label %for.body
257 for.end: ; preds = %for.inc, %entry
261 ; This test represents the following function:
262 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
264 ; for (int i = 0; i < n; ++i)
268 ; and we want to hoist the load of %c out of the loop. This can be done only
269 ; because the dereferenceable meatdata on the c = *cptr load.
271 ; CHECK-LABEL: @test7
272 ; CHECK: load i32, i32* %c, align 4
275 define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
277 %c = load i32*, i32** %cptr, !dereferenceable !0
278 %cmp11 = icmp sgt i32 %n, 0
279 br i1 %cmp11, label %for.body, label %for.end
281 for.body: ; preds = %entry, %for.inc
282 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
283 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
284 %0 = load i32, i32* %arrayidx, align 4
285 %cmp1 = icmp sgt i32 %0, 0
286 br i1 %cmp1, label %if.then, label %for.inc
288 if.then: ; preds = %for.body
289 %1 = load i32, i32* %c, align 4
290 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
291 %2 = load i32, i32* %arrayidx3, align 4
292 %mul = mul nsw i32 %2, %1
293 store i32 %mul, i32* %arrayidx, align 4
296 for.inc: ; preds = %for.body, %if.then
297 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
298 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
299 %exitcond = icmp eq i32 %lftr.wideiv, %n
300 br i1 %exitcond, label %for.end, label %for.body
302 for.end: ; preds = %for.inc, %entry
306 ; This test represents the following function:
307 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
310 ; for (int i = 0; i < n; ++i)
314 ; and we want to hoist the load of %c out of the loop. This can be done only
315 ; because the dereferenceable_or_null meatdata on the c = *cptr load and there
316 ; is a null check on %c.
318 ; CHECK-LABEL: @test8
319 ; CHECK: load i32, i32* %c, align 4
322 define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
324 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
325 %not_null = icmp ne i32* %c, null
326 br i1 %not_null, label %not.null, label %for.end
329 %cmp11 = icmp sgt i32 %n, 0
330 br i1 %cmp11, label %for.body, label %for.end
332 for.body: ; preds = %not.null, %for.inc
333 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
334 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
335 %0 = load i32, i32* %arrayidx, align 4
336 %cmp1 = icmp sgt i32 %0, 0
337 br i1 %cmp1, label %if.then, label %for.inc
339 if.then: ; preds = %for.body
340 %1 = load i32, i32* %c, align 4
341 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
342 %2 = load i32, i32* %arrayidx3, align 4
343 %mul = mul nsw i32 %2, %1
344 store i32 %mul, i32* %arrayidx, align 4
347 for.inc: ; preds = %for.body, %if.then
348 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
349 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
350 %exitcond = icmp eq i32 %lftr.wideiv, %n
351 br i1 %exitcond, label %for.end, label %for.body
353 for.end: ; preds = %for.inc, %entry, %not.null
357 ; This is the same as @test8, but without the null check on %c.
358 ; Without this check, we should not hoist the load of %c.
360 ; CHECK-LABEL: @test9
362 ; CHECK: load i32, i32* %c, align 4
364 define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
366 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
367 %cmp11 = icmp sgt i32 %n, 0
368 br i1 %cmp11, label %for.body, label %for.end
370 for.body: ; preds = %entry, %for.inc
371 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
372 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
373 %0 = load i32, i32* %arrayidx, align 4
374 %cmp1 = icmp sgt i32 %0, 0
375 br i1 %cmp1, label %if.then, label %for.inc
377 if.then: ; preds = %for.body
378 %1 = load i32, i32* %c, align 4
379 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
380 %2 = load i32, i32* %arrayidx3, align 4
381 %mul = mul nsw i32 %2, %1
382 store i32 %mul, i32* %arrayidx, align 4
385 for.inc: ; preds = %for.body, %if.then
386 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
387 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
388 %exitcond = icmp eq i32 %lftr.wideiv, %n
389 br i1 %exitcond, label %for.end, label %for.body
391 for.end: ; preds = %for.inc, %entry
395 ; In this test we should be able to only hoist load from %cptr. We can't hoist
396 ; load from %c because it's dereferenceability can depend on %cmp1 condition.
397 ; By moving it out of the loop we break this dependency and can not rely
398 ; on the dereferenceability anymore.
399 ; In other words this test checks that we strip dereferenceability metadata
400 ; after hoisting an instruction.
402 ; CHECK-LABEL: @test10
403 ; CHECK: %c = load i32*, i32** %cptr
404 ; CHECK-NOT: dereferenceable
406 ; CHECK: load i32, i32* %c, align 4
408 define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
410 %cmp11 = icmp sgt i32 %n, 0
411 br i1 %cmp11, label %for.body, label %for.end
413 for.body: ; preds = %entry, %for.inc
414 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
415 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
416 %0 = load i32, i32* %arrayidx, align 4
417 %cmp1 = icmp sgt i32 %0, 0
418 br i1 %cmp1, label %if.then, label %for.inc
420 if.then: ; preds = %for.body
421 %c = load i32*, i32** %cptr, !dereferenceable !0
422 %1 = load i32, i32* %c, align 4
423 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
424 %2 = load i32, i32* %arrayidx3, align 4
425 %mul = mul nsw i32 %2, %1
426 store i32 %mul, i32* %arrayidx, align 4
429 for.inc: ; preds = %for.body, %if.then
430 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
431 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
432 %exitcond = icmp eq i32 %lftr.wideiv, %n
433 br i1 %exitcond, label %for.end, label %for.body
435 for.end: ; preds = %for.inc, %entry
439 define void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
440 ; CHECK-LABEL: @test11(
442 %cmp11 = icmp sgt i32 %n, 0
443 br i1 %cmp11, label %for.body, label %for.end
445 ; CHECK: for.body.preheader:
446 ; CHECK: %c = load i32*, i32** %cptr, !dereferenceable !0
447 ; CHECK: %d = load i32, i32* %c, align 4
450 for.body: ; preds = %entry, %for.inc
451 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
452 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
453 %0 = load i32, i32* %arrayidx, align 4
454 %cmp1 = icmp sgt i32 %0, 0
455 %c = load i32*, i32** %cptr, !dereferenceable !0
456 br i1 %cmp1, label %if.then, label %for.inc
458 if.then: ; preds = %for.body
459 %d = load i32, i32* %c, align 4
460 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
461 %e = load i32, i32* %arrayidx3, align 4
462 %mul = mul nsw i32 %e, %d
463 store i32 %mul, i32* %arrayidx, align 4
466 for.inc: ; preds = %for.body, %if.then
467 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
468 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
469 %exitcond = icmp eq i32 %lftr.wideiv, %n
470 br i1 %exitcond, label %for.end, label %for.body
472 for.end: ; preds = %for.inc, %entry
476 declare void @llvm.experimental.guard(i1, ...)
478 define void @test12(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
479 ; Prove non-null ness of %c via a guard, not a branch.
481 ; CHECK-LABEL: @test12(
483 %not_null = icmp ne i32* %c, null
484 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]
485 %cmp11 = icmp sgt i32 %n, 0
486 br i1 %cmp11, label %for.body, label %for.end
488 ; CHECK: for.body.preheader:
489 ; CHECK-NEXT: [[VAL:%[^ ]]] = load i32, i32* %c, align 4
490 ; CHECK-NEXT: br label %for.body
493 for.body: ; preds = %entry, %for.inc
494 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
495 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
496 %0 = load i32, i32* %arrayidx, align 4
497 %cmp1 = icmp sgt i32 %0, 0
498 br i1 %cmp1, label %if.then, label %for.inc
500 if.then: ; preds = %for.body
501 %1 = load i32, i32* %c, align 4
502 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
503 %2 = load i32, i32* %arrayidx3, align 4
504 %mul = mul nsw i32 %2, %1
505 store i32 %mul, i32* %arrayidx, align 4
508 for.inc: ; preds = %for.body, %if.then
509 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
510 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
511 %exitcond = icmp eq i32 %lftr.wideiv, %n
512 br i1 %exitcond, label %for.end, label %for.body
514 for.end: ; preds = %for.inc, %entry, %entry
518 define void @test13(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
519 ; Like @test12, but has a post-dominating guard, which cannot be used
520 ; to prove %c is nonnull at the point of the load.
522 ; CHECK-LABEL: @test13(
524 %not_null = icmp ne i32* %c, null
525 %cmp11 = icmp sgt i32 %n, 0
526 br i1 %cmp11, label %for.body, label %for.end
528 ; CHECK: for.body.preheader:
529 ; CHECK-NOT: load i32, i32* %c
530 ; CHECK: br label %for.body
532 for.body: ; preds = %entry, %for.inc
533 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
534 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
535 %0 = load i32, i32* %arrayidx, align 4
536 %cmp1 = icmp sgt i32 %0, 0
537 br i1 %cmp1, label %if.then, label %for.inc
539 if.then: ; preds = %for.body
541 ; CHECK: load i32, i32* %c
542 ; CHECK: br label %for.inc
543 %1 = load i32, i32* %c, align 4
544 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
545 %2 = load i32, i32* %arrayidx3, align 4
546 %mul = mul nsw i32 %2, %1
547 store i32 %mul, i32* %arrayidx, align 4
550 for.inc: ; preds = %for.body, %if.then
551 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
552 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
553 %exitcond = icmp eq i32 %lftr.wideiv, %n
554 br i1 %exitcond, label %for.end, label %for.body
556 for.end: ; preds = %for.inc, %entry, %entry
557 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]
561 ; Check that branch by condition "null check AND something" allows to hoist the
563 define void @test14(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 {
565 ; CHECK-LABEL: @test14
566 ; CHECK: load i32, i32* %c, align 4
570 %not_null = icmp ne i32* %c, null
571 %dummy_and = and i1 %not_null, %dummy_cond
572 br i1 %dummy_and, label %not.null, label %for.end
575 %cmp11 = icmp sgt i32 %n, 0
576 br i1 %cmp11, label %for.body, label %for.end
578 for.body: ; preds = %not.null, %for.inc
579 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
580 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
581 %0 = load i32, i32* %arrayidx, align 4
582 %cmp1 = icmp sgt i32 %0, 0
583 br i1 %cmp1, label %if.then, label %for.inc
585 if.then: ; preds = %for.body
586 %1 = load i32, i32* %c, align 4
587 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
588 %2 = load i32, i32* %arrayidx3, align 4
589 %mul = mul nsw i32 %2, %1
590 store i32 %mul, i32* %arrayidx, align 4
593 for.inc: ; preds = %for.body, %if.then
594 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
595 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
596 %exitcond = icmp eq i32 %lftr.wideiv, %n
597 br i1 %exitcond, label %for.end, label %for.body
599 for.end: ; preds = %for.inc, %entry, %not.null
603 ; Check that guard by condition "null check AND something" allows to hoist the
605 define void @test15(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 {
607 ; CHECK-LABEL: @test15
608 ; CHECK: load i32, i32* %c, align 4
612 %not_null = icmp ne i32* %c, null
613 %dummy_and = and i1 %not_null, %dummy_cond
614 call void(i1, ...) @llvm.experimental.guard(i1 %dummy_and) [ "deopt"() ]
615 %cmp11 = icmp sgt i32 %n, 0
616 br i1 %cmp11, label %for.body, label %for.end
618 for.body: ; preds = %entry, %for.inc
619 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
620 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
621 %0 = load i32, i32* %arrayidx, align 4
622 %cmp1 = icmp sgt i32 %0, 0
623 br i1 %cmp1, label %if.then, label %for.inc
625 if.then: ; preds = %for.body
626 %1 = load i32, i32* %c, align 4
627 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
628 %2 = load i32, i32* %arrayidx3, align 4
629 %mul = mul nsw i32 %2, %1
630 store i32 %mul, i32* %arrayidx, align 4
633 for.inc: ; preds = %for.body, %if.then
634 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
635 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
636 %exitcond = icmp eq i32 %lftr.wideiv, %n
637 br i1 %exitcond, label %for.end, label %for.body
639 for.end: ; preds = %for.inc, %entry
643 ; Ensure that (c == null && other_cond) does not automatically mean that c is
644 ; non-null in false branch. So the condition ((c == null && other_cond) == false)
645 ; is not sufficient to conclude that c != null.
646 define void @test16(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 {
648 ; CHECK-LABEL: @test16
650 ; CHECK: load i32, i32* %c, align 4
653 %not_null = icmp eq i32* %c, null
654 %dummy_and = and i1 %not_null, %dummy_cond
655 br i1 %dummy_and, label %for.end, label %not.null
658 %cmp11 = icmp sgt i32 %n, 0
659 br i1 %cmp11, label %for.body, label %for.end
661 for.body: ; preds = %not.null, %for.inc
662 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
663 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
664 %0 = load i32, i32* %arrayidx, align 4
665 %cmp1 = icmp sgt i32 %0, 0
666 br i1 %cmp1, label %if.then, label %for.inc
668 if.then: ; preds = %for.body
669 %1 = load i32, i32* %c, align 4
670 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
671 %2 = load i32, i32* %arrayidx3, align 4
672 %mul = mul nsw i32 %2, %1
673 store i32 %mul, i32* %arrayidx, align 4
676 for.inc: ; preds = %for.body, %if.then
677 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
678 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
679 %exitcond = icmp eq i32 %lftr.wideiv, %n
680 br i1 %exitcond, label %for.end, label %for.body
682 for.end: ; preds = %for.inc, %entry, %not.null
686 ; Ensure that (c == null && other_cond) does not automatically mean that c is
687 ; non-null in false branch. So the condition ((c == null && other_cond) == false)
688 ; is not sufficient to conclude that c != null.
689 define void @test17(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 {
691 ; CHECK-LABEL: @test17
693 ; CHECK: load i32, i32* %c, align 4
696 %not_null = icmp eq i32* %c, null
697 %dummy_and = and i1 %not_null, %dummy_cond
698 call void(i1, ...) @llvm.experimental.guard(i1 %dummy_and) [ "deopt"() ]
699 %cmp11 = icmp sgt i32 %n, 0
700 br i1 %cmp11, label %for.end, label %for.body
702 for.body: ; preds = %entry, %for.inc
703 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
704 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
705 %0 = load i32, i32* %arrayidx, align 4
706 %cmp1 = icmp sgt i32 %0, 0
707 br i1 %cmp1, label %if.then, label %for.inc
709 if.then: ; preds = %for.body
710 %1 = load i32, i32* %c, align 4
711 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
712 %2 = load i32, i32* %arrayidx3, align 4
713 %mul = mul nsw i32 %2, %1
714 store i32 %mul, i32* %arrayidx, align 4
717 for.inc: ; preds = %for.body, %if.then
718 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
719 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
720 %exitcond = icmp eq i32 %lftr.wideiv, %n
721 br i1 %exitcond, label %for.end, label %for.body
723 for.end: ; preds = %for.inc, %entry
727 attributes #0 = { nounwind uwtable }