1 ; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
2 ; RUN: opt %loadPolly -basicaa -polly-function-scops -analyze < %s | FileCheck %s
4 ; ModuleID = 'scalar_to_array.ll'
5 target 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-n8:16:32:64"
7 @A = common global [1024 x float] zeroinitializer, align 8
9 ; Terminating loops without side-effects will be optimzied away, hence
10 ; detecting a scop would be pointless.
11 ; CHECK-NOT: Function: empty
12 ; Function Attrs: nounwind
13 define i32 @empty() #0 {
18 for.cond: ; preds = %for.inc, %entry
19 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
20 %exitcond = icmp ne i64 %indvar, 1024
21 br i1 %exitcond, label %for.body, label %return
23 for.body: ; preds = %for.cond
26 for.inc: ; preds = %for.body
27 %indvar.next = add i64 %indvar, 1
30 return: ; preds = %for.cond
35 ; CHECK-LABEL: Function: array_access
36 ; Function Attrs: nounwind
37 define i32 @array_access() #0 {
42 for.cond: ; preds = %for.inc, %entry
43 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
44 %exitcond = icmp ne i64 %indvar, 1024
45 br i1 %exitcond, label %for.body, label %return
47 for.body: ; preds = %for.cond
48 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
49 %float = uitofp i64 %indvar to float
50 store float %float, float* %arrayidx
52 ; CHECK: Stmt_for_body
53 ; CHECK-NOT: ReadAccess
54 ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
55 ; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
57 for.inc: ; preds = %for.body
58 %indvar.next = add i64 %indvar, 1
61 return: ; preds = %for.cond
66 ; Function Attrs: nounwind
67 ; CHECK-LABEL: Function: intra_scop_dep
68 define i32 @intra_scop_dep() #0 {
73 for.cond: ; preds = %for.inc, %entry
74 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
75 %exitcond = icmp ne i64 %indvar, 1024
76 br i1 %exitcond, label %for.body.a, label %return
78 for.body.a: ; preds = %for.cond
79 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
80 %scalar = load float, float* %arrayidx
82 ; CHECK: Stmt_for_body_a
83 ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
84 ; CHECK-NEXT: { Stmt_for_body_a[i0] -> MemRef_A[i0] };
85 ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
86 ; CHECK-NEXT: { Stmt_for_body_a[i0] -> MemRef_scalar[] };
88 for.body.b: ; preds = %for.body.a
89 %arrayidx2 = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
90 %float = uitofp i64 %indvar to float
91 %sum = fadd float %scalar, %float
92 store float %sum, float* %arrayidx2
94 ; CHECK: Stmt_for_body_b
95 ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
96 ; CHECK-NEXT: { Stmt_for_body_b[i0] -> MemRef_scalar[] };
97 ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
98 ; CHECK-NEXT: { Stmt_for_body_b[i0] -> MemRef_A[i0] };
100 for.inc: ; preds = %for.body.b
101 %indvar.next = add i64 %indvar, 1
104 return: ; preds = %for.cond
109 ; It is not possible to have a scop which accesses a scalar element that is
110 ; a global variable. All global variables are pointers containing possibly
111 ; a single element. Hence they do not need to be handled anyways.
112 ; Please note that this is still required when scalar to array rewritting is
115 ; CHECK-LABEL: Function: use_after_scop
116 ; Function Attrs: nounwind
117 define i32 @use_after_scop() #0 {
119 %scalar.s2a = alloca float
123 for.head: ; preds = %for.inc, %entry
124 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
127 for.body: ; preds = %for.head
128 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
129 %scalar = load float, float* %arrayidx
130 store float %scalar, float* %scalar.s2a
131 ; Escaped uses are still required to be rewritten to stack variable.
132 ; CHECK: Stmt_for_body
133 ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
134 ; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
135 ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
136 ; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_scalar_s2a[0] };
139 for.inc: ; preds = %for.body
140 %indvar.next = add i64 %indvar, 1
141 %exitcond = icmp ne i64 %indvar.next, 1024
142 br i1 %exitcond, label %for.head, label %for.after
144 for.after: ; preds = %for.inc
145 %scalar.loadoutside = load float, float* %scalar.s2a
147 %return_value = fptosi float %scalar.loadoutside to i32
150 return: ; preds = %for.after
151 ret i32 %return_value
154 ; We currently do not transform scalar references, that have only read accesses
155 ; in the scop. There are two reasons for this:
157 ; o We don't introduce additional memory references which may yield to compile
159 ; o For integer values, such a translation may block the use of scalar
160 ; evolution on those values.
162 ; CHECK-LABEL: Function: before_scop
163 ; Function Attrs: nounwind
164 define i32 @before_scop() #0 {
168 preheader: ; preds = %entry
169 %scalar = fadd float 4.000000e+00, 5.000000e+00
173 for.cond: ; preds = %for.inc, %preheader
174 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %preheader ]
175 %exitcond = icmp ne i64 %indvar, 1024
176 br i1 %exitcond, label %for.body, label %return
178 for.body: ; preds = %for.cond
179 %arrayidx = getelementptr [1024 x float], [1024 x float]* @A, i64 0, i64 %indvar
180 store float %scalar, float* %arrayidx
182 ; CHECK: Stmt_for_body
183 ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
184 ; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
186 for.inc: ; preds = %for.body
187 %indvar.next = add i64 %indvar, 1
190 return: ; preds = %for.cond
195 attributes #0 = { nounwind }