• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -S -basicaa -licm < %s | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='loop-simplify,require<aa>,require<targetir>,require<scalar-evolution>,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-unknown-linux-gnu"
5
6; This test represents the following function:
7; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) {
8;   for (int i = 0; i < n; ++i)
9;     if (a[i] > 0)
10;       a[i] = c*b[i];
11; }
12; and we want to hoist the load of %c out of the loop. This can be done only
13; because the dereferenceable attribute is on %c.
14
15; CHECK-LABEL: @test1
16; CHECK: load i32, i32* %c, align 4
17; CHECK: for.body:
18
19define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 {
20entry:
21  %cmp11 = icmp sgt i32 %n, 0
22  br i1 %cmp11, label %for.body, label %for.end
23
24for.body:                                         ; preds = %entry, %for.inc
25  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
26  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
27  %0 = load i32, i32* %arrayidx, align 4
28  %cmp1 = icmp sgt i32 %0, 0
29  br i1 %cmp1, label %if.then, label %for.inc
30
31if.then:                                          ; preds = %for.body
32  %1 = load i32, i32* %c, align 4
33  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
34  %2 = load i32, i32* %arrayidx3, align 4
35  %mul = mul nsw i32 %2, %1
36  store i32 %mul, i32* %arrayidx, align 4
37  br label %for.inc
38
39for.inc:                                          ; preds = %for.body, %if.then
40  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
41  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
42  %exitcond = icmp eq i32 %lftr.wideiv, %n
43  br i1 %exitcond, label %for.end, label %for.body
44
45for.end:                                          ; preds = %for.inc, %entry
46  ret void
47}
48
49; This is the same as @test1, but without the dereferenceable attribute on %c.
50; Without this attribute, we should not hoist the load of %c.
51
52; CHECK-LABEL: @test2
53; CHECK: if.then:
54; CHECK: load i32, i32* %c, align 4
55
56define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 {
57entry:
58  %cmp11 = icmp sgt i32 %n, 0
59  br i1 %cmp11, label %for.body, label %for.end
60
61for.body:                                         ; preds = %entry, %for.inc
62  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
63  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
64  %0 = load i32, i32* %arrayidx, align 4
65  %cmp1 = icmp sgt i32 %0, 0
66  br i1 %cmp1, label %if.then, label %for.inc
67
68if.then:                                          ; preds = %for.body
69  %1 = load i32, i32* %c, align 4
70  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
71  %2 = load i32, i32* %arrayidx3, align 4
72  %mul = mul nsw i32 %2, %1
73  store i32 %mul, i32* %arrayidx, align 4
74  br label %for.inc
75
76for.inc:                                          ; preds = %for.body, %if.then
77  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
78  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
79  %exitcond = icmp eq i32 %lftr.wideiv, %n
80  br i1 %exitcond, label %for.end, label %for.body
81
82for.end:                                          ; preds = %for.inc, %entry
83  ret void
84}
85
86; This test represents the following function:
87; void test3(int * restrict a, int * restrict b, int c[static 3], int n) {
88;   for (int i = 0; i < n; ++i)
89;     if (a[i] > 0)
90;       a[i] = c[2]*b[i];
91; }
92; and we want to hoist the load of c[2] out of the loop. This can be done only
93; because the dereferenceable attribute is on %c.
94
95; CHECK-LABEL: @test3
96; CHECK: load i32, i32* %c2, align 4
97; CHECK: for.body:
98
99define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 {
100entry:
101  %cmp11 = icmp sgt i32 %n, 0
102  br i1 %cmp11, label %for.body, label %for.end
103
104for.body:                                         ; preds = %entry, %for.inc
105  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
106  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
107  %0 = load i32, i32* %arrayidx, align 4
108  %cmp1 = icmp sgt i32 %0, 0
109  br i1 %cmp1, label %if.then, label %for.inc
110
111if.then:                                          ; preds = %for.body
112  %c2 = getelementptr inbounds i32, i32* %c, i64 2
113  %1 = load i32, i32* %c2, align 4
114  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
115  %2 = load i32, i32* %arrayidx3, align 4
116  %mul = mul nsw i32 %2, %1
117  store i32 %mul, i32* %arrayidx, align 4
118  br label %for.inc
119
120for.inc:                                          ; preds = %for.body, %if.then
121  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
122  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
123  %exitcond = icmp eq i32 %lftr.wideiv, %n
124  br i1 %exitcond, label %for.end, label %for.body
125
126for.end:                                          ; preds = %for.inc, %entry
127  ret void
128}
129
130; This is the same as @test3, but with a dereferenceable attribute on %c with a
131; size too small to cover c[2] (and so we should not hoist it).
132
133; CHECK-LABEL: @test4
134; CHECK: if.then:
135; CHECK: load i32, i32* %c2, align 4
136
137define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 {
138entry:
139  %cmp11 = icmp sgt i32 %n, 0
140  br i1 %cmp11, label %for.body, label %for.end
141
142for.body:                                         ; preds = %entry, %for.inc
143  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
144  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
145  %0 = load i32, i32* %arrayidx, align 4
146  %cmp1 = icmp sgt i32 %0, 0
147  br i1 %cmp1, label %if.then, label %for.inc
148
149if.then:                                          ; preds = %for.body
150  %c2 = getelementptr inbounds i32, i32* %c, i64 2
151  %1 = load i32, i32* %c2, align 4
152  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
153  %2 = load i32, i32* %arrayidx3, align 4
154  %mul = mul nsw i32 %2, %1
155  store i32 %mul, i32* %arrayidx, align 4
156  br label %for.inc
157
158for.inc:                                          ; preds = %for.body, %if.then
159  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
160  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
161  %exitcond = icmp eq i32 %lftr.wideiv, %n
162  br i1 %exitcond, label %for.end, label %for.body
163
164for.end:                                          ; preds = %for.inc, %entry
165  ret void
166}
167
168; This test represents the following function:
169; void test1(int * __restrict__ a, int *b, int &c, int n) {
170;   if (c != null)
171;     for (int i = 0; i < n; ++i)
172;       if (a[i] > 0)
173;         a[i] = c*b[i];
174; }
175; and we want to hoist the load of %c out of the loop. This can be done only
176; because the dereferenceable_or_null attribute is on %c and there is a null
177; check on %c.
178
179; CHECK-LABEL: @test5
180; CHECK: load i32, i32* %c, align 4
181; CHECK: for.body:
182
183define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
184entry:
185  %not_null = icmp ne i32* %c, null
186  br i1 %not_null, label %not.null, label %for.end
187
188not.null:
189  %cmp11 = icmp sgt i32 %n, 0
190  br i1 %cmp11, label %for.body, label %for.end
191
192for.body:                                         ; preds = %not.null, %for.inc
193  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
194  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
195  %0 = load i32, i32* %arrayidx, align 4
196  %cmp1 = icmp sgt i32 %0, 0
197  br i1 %cmp1, label %if.then, label %for.inc
198
199if.then:                                          ; preds = %for.body
200  %1 = load i32, i32* %c, align 4
201  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
202  %2 = load i32, i32* %arrayidx3, align 4
203  %mul = mul nsw i32 %2, %1
204  store i32 %mul, i32* %arrayidx, align 4
205  br label %for.inc
206
207for.inc:                                          ; preds = %for.body, %if.then
208  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
209  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
210  %exitcond = icmp eq i32 %lftr.wideiv, %n
211  br i1 %exitcond, label %for.end, label %for.body
212
213for.end:                                          ; preds = %for.inc, %entry, %not.null
214  ret void
215}
216
217; This is the same as @test5, but without the null check on %c.
218; Without this check, we should not hoist the load of %c.
219
220; This test case has an icmp on c but the use of this comparison is
221; not a branch.
222
223; CHECK-LABEL: @test6
224; CHECK: if.then:
225; CHECK: load i32, i32* %c, align 4
226
227define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
228entry:
229  %not_null = icmp ne i32* %c, null
230  %cmp11 = icmp sgt i32 %n, 0
231  br i1 %cmp11, label %for.body, label %for.end
232
233for.body:                                         ; preds = %entry, %for.inc
234  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
235  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
236  %0 = load i32, i32* %arrayidx, align 4
237  %cmp1 = icmp sgt i32 %0, 0
238  br i1 %cmp1, label %if.then, label %for.inc
239
240if.then:                                          ; preds = %for.body
241  %1 = load i32, i32* %c, align 4
242  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
243  %2 = load i32, i32* %arrayidx3, align 4
244  %mul = mul nsw i32 %2, %1
245  store i32 %mul, i32* %arrayidx, align 4
246  br label %for.inc
247
248for.inc:                                          ; preds = %for.body, %if.then
249  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
250  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
251  %exitcond = icmp eq i32 %lftr.wideiv, %n
252  br i1 %exitcond, label %for.end, label %for.body
253
254for.end:                                          ; preds = %for.inc, %entry
255  ret i1 %not_null
256}
257
258; This test represents the following function:
259; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
260;   c = *cptr;
261;   for (int i = 0; i < n; ++i)
262;     if (a[i] > 0)
263;       a[i] = (*c)*b[i];
264; }
265; and we want to hoist the load of %c out of the loop. This can be done only
266; because the dereferenceable meatdata on the c = *cptr load.
267
268; CHECK-LABEL: @test7
269; CHECK: load i32, i32* %c, align 4
270; CHECK: for.body:
271
272define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
273entry:
274  %c = load i32*, i32** %cptr, !dereferenceable !0
275  %cmp11 = icmp sgt i32 %n, 0
276  br i1 %cmp11, label %for.body, label %for.end
277
278for.body:                                         ; preds = %entry, %for.inc
279  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
280  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
281  %0 = load i32, i32* %arrayidx, align 4
282  %cmp1 = icmp sgt i32 %0, 0
283  br i1 %cmp1, label %if.then, label %for.inc
284
285if.then:                                          ; preds = %for.body
286  %1 = load i32, i32* %c, align 4
287  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
288  %2 = load i32, i32* %arrayidx3, align 4
289  %mul = mul nsw i32 %2, %1
290  store i32 %mul, i32* %arrayidx, align 4
291  br label %for.inc
292
293for.inc:                                          ; preds = %for.body, %if.then
294  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
295  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
296  %exitcond = icmp eq i32 %lftr.wideiv, %n
297  br i1 %exitcond, label %for.end, label %for.body
298
299for.end:                                          ; preds = %for.inc, %entry
300  ret void
301}
302
303; This test represents the following function:
304; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
305;   c = *cptr;
306;   if (c != null)
307;     for (int i = 0; i < n; ++i)
308;       if (a[i] > 0)
309;         a[i] = (*c)*b[i];
310; }
311; and we want to hoist the load of %c out of the loop. This can be done only
312; because the dereferenceable_or_null meatdata on the c = *cptr load and there
313; is a null check on %c.
314
315; CHECK-LABEL: @test8
316; CHECK: load i32, i32* %c, align 4
317; CHECK: for.body:
318
319define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
320entry:
321  %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
322  %not_null = icmp ne i32* %c, null
323  br i1 %not_null, label %not.null, label %for.end
324
325not.null:
326  %cmp11 = icmp sgt i32 %n, 0
327  br i1 %cmp11, label %for.body, label %for.end
328
329for.body:                                         ; preds = %not.null, %for.inc
330  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
331  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
332  %0 = load i32, i32* %arrayidx, align 4
333  %cmp1 = icmp sgt i32 %0, 0
334  br i1 %cmp1, label %if.then, label %for.inc
335
336if.then:                                          ; preds = %for.body
337  %1 = load i32, i32* %c, align 4
338  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
339  %2 = load i32, i32* %arrayidx3, align 4
340  %mul = mul nsw i32 %2, %1
341  store i32 %mul, i32* %arrayidx, align 4
342  br label %for.inc
343
344for.inc:                                          ; preds = %for.body, %if.then
345  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
346  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
347  %exitcond = icmp eq i32 %lftr.wideiv, %n
348  br i1 %exitcond, label %for.end, label %for.body
349
350for.end:                                          ; preds = %for.inc, %entry, %not.null
351  ret void
352}
353
354; This is the same as @test8, but without the null check on %c.
355; Without this check, we should not hoist the load of %c.
356
357; CHECK-LABEL: @test9
358; CHECK: if.then:
359; CHECK: load i32, i32* %c, align 4
360
361define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
362entry:
363  %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
364  %cmp11 = icmp sgt i32 %n, 0
365  br i1 %cmp11, label %for.body, label %for.end
366
367for.body:                                         ; preds = %entry, %for.inc
368  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
369  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
370  %0 = load i32, i32* %arrayidx, align 4
371  %cmp1 = icmp sgt i32 %0, 0
372  br i1 %cmp1, label %if.then, label %for.inc
373
374if.then:                                          ; preds = %for.body
375  %1 = load i32, i32* %c, align 4
376  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
377  %2 = load i32, i32* %arrayidx3, align 4
378  %mul = mul nsw i32 %2, %1
379  store i32 %mul, i32* %arrayidx, align 4
380  br label %for.inc
381
382for.inc:                                          ; preds = %for.body, %if.then
383  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
384  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
385  %exitcond = icmp eq i32 %lftr.wideiv, %n
386  br i1 %exitcond, label %for.end, label %for.body
387
388for.end:                                          ; preds = %for.inc, %entry
389  ret void
390}
391
392; In this test we should be able to only hoist load from %cptr. We can't hoist
393; load from %c because it's dereferenceability can depend on %cmp1 condition.
394; By moving it out of the loop we break this dependency and can not rely
395; on the dereferenceability anymore.
396; In other words this test checks that we strip dereferenceability  metadata
397; after hoisting an instruction.
398
399; CHECK-LABEL: @test10
400; CHECK: %c = load i32*, i32** %cptr
401; CHECK-NOT: dereferenceable
402; CHECK: if.then:
403; CHECK: load i32, i32* %c, align 4
404
405define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
406entry:
407  %cmp11 = icmp sgt i32 %n, 0
408  br i1 %cmp11, label %for.body, label %for.end
409
410for.body:                                         ; preds = %entry, %for.inc
411  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
412  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
413  %0 = load i32, i32* %arrayidx, align 4
414  %cmp1 = icmp sgt i32 %0, 0
415  br i1 %cmp1, label %if.then, label %for.inc
416
417if.then:                                          ; preds = %for.body
418  %c = load i32*, i32** %cptr, !dereferenceable !0
419  %1 = load i32, i32* %c, align 4
420  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
421  %2 = load i32, i32* %arrayidx3, align 4
422  %mul = mul nsw i32 %2, %1
423  store i32 %mul, i32* %arrayidx, align 4
424  br label %for.inc
425
426for.inc:                                          ; preds = %for.body, %if.then
427  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
428  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
429  %exitcond = icmp eq i32 %lftr.wideiv, %n
430  br i1 %exitcond, label %for.end, label %for.body
431
432for.end:                                          ; preds = %for.inc, %entry
433  ret void
434}
435
436define void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
437; CHECK-LABEL: @test11(
438entry:
439  %cmp11 = icmp sgt i32 %n, 0
440  br i1 %cmp11, label %for.body, label %for.end
441
442; CHECK: for.body.preheader:
443; CHECK:  %c = load i32*, i32** %cptr, !dereferenceable !0
444; CHECK:  %d = load i32, i32* %c, align 4
445
446
447for.body:                                         ; preds = %entry, %for.inc
448  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
449  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
450  %0 = load i32, i32* %arrayidx, align 4
451  %cmp1 = icmp sgt i32 %0, 0
452  %c = load i32*, i32** %cptr, !dereferenceable !0
453  br i1 %cmp1, label %if.then, label %for.inc
454
455if.then:                                          ; preds = %for.body
456  %d = load i32, i32* %c, align 4
457  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
458  %e = load i32, i32* %arrayidx3, align 4
459  %mul = mul nsw i32 %e, %d
460  store i32 %mul, i32* %arrayidx, align 4
461  br label %for.inc
462
463for.inc:                                          ; preds = %for.body, %if.then
464  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
465  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
466  %exitcond = icmp eq i32 %lftr.wideiv, %n
467  br i1 %exitcond, label %for.end, label %for.body
468
469for.end:                                          ; preds = %for.inc, %entry
470  ret void
471}
472
473declare void @llvm.experimental.guard(i1, ...)
474
475define void @test12(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
476; Prove non-null ness of %c via a guard, not a branch.
477
478; CHECK-LABEL: @test12(
479entry:
480  %not_null = icmp ne i32* %c, null
481  call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]
482  %cmp11 = icmp sgt i32 %n, 0
483  br i1 %cmp11, label %for.body, label %for.end
484
485; CHECK: for.body.preheader:
486; CHECK-NEXT:  [[VAL:%[^ ]]] = load i32, i32* %c, align 4
487; CHECK-NEXT:  br label %for.body
488
489
490for.body:                                         ; preds = %entry, %for.inc
491  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
492  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
493  %0 = load i32, i32* %arrayidx, align 4
494  %cmp1 = icmp sgt i32 %0, 0
495  br i1 %cmp1, label %if.then, label %for.inc
496
497if.then:                                          ; preds = %for.body
498  %1 = load i32, i32* %c, align 4
499  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
500  %2 = load i32, i32* %arrayidx3, align 4
501  %mul = mul nsw i32 %2, %1
502  store i32 %mul, i32* %arrayidx, align 4
503  br label %for.inc
504
505for.inc:                                          ; preds = %for.body, %if.then
506  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
507  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
508  %exitcond = icmp eq i32 %lftr.wideiv, %n
509  br i1 %exitcond, label %for.end, label %for.body
510
511for.end:                                          ; preds = %for.inc, %entry, %entry
512  ret void
513}
514
515define void @test13(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
516; Like @test12, but has a post-dominating guard, which cannot be used
517; to prove %c is nonnull at the point of the load.
518
519; CHECK-LABEL: @test13(
520entry:
521  %not_null = icmp ne i32* %c, null
522  %cmp11 = icmp sgt i32 %n, 0
523  br i1 %cmp11, label %for.body, label %for.end
524
525; CHECK: for.body.preheader:
526; CHECK-NOT:  load i32, i32* %c
527; CHECK:  br label %for.body
528
529for.body:                                         ; preds = %entry, %for.inc
530  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
531  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
532  %0 = load i32, i32* %arrayidx, align 4
533  %cmp1 = icmp sgt i32 %0, 0
534  br i1 %cmp1, label %if.then, label %for.inc
535
536if.then:                                          ; preds = %for.body
537; CHECK: if.then:
538; CHECK:  load i32, i32* %c
539; CHECK:  br label %for.inc
540  %1 = load i32, i32* %c, align 4
541  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
542  %2 = load i32, i32* %arrayidx3, align 4
543  %mul = mul nsw i32 %2, %1
544  store i32 %mul, i32* %arrayidx, align 4
545  br label %for.inc
546
547for.inc:                                          ; preds = %for.body, %if.then
548  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
549  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
550  %exitcond = icmp eq i32 %lftr.wideiv, %n
551  br i1 %exitcond, label %for.end, label %for.body
552
553for.end:                                          ; preds = %for.inc, %entry, %entry
554  call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]
555  ret void
556}
557
558attributes #0 = { nounwind uwtable }
559!0 = !{i64 4}
560