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