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* %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* %a, i64 %indvars.iv
26  %0 = load 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* %c, align 4
32  %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv
33  %2 = load 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* %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* %a, i64 %indvars.iv
63  %0 = load 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* %c, align 4
69  %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv
70  %2 = load 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* %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* %a, i64 %indvars.iv
106  %0 = load 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* %c, i64 2
112  %1 = load i32* %c2, align 4
113  %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv
114  %2 = load 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* %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* %a, i64 %indvars.iv
144  %0 = load 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* %c, i64 2
150  %1 = load i32* %c2, align 4
151  %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv
152  %2 = load 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
167attributes #0 = { nounwind uwtable }
168
169