1; RUN: opt %loadPolly -disable-basicaa -polly-detect -analyze < %s | FileCheck %s
2
3
4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
5
6define void @base_pointer_in_condition(i64** noalias %A_ptr, i64 %N) nounwind {
7entry:
8  fence seq_cst
9  br label %pre
10
11pre:
12  %A = load i64*, i64** %A_ptr
13  br i1 true, label %for.i, label %then
14
15for.i:
16  %indvar = phi i64 [ 0, %pre ], [ %indvar.next, %for.i ]
17  %scevgep = getelementptr i64, i64* %A, i64 %indvar
18  store i64 %indvar, i64* %scevgep
19  %indvar.next = add nsw i64 %indvar, 1
20  %exitcond = icmp eq i64 %indvar.next, %N
21  br i1 %exitcond, label %then, label %for.i
22
23then:
24  br label %return
25
26return:
27  fence seq_cst
28  ret void
29}
30
31; CHECK-LABEL: base_pointer_in_condition
32; CHECK: Valid Region for Scop: pre => return
33
34define void @base_pointer_is_argument(float* %A, i64 %n) {
35entry:
36  br label %for.i
37
38for.i:
39  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
40  br label %S1
41
42S1:
43  %conv = sitofp i64 %indvar.i to float
44  %arrayidx5 = getelementptr float, float* %A, i64 %indvar.i
45  store float %conv, float* %arrayidx5, align 4
46  br label %for.i.inc
47
48for.i.inc:
49  %indvar.i.next = add i64 %indvar.i, 1
50  %exitcond.i = icmp ne i64 %indvar.i.next, %n
51  br i1 %exitcond.i, label %for.i, label %exit
52
53exit:
54  ret void
55}
56
57; CHECK-LABEL: base_pointer_is_argument
58; CHECK: Valid Region for Scop: for.i => exit
59
60define void @base_pointer_is_const_expr(i64 %n) {
61entry:
62  br label %for.i
63
64for.i:
65  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
66  br label %S1
67
68S1:
69  %conv = sitofp i64 %indvar.i to float
70  %arrayidx5 = getelementptr float, float* inttoptr (i64 100 to float*), i64 %indvar.i
71  store float %conv, float* %arrayidx5, align 4
72  br label %for.i.inc
73
74for.i.inc:
75  %indvar.i.next = add i64 %indvar.i, 1
76  %exitcond.i = icmp ne i64 %indvar.i.next, %n
77  br i1 %exitcond.i, label %for.i, label %exit
78
79exit:
80  ret void
81}
82
83; CHECK-LABEL: base_pointer_is_const_expr
84; CHECK-LABEL: Valid Region for Scop: for.i => exit
85
86@A = external global float
87
88define void @base_pointer_is_global(i64 %n) {
89entry:
90  br label %for.i
91
92for.i:
93  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
94  br label %S1
95
96S1:
97  %conv = sitofp i64 %indvar.i to float
98  %arrayidx5 = getelementptr float, float* @A, i64 %indvar.i
99  store float %conv, float* %arrayidx5, align 4
100  br label %for.i.inc
101
102for.i.inc:
103  %indvar.i.next = add i64 %indvar.i, 1
104  %exitcond.i = icmp ne i64 %indvar.i.next, %n
105  br i1 %exitcond.i, label %for.i, label %exit
106
107exit:
108  ret void
109}
110
111; CHECK-LABEL: base_pointer_is_global
112; CHECK: Valid Region for Scop: for.i => exit
113
114declare float *@foo()
115
116define void @base_pointer_is_inst_outside(i64 %n) {
117entry:
118  %A = call float *@foo()
119  br label %for.i
120
121for.i:
122  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
123  br label %S1
124
125S1:
126  %conv = sitofp i64 %indvar.i to float
127  %arrayidx5 = getelementptr float, float* %A, i64 %indvar.i
128  store float %conv, float* %arrayidx5, align 4
129  br label %for.i.inc
130
131for.i.inc:
132  %indvar.i.next = add i64 %indvar.i, 1
133  %exitcond.i = icmp ne i64 %indvar.i.next, %n
134  br i1 %exitcond.i, label %for.i, label %exit
135
136exit:
137  ret void
138}
139
140; CHECK-LABEL: base_pointer_is_inst_outside
141; CHECK: Valid Region for Scop: for.i => exit
142
143declare float* @getNextBasePtr(float*) readnone nounwind
144
145define void @base_pointer_is_phi_node(i64 %n, float* %A) {
146entry:
147  br label %for.i
148
149for.i:
150  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
151  %ptr = phi float* [ %ptr.next, %for.i.inc ], [ %A, %entry ]
152; To get a PHI node inside a SCoP that can not be analyzed but
153; for which the surrounding SCoP is normally still valid we use a function
154; without any side effects.
155  %ptr.next = call float* @getNextBasePtr(float* %ptr)
156  br label %S1
157
158S1:
159  %conv = sitofp i64 %indvar.i to float
160  %arrayidx5 = getelementptr float, float* %ptr, i64 %indvar.i
161  store float %conv, float* %arrayidx5, align 4
162  br label %for.i.inc
163
164for.i.inc:
165  %indvar.i.next = add i64 %indvar.i, 1
166  %exitcond.i = icmp ne i64 %indvar.i.next, %n
167  br i1 %exitcond.i, label %for.i, label %exit
168
169exit:
170  ret void
171}
172
173; CHECK-LABEL: base_pointer_is_phi_node
174; CHECK-NOT: Valid Region for Scop
175
176define void @base_pointer_is_inst_inside_invariant_1(i64 %n, float* %A) {
177entry:
178  br label %for.i
179
180for.i:
181  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
182; To get an instruction inside a region, we use a function without side
183; effects on which SCEV blocks, but for which it is still clear that the
184; return value remains invariant throughout the whole loop.
185  %ptr = call float* @getNextBasePtr(float* %A)
186  br label %S1
187
188S1:
189  %conv = sitofp i64 %indvar.i to float
190  %arrayidx5 = getelementptr float, float* %ptr, i64 %indvar.i
191  store float %conv, float* %arrayidx5, align 4
192  br label %for.i.inc
193
194for.i.inc:
195  %indvar.i.next = add i64 %indvar.i, 1
196  %exitcond.i = icmp ne i64 %indvar.i.next, %n
197  br i1 %exitcond.i, label %for.i, label %exit
198
199exit:
200  ret void
201}
202
203; CHECK-LABEL: base_pointer_is_inst_inside_invariant_1
204; CHECK: Valid Region for Scop: for.i => exit
205
206declare float* @getNextBasePtr2(float*) readnone nounwind
207
208define void @base_pointer_is_inst_inside_invariant_2(i64 %n, float* %A) {
209entry:
210  br label %for.i
211
212for.i:
213  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
214  %ptr = call float* @getNextBasePtr2(float* %A)
215  %ptr2 = call float* @getNextBasePtr(float* %ptr)
216  br label %S1
217
218S1:
219  %conv = sitofp i64 %indvar.i to float
220  %arrayidx5 = getelementptr float, float* %ptr2, i64 %indvar.i
221  store float %conv, float* %arrayidx5, align 4
222  br label %for.i.inc
223
224for.i.inc:
225  %indvar.i.next = add i64 %indvar.i, 1
226  %exitcond.i = icmp ne i64 %indvar.i.next, %n
227  br i1 %exitcond.i, label %for.i, label %exit
228
229exit:
230  ret void
231}
232
233; CHECK-LABEL: base_pointer_is_inst_inside_invariant_2
234; CHECK: Valid Region for Scop: for.i => exit
235
236declare float* @getNextBasePtr3(float*, i64) readnone nounwind
237
238define void @base_pointer_is_inst_inside_variant(i64 %n, float* %A) {
239entry:
240  br label %for.i
241
242for.i:
243  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
244  %ptr = call float* @getNextBasePtr3(float* %A, i64 %indvar.i)
245  %ptr2 = call float* @getNextBasePtr(float* %ptr)
246  br label %S1
247
248S1:
249  %conv = sitofp i64 %indvar.i to float
250  %arrayidx5 = getelementptr float, float* %ptr2, i64 %indvar.i
251  store float %conv, float* %arrayidx5, align 4
252  br label %for.i.inc
253
254for.i.inc:
255  %indvar.i.next = add i64 %indvar.i, 1
256  %exitcond.i = icmp ne i64 %indvar.i.next, %n
257  br i1 %exitcond.i, label %for.i, label %exit
258
259exit:
260  ret void
261}
262
263; CHECK: base_pointer_is_inst_inside_variant
264; CHECK-NOT: Valid Region for Scop
265
266define void @base_pointer_is_ptr2ptr(float** noalias %A, i64 %n) {
267entry:
268  br label %for.i
269
270for.i:
271  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
272  %arrayidx = getelementptr float*, float** %A, i64 %indvar.i
273  br label %for.j
274
275for.j:
276  %indvar.j = phi i64 [ 0, %for.i ], [ %indvar.j.next, %for.j ]
277  %conv = sitofp i64 %indvar.i to float
278  %basepointer = load float*, float** %arrayidx, align 8
279  %arrayidx5 = getelementptr float, float* %basepointer, i64 %indvar.j
280  store float %conv, float* %arrayidx5, align 4
281  %indvar.j.next = add i64 %indvar.j, 1
282  %exitcond.j = icmp ne i64 %indvar.j.next, %n
283  br i1 %exitcond.j, label %for.j, label %for.i.inc
284
285for.i.inc:
286  %indvar.i.next = add i64 %indvar.i, 1
287  %exitcond.i = icmp ne i64 %indvar.i.next, %n
288  br i1 %exitcond.i, label %for.i, label %exit
289
290exit:
291  ret void
292}
293
294; CHECK: base_pointer_is_ptr2ptr
295; CHECK: Valid Region for Scop: for.j => for.i.inc
296