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