1; RUN: opt -S -basicaa -licm < %s | FileCheck %s
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3target triple = "x86_64-unknown-linux-gnu"
4
5; This test represents the following function:
6; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) {
7;   for (int i = 0; i < n; ++i)
8;     if (a[i] > 0)
9;       a[i] = c*b[i];
10; }
11; and we want to hoist the load of %c out of the loop. This can be done only
12; because the dereferenceable attribute is on %c.
13
14; CHECK-LABEL: @test1
15; CHECK: load i32, i32* %c, align 4
16; CHECK: for.body:
17
18define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 {
19entry:
20  %cmp11 = icmp sgt i32 %n, 0
21  br i1 %cmp11, label %for.body, label %for.end
22
23for.body:                                         ; preds = %entry, %for.inc
24  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
25  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
26  %0 = load i32, i32* %arrayidx, align 4
27  %cmp1 = icmp sgt i32 %0, 0
28  br i1 %cmp1, label %if.then, label %for.inc
29
30if.then:                                          ; preds = %for.body
31  %1 = load i32, i32* %c, align 4
32  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
33  %2 = load i32, i32* %arrayidx3, align 4
34  %mul = mul nsw i32 %2, %1
35  store i32 %mul, i32* %arrayidx, align 4
36  br label %for.inc
37
38for.inc:                                          ; preds = %for.body, %if.then
39  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
40  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
41  %exitcond = icmp eq i32 %lftr.wideiv, %n
42  br i1 %exitcond, label %for.end, label %for.body
43
44for.end:                                          ; preds = %for.inc, %entry
45  ret void
46}
47
48; This is the same as @test1, but without the dereferenceable attribute on %c.
49; Without this attribute, we should not hoist the load of %c.
50
51; CHECK-LABEL: @test2
52; CHECK: if.then:
53; CHECK: load i32, i32* %c, align 4
54
55define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 {
56entry:
57  %cmp11 = icmp sgt i32 %n, 0
58  br i1 %cmp11, label %for.body, label %for.end
59
60for.body:                                         ; preds = %entry, %for.inc
61  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
62  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
63  %0 = load i32, i32* %arrayidx, align 4
64  %cmp1 = icmp sgt i32 %0, 0
65  br i1 %cmp1, label %if.then, label %for.inc
66
67if.then:                                          ; preds = %for.body
68  %1 = load i32, i32* %c, align 4
69  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
70  %2 = load i32, i32* %arrayidx3, align 4
71  %mul = mul nsw i32 %2, %1
72  store i32 %mul, i32* %arrayidx, align 4
73  br label %for.inc
74
75for.inc:                                          ; preds = %for.body, %if.then
76  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
77  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
78  %exitcond = icmp eq i32 %lftr.wideiv, %n
79  br i1 %exitcond, label %for.end, label %for.body
80
81for.end:                                          ; preds = %for.inc, %entry
82  ret void
83}
84
85; This test represents the following function:
86; void test3(int * restrict a, int * restrict b, int c[static 3], int n) {
87;   for (int i = 0; i < n; ++i)
88;     if (a[i] > 0)
89;       a[i] = c[2]*b[i];
90; }
91; and we want to hoist the load of c[2] out of the loop. This can be done only
92; because the dereferenceable attribute is on %c.
93
94; CHECK-LABEL: @test3
95; CHECK: load i32, i32* %c2, align 4
96; CHECK: for.body:
97
98define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 {
99entry:
100  %cmp11 = icmp sgt i32 %n, 0
101  br i1 %cmp11, label %for.body, label %for.end
102
103for.body:                                         ; preds = %entry, %for.inc
104  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
105  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
106  %0 = load i32, i32* %arrayidx, align 4
107  %cmp1 = icmp sgt i32 %0, 0
108  br i1 %cmp1, label %if.then, label %for.inc
109
110if.then:                                          ; preds = %for.body
111  %c2 = getelementptr inbounds i32, i32* %c, i64 2
112  %1 = load i32, i32* %c2, align 4
113  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
114  %2 = load i32, i32* %arrayidx3, align 4
115  %mul = mul nsw i32 %2, %1
116  store i32 %mul, i32* %arrayidx, align 4
117  br label %for.inc
118
119for.inc:                                          ; preds = %for.body, %if.then
120  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
121  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
122  %exitcond = icmp eq i32 %lftr.wideiv, %n
123  br i1 %exitcond, label %for.end, label %for.body
124
125for.end:                                          ; preds = %for.inc, %entry
126  ret void
127}
128
129; This is the same as @test3, but with a dereferenceable attribute on %c with a
130; size too small to cover c[2] (and so we should not hoist it).
131
132; CHECK-LABEL: @test4
133; CHECK: if.then:
134; CHECK: load i32, i32* %c2, align 4
135
136define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 {
137entry:
138  %cmp11 = icmp sgt i32 %n, 0
139  br i1 %cmp11, label %for.body, label %for.end
140
141for.body:                                         ; preds = %entry, %for.inc
142  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
143  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
144  %0 = load i32, i32* %arrayidx, align 4
145  %cmp1 = icmp sgt i32 %0, 0
146  br i1 %cmp1, label %if.then, label %for.inc
147
148if.then:                                          ; preds = %for.body
149  %c2 = getelementptr inbounds i32, i32* %c, i64 2
150  %1 = load i32, i32* %c2, align 4
151  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
152  %2 = load i32, i32* %arrayidx3, align 4
153  %mul = mul nsw i32 %2, %1
154  store i32 %mul, i32* %arrayidx, align 4
155  br label %for.inc
156
157for.inc:                                          ; preds = %for.body, %if.then
158  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
159  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
160  %exitcond = icmp eq i32 %lftr.wideiv, %n
161  br i1 %exitcond, label %for.end, label %for.body
162
163for.end:                                          ; preds = %for.inc, %entry
164  ret void
165}
166
167; This test represents the following function:
168; void test1(int * __restrict__ a, int *b, int &c, int n) {
169;   if (c != null)
170;     for (int i = 0; i < n; ++i)
171;       if (a[i] > 0)
172;         a[i] = c*b[i];
173; }
174; and we want to hoist the load of %c out of the loop. This can be done only
175; because the dereferenceable_or_null attribute is on %c and there is a null
176; check on %c.
177
178; CHECK-LABEL: @test5
179; CHECK: load i32, i32* %c, align 4
180; CHECK: for.body:
181
182define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
183entry:
184  %not_null = icmp ne i32* %c, null
185  br i1 %not_null, label %not.null, label %for.end
186
187not.null:
188  %cmp11 = icmp sgt i32 %n, 0
189  br i1 %cmp11, label %for.body, label %for.end
190
191for.body:                                         ; preds = %not.null, %for.inc
192  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
193  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
194  %0 = load i32, i32* %arrayidx, align 4
195  %cmp1 = icmp sgt i32 %0, 0
196  br i1 %cmp1, label %if.then, label %for.inc
197
198if.then:                                          ; preds = %for.body
199  %1 = load i32, i32* %c, align 4
200  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
201  %2 = load i32, i32* %arrayidx3, align 4
202  %mul = mul nsw i32 %2, %1
203  store i32 %mul, i32* %arrayidx, align 4
204  br label %for.inc
205
206for.inc:                                          ; preds = %for.body, %if.then
207  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
208  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
209  %exitcond = icmp eq i32 %lftr.wideiv, %n
210  br i1 %exitcond, label %for.end, label %for.body
211
212for.end:                                          ; preds = %for.inc, %entry, %not.null
213  ret void
214}
215
216; This is the same as @test5, but without the null check on %c.
217; Without this check, we should not hoist the load of %c.
218
219; This test case has an icmp on c but the use of this comparison is
220; not a branch.
221
222; CHECK-LABEL: @test6
223; CHECK: if.then:
224; CHECK: load i32, i32* %c, align 4
225
226define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
227entry:
228  %not_null = icmp ne i32* %c, null
229  %cmp11 = icmp sgt i32 %n, 0
230  br i1 %cmp11, label %for.body, label %for.end
231
232for.body:                                         ; preds = %entry, %for.inc
233  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
234  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
235  %0 = load i32, i32* %arrayidx, align 4
236  %cmp1 = icmp sgt i32 %0, 0
237  br i1 %cmp1, label %if.then, label %for.inc
238
239if.then:                                          ; preds = %for.body
240  %1 = load i32, i32* %c, align 4
241  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
242  %2 = load i32, i32* %arrayidx3, align 4
243  %mul = mul nsw i32 %2, %1
244  store i32 %mul, i32* %arrayidx, align 4
245  br label %for.inc
246
247for.inc:                                          ; preds = %for.body, %if.then
248  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
249  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
250  %exitcond = icmp eq i32 %lftr.wideiv, %n
251  br i1 %exitcond, label %for.end, label %for.body
252
253for.end:                                          ; preds = %for.inc, %entry
254  ret i1 %not_null
255}
256
257; This test represents the following function:
258; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
259;   c = *cptr;
260;   for (int i = 0; i < n; ++i)
261;     if (a[i] > 0)
262;       a[i] = (*c)*b[i];
263; }
264; and we want to hoist the load of %c out of the loop. This can be done only
265; because the dereferenceable meatdata on the c = *cptr load.
266
267; CHECK-LABEL: @test7
268; CHECK: load i32, i32* %c, align 4
269; CHECK: for.body:
270
271define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
272entry:
273  %c = load i32*, i32** %cptr, !dereferenceable !0
274  %cmp11 = icmp sgt i32 %n, 0
275  br i1 %cmp11, label %for.body, label %for.end
276
277for.body:                                         ; preds = %entry, %for.inc
278  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
279  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
280  %0 = load i32, i32* %arrayidx, align 4
281  %cmp1 = icmp sgt i32 %0, 0
282  br i1 %cmp1, label %if.then, label %for.inc
283
284if.then:                                          ; preds = %for.body
285  %1 = load i32, i32* %c, align 4
286  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
287  %2 = load i32, i32* %arrayidx3, align 4
288  %mul = mul nsw i32 %2, %1
289  store i32 %mul, i32* %arrayidx, align 4
290  br label %for.inc
291
292for.inc:                                          ; preds = %for.body, %if.then
293  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
294  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
295  %exitcond = icmp eq i32 %lftr.wideiv, %n
296  br i1 %exitcond, label %for.end, label %for.body
297
298for.end:                                          ; preds = %for.inc, %entry
299  ret void
300}
301
302; This test represents the following function:
303; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
304;   c = *cptr;
305;   if (c != null)
306;     for (int i = 0; i < n; ++i)
307;       if (a[i] > 0)
308;         a[i] = (*c)*b[i];
309; }
310; and we want to hoist the load of %c out of the loop. This can be done only
311; because the dereferenceable_or_null meatdata on the c = *cptr load and there
312; is a null check on %c.
313
314; CHECK-LABEL: @test8
315; CHECK: load i32, i32* %c, align 4
316; CHECK: for.body:
317
318define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
319entry:
320  %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
321  %not_null = icmp ne i32* %c, null
322  br i1 %not_null, label %not.null, label %for.end
323
324not.null:
325  %cmp11 = icmp sgt i32 %n, 0
326  br i1 %cmp11, label %for.body, label %for.end
327
328for.body:                                         ; preds = %not.null, %for.inc
329  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
330  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
331  %0 = load i32, i32* %arrayidx, align 4
332  %cmp1 = icmp sgt i32 %0, 0
333  br i1 %cmp1, label %if.then, label %for.inc
334
335if.then:                                          ; preds = %for.body
336  %1 = load i32, i32* %c, align 4
337  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
338  %2 = load i32, i32* %arrayidx3, align 4
339  %mul = mul nsw i32 %2, %1
340  store i32 %mul, i32* %arrayidx, align 4
341  br label %for.inc
342
343for.inc:                                          ; preds = %for.body, %if.then
344  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
345  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
346  %exitcond = icmp eq i32 %lftr.wideiv, %n
347  br i1 %exitcond, label %for.end, label %for.body
348
349for.end:                                          ; preds = %for.inc, %entry, %not.null
350  ret void
351}
352
353; This is the same as @test8, but without the null check on %c.
354; Without this check, we should not hoist the load of %c.
355
356; CHECK-LABEL: @test9
357; CHECK: if.then:
358; CHECK: load i32, i32* %c, align 4
359
360define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
361entry:
362  %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
363  %cmp11 = icmp sgt i32 %n, 0
364  br i1 %cmp11, label %for.body, label %for.end
365
366for.body:                                         ; preds = %entry, %for.inc
367  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
368  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
369  %0 = load i32, i32* %arrayidx, align 4
370  %cmp1 = icmp sgt i32 %0, 0
371  br i1 %cmp1, label %if.then, label %for.inc
372
373if.then:                                          ; preds = %for.body
374  %1 = load i32, i32* %c, align 4
375  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
376  %2 = load i32, i32* %arrayidx3, align 4
377  %mul = mul nsw i32 %2, %1
378  store i32 %mul, i32* %arrayidx, align 4
379  br label %for.inc
380
381for.inc:                                          ; preds = %for.body, %if.then
382  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
383  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
384  %exitcond = icmp eq i32 %lftr.wideiv, %n
385  br i1 %exitcond, label %for.end, label %for.body
386
387for.end:                                          ; preds = %for.inc, %entry
388  ret void
389}
390
391; In this test we should be able to only hoist load from %cptr. We can't hoist
392; load from %c because it's dereferenceability can depend on %cmp1 condition.
393; By moving it out of the loop we break this dependency and can not rely
394; on the dereferenceability anymore.
395; In other words this test checks that we strip dereferenceability  metadata
396; after hoisting an instruction.
397
398; CHECK-LABEL: @test10
399; CHECK: %c = load i32*, i32** %cptr
400; CHECK-NOT: dereferenceable
401; CHECK: if.then:
402; CHECK: load i32, i32* %c, align 4
403
404define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
405entry:
406  %cmp11 = icmp sgt i32 %n, 0
407  br i1 %cmp11, label %for.body, label %for.end
408
409for.body:                                         ; preds = %entry, %for.inc
410  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
411  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
412  %0 = load i32, i32* %arrayidx, align 4
413  %cmp1 = icmp sgt i32 %0, 0
414  br i1 %cmp1, label %if.then, label %for.inc
415
416if.then:                                          ; preds = %for.body
417  %c = load i32*, i32** %cptr, !dereferenceable !0
418  %1 = load i32, i32* %c, align 4
419  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
420  %2 = load i32, i32* %arrayidx3, align 4
421  %mul = mul nsw i32 %2, %1
422  store i32 %mul, i32* %arrayidx, align 4
423  br label %for.inc
424
425for.inc:                                          ; preds = %for.body, %if.then
426  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
427  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
428  %exitcond = icmp eq i32 %lftr.wideiv, %n
429  br i1 %exitcond, label %for.end, label %for.body
430
431for.end:                                          ; preds = %for.inc, %entry
432  ret void
433}
434
435attributes #0 = { nounwind uwtable }
436!0 = !{i64 4}
437