[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / LICM / hoist-deref-load.ll
blobaacff88ac12ec78d6104570be5222be2312499af
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(simplify-cfg,licm)' -enable-mssa-loop-dependency=true -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)
12 ;     if (a[i] > 0)
13 ;       a[i] = c*b[i];
14 ; }
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.
18 ; CHECK-LABEL: @test1
19 ; CHECK: load i32, i32* %c, align 4
20 ; CHECK: for.body:
22 define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 {
23 entry:
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
40   br label %for.inc
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
49   ret void
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.
55 ; CHECK-LABEL: @test2
56 ; CHECK: if.then:
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 {
60 entry:
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
77   br label %for.inc
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
86   ret void
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)
92 ;     if (a[i] > 0)
93 ;       a[i] = c[2]*b[i];
94 ; }
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.
98 ; CHECK-LABEL: @test3
99 ; CHECK: load i32, i32* %c2, align 4
100 ; CHECK: for.body:
102 define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 {
103 entry:
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
121   br label %for.inc
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
130   ret void
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
137 ; CHECK: if.then:
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 {
141 entry:
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
159   br label %for.inc
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
168   ret void
171 ; This test represents the following function:
172 ; void test1(int * __restrict__ a, int *b, int &c, int n) {
173 ;   if (c != null)
174 ;     for (int i = 0; i < n; ++i)
175 ;       if (a[i] > 0)
176 ;         a[i] = c*b[i];
177 ; }
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
180 ; check on %c.
182 ; CHECK-LABEL: @test5
183 ; CHECK: load i32, i32* %c, align 4
184 ; CHECK: for.body:
186 define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
187 entry:
188   %not_null = icmp ne i32* %c, null
189   br i1 %not_null, label %not.null, label %for.end
191 not.null:
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
208   br label %for.inc
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
217   ret void
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
224 ; not a branch. 
226 ; CHECK-LABEL: @test6
227 ; CHECK: if.then:
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 {
231 entry:
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
249   br label %for.inc
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
258   ret i1 %not_null
261 ; This test represents the following function:
262 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
263 ;   c = *cptr;
264 ;   for (int i = 0; i < n; ++i)
265 ;     if (a[i] > 0)
266 ;       a[i] = (*c)*b[i];
267 ; }
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
273 ; CHECK: for.body:
275 define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
276 entry:
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
294   br label %for.inc
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
303   ret void
306 ; This test represents the following function:
307 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
308 ;   c = *cptr;
309 ;   if (c != null)
310 ;     for (int i = 0; i < n; ++i)
311 ;       if (a[i] > 0)
312 ;         a[i] = (*c)*b[i];
313 ; }
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
320 ; CHECK: for.body:
322 define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
323 entry:
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
328 not.null:
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
345   br label %for.inc
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
354   ret void
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
361 ; CHECK: if.then:
362 ; CHECK: load i32, i32* %c, align 4
364 define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
365 entry:
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
383   br label %for.inc
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
392   ret void
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
405 ; CHECK: if.then:
406 ; CHECK: load i32, i32* %c, align 4
408 define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
409 entry:
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
427   br label %for.inc
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
436   ret void
439 define void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
440 ; CHECK-LABEL: @test11(
441 entry:
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
464   br label %for.inc
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
473   ret void
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(
482 entry:
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
506   br label %for.inc
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
515   ret void
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(
523 entry:
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
540 ; CHECK: if.then:
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
548   br label %for.inc
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"() ]
558   ret void
561 ; Check that branch by condition "null check AND something" allows to hoist the
562 ; load.
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
567 ; CHECK: for.body:
569 entry:
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
574 not.null:
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
591   br label %for.inc
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
600   ret void
603 ; Check that guard by condition "null check AND something" allows to hoist the
604 ; load.
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
609 ; CHECK: for.body:
611 entry:
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
631   br label %for.inc
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
640   ret void
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
649 ; CHECK: for.body:
650 ; CHECK: load i32, i32* %c, align 4
652 entry:
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
657 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
674   br label %for.inc
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
683   ret void
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
692 ; CHECK: for.body:
693 ; CHECK: load i32, i32* %c, align 4
695 entry:
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
715   br label %for.inc
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
724   ret void
727 attributes #0 = { nounwind uwtable }
728 !0 = !{i64 4}