1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
3 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
4 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
5 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
6 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -fopenmp-version=50 -DOMP5
7 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
8 
9 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
10 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
11 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
12 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck --check-prefix=TERM_DEBUG %s
13 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
14 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -fopenmp-version=50 -DOMP5
15 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
16 // expected-no-diagnostics
17  #ifndef HEADER
18  #define HEADER
19 
20 // CHECK: [[SS_TY:%.+]] = type { i32 }
21 
22 long long get_val() { return 0; }
23 double *g_ptr;
24 
25 // CHECK-LABEL: define {{.*void}} @{{.*}}simple{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
26 void simple(float *a, float *b, float *c, float *d) {
27 #ifdef OMP5
28   #pragma omp simd if (simd: true)
29 #else
30   #pragma omp simd
31 #endif
32   // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
33 
34 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
35 // CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], 6
36 // CHECK-NEXT: br i1 [[CMP]], label %[[SIMPLE_LOOP1_BODY:.+]], label %[[SIMPLE_LOOP1_END:[^,]+]]
37   for (int i = 3; i < 32; i += 5) {
38 // CHECK: [[SIMPLE_LOOP1_BODY]]:
39 // Start of body: calculate i from IV:
40 // CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
41 // CHECK: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 5
42 // CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 3, [[CALC_I_1]]
43 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]{{.*}}!llvm.access.group
44 // ... loop body ...
45 // End of body: store into a[i]:
46 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}{{.*}}!llvm.access.group
47     a[i] = b[i] * c[i] * d[i];
48 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
49 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
50 // CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
51 // br label %{{.+}}, !llvm.loop !{{.+}}
52   }
53 // CHECK: [[SIMPLE_LOOP1_END]]:
54 
55   long long k = get_val();
56 
57   #pragma omp simd linear(k : 3)
58 // CHECK: [[K0:%.+]] = call {{.*}}i64 @{{.*}}get_val
59 // CHECK-NEXT: store i64 [[K0]], i64* [[K_VAR:%[^,]+]]
60 // CHECK: store i32 0, i32* [[OMP_IV2:%[^,]+]]
61 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_VAR]]
62 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
63 
64 // CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
65 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV2]], 9
66 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP2_BODY:.+]], label %[[SIMPLE_LOOP2_END:[^,]+]]
67   for (int i = 10; i > 1; i--) {
68 // CHECK: [[SIMPLE_LOOP2_BODY]]:
69 // Start of body: calculate i from IV:
70 // CHECK: [[IV2_0:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
71 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
72 // CHECK-NEXT: [[IV2_1:%.+]] = mul nsw i32 [[IV2_0]], 1
73 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV2_1]]
74 // CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
75 //
76 // CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
77 // CHECK-NEXT: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
78 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV2_2]], 3
79 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
80 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
81 // Update of the privatized version of linear variable!
82 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
83     a[k]++;
84     k = k + 3;
85 // CHECK: [[IV2_2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.access.group
86 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV2_2]], 1
87 // CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.access.group
88 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP2_ID]]
89   }
90 // CHECK: [[SIMPLE_LOOP2_END]]:
91 //
92 // Update linear vars after loop, as the loop was operating on a private version.
93 // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]]
94 // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27
95 // CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[K_VAR]]
96 //
97 
98   int lin = 12;
99   #pragma omp simd linear(lin : get_val()), linear(g_ptr)
100 
101 // Init linear private var.
102 // CHECK: store i32 12, i32* [[LIN_VAR:%[^,]+]]
103 // CHECK: store i64 0, i64* [[OMP_IV3:%[^,]+]]
104 
105 // CHECK: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]]
106 // CHECK-NEXT: store i32 [[LIN_LOAD]], i32* [[LIN_START:%[^,]+]]
107 // Remember linear step.
108 // CHECK: [[CALL_VAL:%.+]] = invoke
109 // CHECK: store i64 [[CALL_VAL]], i64* [[LIN_STEP:%[^,]+]]
110 
111 // CHECK: [[GLIN_LOAD:%.+]] = load double*, double** [[GLIN_VAR:@[^,]+]]
112 // CHECK-NEXT: store double* [[GLIN_LOAD]], double** [[GLIN_START:%[^,]+]]
113 
114 // CHECK: [[IV3:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
115 // CHECK-NEXT: [[CMP3:%.+]] = icmp ult i64 [[IV3]], 4
116 // CHECK-NEXT: br i1 [[CMP3]], label %[[SIMPLE_LOOP3_BODY:.+]], label %[[SIMPLE_LOOP3_END:[^,]+]]
117   for (unsigned long long it = 2000; it >= 600; it-=400) {
118 // CHECK: [[SIMPLE_LOOP3_BODY]]:
119 // Start of body: calculate it from IV:
120 // CHECK: [[IV3_0:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
121 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul i64 [[IV3_0]], 400
122 // CHECK-NEXT: [[LC_IT_2:%.+]] = sub i64 2000, [[LC_IT_1]]
123 // CHECK-NEXT: store i64 [[LC_IT_2]], i64* {{.+}}, !llvm.access.group
124 //
125 // Linear start and step are used to calculate current value of the linear variable.
126 // CHECK: [[LINSTART:.+]] = load i32, i32* [[LIN_START]]{{.*}}!llvm.access.group
127 // CHECK: [[LINSTEP:.+]] = load i64, i64* [[LIN_STEP]]{{.*}}!llvm.access.group
128 // CHECK-NOT: store i32 {{.+}}, i32* [[LIN_VAR]],{{.*}}!llvm.access.group
129 // CHECK: [[GLINSTART:.+]] = load double*, double** [[GLIN_START]]{{.*}}!llvm.access.group
130 // CHECK-NEXT: [[IV3_1:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
131 // CHECK-NEXT: [[MUL:%.+]] = mul i64 [[IV3_1]], 1
132 // CHECK: [[GEP:%.+]] = getelementptr{{.*}}[[GLINSTART]]
133 // CHECK-NEXT: store double* [[GEP]], double** [[G_PTR_CUR:%[^,]+]]{{.*}}!llvm.access.group
134     *g_ptr++ = 0.0;
135 // CHECK: [[GEP_VAL:%.+]] = load double{{.*}}[[G_PTR_CUR]]{{.*}}!llvm.access.group
136 // CHECK: store double{{.*}}[[GEP_VAL]]{{.*}}!llvm.access.group
137     a[it + lin]++;
138 // CHECK: [[FLT_INC:%.+]] = fadd float
139 // CHECK-NEXT: store float [[FLT_INC]],{{.*}}!llvm.access.group
140 // CHECK: [[IV3_2:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.access.group
141 // CHECK-NEXT: [[ADD3_2:%.+]] = add i64 [[IV3_2]], 1
142 // CHECK-NEXT: store i64 [[ADD3_2]], i64* [[OMP_IV3]]{{.*}}!llvm.access.group
143   }
144 // CHECK: [[SIMPLE_LOOP3_END]]:
145 //
146 // Linear start and step are used to calculate final value of the linear variables.
147 // CHECK: [[LINSTART:.+]] = load i32, i32* [[LIN_START]]
148 // CHECK: [[LINSTEP:.+]] = load i64, i64* [[LIN_STEP]]
149 // CHECK: store i32 {{.+}}, i32* [[LIN_VAR]],
150 // CHECK: [[GLINSTART:.+]] = load double*, double** [[GLIN_START]]
151 // CHECK: store double* {{.*}}[[GLIN_VAR]]
152 
153   #pragma omp simd
154 // CHECK: store i32 0, i32* [[OMP_IV4:%[^,]+]]
155 
156 // CHECK: [[IV4:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.access.group
157 // CHECK-NEXT: [[CMP4:%.+]] = icmp slt i32 [[IV4]], 4
158 // CHECK-NEXT: br i1 [[CMP4]], label %[[SIMPLE_LOOP4_BODY:.+]], label %[[SIMPLE_LOOP4_END:[^,]+]]
159   for (short it = 6; it <= 20; it-=-4) {
160 // CHECK: [[SIMPLE_LOOP4_BODY]]:
161 // Start of body: calculate it from IV:
162 // CHECK: [[IV4_0:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.access.group
163 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i32 [[IV4_0]], 4
164 // CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i32 6, [[LC_IT_1]]
165 // CHECK-NEXT: [[LC_IT_3:%.+]] = trunc i32 [[LC_IT_2]] to i16
166 // CHECK-NEXT: store i16 [[LC_IT_3]], i16* {{.+}}, !llvm.access.group
167 
168 // CHECK: [[IV4_2:%.+]] = load i32, i32* [[OMP_IV4]]{{.*}}!llvm.access.group
169 // CHECK-NEXT: [[ADD4_2:%.+]] = add nsw i32 [[IV4_2]], 1
170 // CHECK-NEXT: store i32 [[ADD4_2]], i32* [[OMP_IV4]]{{.*}}!llvm.access.group
171   }
172 // CHECK: [[SIMPLE_LOOP4_END]]:
173 
174   #pragma omp simd
175 // CHECK: store i32 0, i32* [[OMP_IV5:%[^,]+]]
176 
177 // CHECK: [[IV5:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.access.group
178 // CHECK-NEXT: [[CMP5:%.+]] = icmp slt i32 [[IV5]], 26
179 // CHECK-NEXT: br i1 [[CMP5]], label %[[SIMPLE_LOOP5_BODY:.+]], label %[[SIMPLE_LOOP5_END:[^,]+]]
180   for (unsigned char it = 'z'; it >= 'a'; it+=-1) {
181 // CHECK: [[SIMPLE_LOOP5_BODY]]:
182 // Start of body: calculate it from IV:
183 // CHECK: [[IV5_0:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.access.group
184 // CHECK-NEXT: [[IV5_1:%.+]] = mul nsw i32 [[IV5_0]], 1
185 // CHECK-NEXT: [[LC_IT_1:%.+]] = sub nsw i32 122, [[IV5_1]]
186 // CHECK-NEXT: [[LC_IT_2:%.+]] = trunc i32 [[LC_IT_1]] to i8
187 // CHECK-NEXT: store i8 [[LC_IT_2]], i8* {{.+}}, !llvm.access.group
188 
189 // CHECK: [[IV5_2:%.+]] = load i32, i32* [[OMP_IV5]]{{.*}}!llvm.access.group
190 // CHECK-NEXT: [[ADD5_2:%.+]] = add nsw i32 [[IV5_2]], 1
191 // CHECK-NEXT: store i32 [[ADD5_2]], i32* [[OMP_IV5]]{{.*}}!llvm.access.group
192   }
193 // CHECK: [[SIMPLE_LOOP5_END]]:
194 
195 // CHECK-NOT: mul i32 %{{.+}}, 10
196   #pragma omp simd
197   for (unsigned i=100; i<10; i+=10) {
198   }
199 
200   int A;
201   // CHECK: store i32 -1, i32* [[A:%.+]],
202   A = -1;
203   #pragma omp simd lastprivate(A)
204 // CHECK: store i64 0, i64* [[OMP_IV7:%[^,]+]]
205 // CHECK: br label %[[SIMD_LOOP7_COND:[^,]+]]
206 // CHECK: [[SIMD_LOOP7_COND]]:
207 // CHECK-NEXT: [[IV7:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.access.group
208 // CHECK-NEXT: [[CMP7:%.+]] = icmp slt i64 [[IV7]], 7
209 // CHECK-NEXT: br i1 [[CMP7]], label %[[SIMPLE_LOOP7_BODY:.+]], label %[[SIMPLE_LOOP7_END:[^,]+]]
210   for (long long i = -10; i < 10; i += 3) {
211 // CHECK: [[SIMPLE_LOOP7_BODY]]:
212 // Start of body: calculate i from IV:
213 // CHECK: [[IV7_0:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.access.group
214 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV7_0]], 3
215 // CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
216 // CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.access.group
217 // CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.access.group
218 // CHECK-NEXT: [[CONV:%.+]] = trunc i64 [[LC_VAL]] to i32
219 // CHECK-NEXT: store i32 [[CONV]], i32* [[A_PRIV:%[^,]+]],{{.+}}!llvm.access.group
220     A = i;
221 // CHECK: [[IV7_2:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.access.group
222 // CHECK-NEXT: [[ADD7_2:%.+]] = add nsw i64 [[IV7_2]], 1
223 // CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.access.group
224   }
225 // CHECK: [[SIMPLE_LOOP7_END]]:
226 // CHECK-NEXT: store i64 11, i64*
227 // CHECK-NEXT: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]],
228 // CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* [[A]],
229   int R;
230   // CHECK: store i32 -1, i32* [[R:%[^,]+]],
231   R = -1;
232 // CHECK: store i64 0, i64* [[OMP_IV8:%[^,]+]],
233 // CHECK: store i32 1, i32* [[R_PRIV:%[^,]+]],
234 #ifdef OMP5
235   #pragma omp simd reduction(*:R) if(A)
236 #else
237   #pragma omp simd reduction(*:R)
238 #endif
239 // OMP50:      [[A_VAL:%.+]] = load i32, i32* [[A]],
240 // OMP50-NEXT: [[COND:%.+]] = icmp ne i32 [[A_VAL]], 0
241 // OMP50-NEXT: br i1 [[COND]], label {{%?}}[[THEN:[^,]+]], label {{%?}}[[ELSE:[^,]+]]
242 // OMP50:      [[THEN]]:
243 
244 // CHECK: br label %[[SIMD_LOOP8_COND:[^,]+]]
245 // CHECK: [[SIMD_LOOP8_COND]]:
246 // CHECK-NEXT: [[IV8:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
247 // CHECK-NEXT: [[CMP8:%.+]] = icmp slt i64 [[IV8]], 7
248 // CHECK-NEXT: br i1 [[CMP8]], label %[[SIMPLE_LOOP8_BODY:.+]], label %[[SIMPLE_LOOP8_END:[^,]+]]
249   for (long long i = -10; i < 10; i += 3) {
250 // CHECK: [[SIMPLE_LOOP8_BODY]]:
251 // Start of body: calculate i from IV:
252 // CHECK: [[IV8_0:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
253 // CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV8_0]], 3
254 // CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
255 // CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.access.group
256 // CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.access.group
257 // CHECK: store i32 %{{.+}}, i32* [[R_PRIV]],{{.+}}!llvm.access.group
258     R *= i;
259 // CHECK: [[IV8_2:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
260 // CHECK-NEXT: [[ADD8_2:%.+]] = add nsw i64 [[IV8_2]], 1
261 // CHECK-NEXT: store i64 [[ADD8_2]], i64* [[OMP_IV8]]{{.*}}!llvm.access.group
262   }
263 // CHECK: [[SIMPLE_LOOP8_END]]:
264 // OMP50: br label {{%?}}[[EXIT:[^,]+]]
265 // OMP50: br label %[[SIMD_LOOP8_COND:[^,]+]]
266 // OMP50: [[SIMD_LOOP8_COND]]:
267 // OMP50-NEXT: [[IV8:%.+]] = load i64, i64* [[OMP_IV8]],{{[^!]*}}
268 // OMP50-NEXT: [[CMP8:%.+]] = icmp slt i64 [[IV8]], 7
269 // OMP50-NEXT: br i1 [[CMP8]], label %[[SIMPLE_LOOP8_BODY:.+]], label %[[SIMPLE_LOOP8_END:[^,]+]]
270 // OMP50: [[SIMPLE_LOOP8_BODY]]:
271 // Start of body: calculate i from IV:
272 // OMP50: [[IV8_0:%.+]] = load i64, i64* [[OMP_IV8]],{{[^!]*}}
273 // OMP50-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV8_0]], 3
274 // OMP50-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
275 // OMP50-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{[^!]*}}
276 // OMP50-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]],{{[^!]*}}
277 // OMP50: store i32 %{{.+}}, i32* [[R_PRIV]],{{[^!]*}}
278 // OMP50: [[IV8_2:%.+]] = load i64, i64* [[OMP_IV8]],{{[^!]*}}
279 // OMP50-NEXT: [[ADD8_2:%.+]] = add nsw i64 [[IV8_2]], 1
280 // OMP50-NEXT: store i64 [[ADD8_2]], i64* [[OMP_IV8]],{{[^!]*}}
281 // OMP50:      br label {{%?}}[[SIMD_LOOP8_COND]], {{.*}}!llvm.loop ![[DISABLE_VECT:.+]]
282 // OMP50: [[SIMPLE_LOOP8_END]]:
283 // OMP50: br label {{%?}}[[EXIT]]
284 // OMP50: [[EXIT]]:
285 
286 // CHECK-DAG: [[R_VAL:%.+]] = load i32, i32* [[R]],
287 // CHECK-DAG: [[R_PRIV_VAL:%.+]] = load i32, i32* [[R_PRIV]],
288 // CHECK: [[RED:%.+]] = mul nsw i32 [[R_VAL]], [[R_PRIV_VAL]]
289 // CHECK-NEXT: store i32 [[RED]], i32* [[R]],
290 // CHECK-NEXT: ret void
291 }
292 
293 template <class T, unsigned K> T tfoo(T a) { return a + K; }
294 
295 template <typename T, unsigned N>
296 int templ1(T a, T *z) {
297   #pragma omp simd collapse(N)
298   for (int i = 0; i < N * 2; i++) {
299     for (long long j = 0; j < (N + N + N + N); j += 2) {
300       z[i + j] = a + tfoo<T, N>(i + j);
301     }
302   }
303   return 0;
304 }
305 
306 // Instatiation templ1<float,2>
307 // CHECK-LABEL: define {{.*i32}} @{{.*}}templ1{{.*}}(float {{.+}}, float* {{.+}})
308 // CHECK: store i64 0, i64* [[T1_OMP_IV:[^,]+]]
309 // ...
310 // CHECK: [[IV:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
311 // CHECK-NEXT: [[CMP1:%.+]] = icmp slt i64 [[IV]], 16
312 // CHECK-NEXT: br i1 [[CMP1]], label %[[T1_BODY:.+]], label %[[T1_END:[^,]+]]
313 // CHECK: [[T1_BODY]]:
314 // Loop counters i and j updates:
315 // CHECK: [[IV1:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
316 // CHECK-NEXT: [[I_1:%.+]] = sdiv i64 [[IV1]], 4
317 // CHECK-NEXT: [[I_1_MUL1:%.+]] = mul nsw i64 [[I_1]], 1
318 // CHECK-NEXT: [[I_1_ADD0:%.+]] = add nsw i64 0, [[I_1_MUL1]]
319 // CHECK-NEXT: [[I_2:%.+]] = trunc i64 [[I_1_ADD0]] to i32
320 // CHECK-NEXT: store i32 [[I_2]], i32* {{%.+}}{{.*}}!llvm.access.group
321 // CHECK: [[IV2:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
322 // CHECK: [[IV2_1:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
323 // CHECK-NEXT: [[J_1_DIV1:%.+]] = sdiv i64 [[IV2_1]], 4
324 // CHECK-NEXT: [[J_1_MUL1:%.+]] = mul nsw i64 [[J_1_DIV1]], 4
325 // CHECK-NEXT: [[J_1_SUB0:%.+]] = sub nsw i64 [[IV2]], [[J_1_MUL1]]
326 // CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1_SUB0]], 2
327 // CHECK-NEXT: [[J_2_ADD0:%.+]] = add nsw i64 0, [[J_2]]
328 // CHECK-NEXT: store i64 [[J_2_ADD0]], i64* {{%.+}}{{.*}}!llvm.access.group
329 // simd.for.inc:
330 // CHECK: [[IV3:%.+]] = load i64, i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
331 // CHECK-NEXT: [[INC:%.+]] = add nsw i64 [[IV3]], 1
332 // CHECK-NEXT: store i64 [[INC]], i64* [[T1_OMP_IV]]{{.*}}!llvm.access.group
333 // CHECK-NEXT: br label {{%.+}}
334 // CHECK: [[T1_END]]:
335 // CHECK: ret i32 0
336 //
337 void inst_templ1() {
338   float a;
339   float z[100];
340   templ1<float,2> (a, z);
341 }
342 
343 
344 typedef int MyIdx;
345 
346 class IterDouble {
347   double *Ptr;
348 public:
349   IterDouble operator++ () const {
350     IterDouble n;
351     n.Ptr = Ptr + 1;
352     return n;
353   }
354   bool operator < (const IterDouble &that) const {
355     return Ptr < that.Ptr;
356   }
357   double & operator *() const {
358     return *Ptr;
359   }
360   MyIdx operator - (const IterDouble &that) const {
361     return (MyIdx) (Ptr - that.Ptr);
362   }
363   IterDouble operator + (int Delta) {
364     IterDouble re;
365     re.Ptr = Ptr + Delta;
366     return re;
367   }
368 
369   ///~IterDouble() {}
370 };
371 
372 // CHECK-LABEL: define {{.*void}} @{{.*}}iter_simple{{.*}}
373 void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) {
374 //
375 // Calculate number of iterations before the loop body.
376 // CHECK: [[DIFF1:%.+]] = invoke {{.*}}i32 @{{.*}}IterDouble{{.*}}
377 // CHECK: [[DIFF2:%.+]] = sub nsw i32 [[DIFF1]], 1
378 // CHECK-NEXT: [[DIFF3:%.+]] = add nsw i32 [[DIFF2]], 1
379 // CHECK-NEXT: [[DIFF4:%.+]] = sdiv i32 [[DIFF3]], 1
380 // CHECK-NEXT: [[DIFF5:%.+]] = sub nsw i32 [[DIFF4]], 1
381 // CHECK-NEXT: store i32 [[DIFF5]], i32* [[OMP_LAST_IT:%[^,]+]]{{.+}}
382 // CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]]
383   #pragma omp simd
384 
385 // CHECK: [[IV:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}} !llvm.access.group
386 // CHECK-NEXT: [[LAST_IT:%.+]] = load i32, i32* [[OMP_LAST_IT]]{{.+}}!llvm.access.group
387 // CHECK-NEXT: [[NUM_IT:%.+]] = add nsw i32 [[LAST_IT]], 1
388 // CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], [[NUM_IT]]
389 // CHECK-NEXT: br i1 [[CMP]], label %[[IT_BODY:[^,]+]], label %[[IT_END:[^,]+]]
390   for (IterDouble i = ia; i < ib; ++i) {
391 // CHECK: [[IT_BODY]]:
392 // Start of body: calculate i from index:
393 // CHECK: [[IV1:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}}!llvm.access.group
394 // Call of operator+ (i, IV).
395 // CHECK: {{%.+}} = invoke {{.+}} @{{.*}}IterDouble{{.*}}
396 // ... loop body ...
397    *i = *ic * 0.5;
398 // Float multiply and save result.
399 // CHECK: [[MULR:%.+]] = fmul double {{%.+}}, 5.000000e-01
400 // CHECK-NEXT: invoke {{.+}} @{{.*}}IterDouble{{.*}}
401 // CHECK: store double [[MULR:%.+]], double* [[RESULT_ADDR:%.+]], !llvm.access.group
402    ++ic;
403 //
404 // CHECK: [[IV2:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}}!llvm.access.group
405 // CHECK-NEXT: [[ADD2:%.+]] = add nsw i32 [[IV2]], 1
406 // CHECK-NEXT: store i32 [[ADD2]], i32* [[IT_OMP_IV]]{{.+}}!llvm.access.group
407 // br label %{{.*}}, !llvm.loop ![[ITER_LOOP_ID]]
408   }
409 // CHECK: [[IT_END]]:
410 // CHECK: ret void
411 }
412 
413 
414 // CHECK-LABEL: define {{.*void}} @{{.*}}collapsed{{.*}}
415 void collapsed(float *a, float *b, float *c, float *d) {
416   int i; // outer loop counter
417   unsigned j; // middle loop couter, leads to unsigned icmp in loop header.
418   // k declared in the loop init below
419   short l; // inner loop counter
420 // CHECK: store i32 0, i32* [[OMP_IV:[^,]+]]
421 //
422   #pragma omp simd collapse(4)
423 
424 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
425 // CHECK-NEXT: [[CMP:%.+]] = icmp ult i32 [[IV]], 120
426 // CHECK-NEXT: br i1 [[CMP]], label %[[COLL1_BODY:[^,]+]], label %[[COLL1_END:[^,]+]]
427   for (i = 1; i < 3; i++) // 2 iterations
428     for (j = 2u; j < 5u; j++) //3 iterations
429       for (int k = 3; k <= 6; k++) // 4 iterations
430         for (l = 4; l < 9; ++l) // 5 iterations
431         {
432 // CHECK: [[COLL1_BODY]]:
433 // Start of body: calculate i from index:
434 // CHECK: [[IV1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
435 // Calculation of the loop counters values.
436 // CHECK: [[CALC_I_1:%.+]] = udiv i32 [[IV1]], 60
437 // CHECK-NEXT: [[CALC_I_1_MUL1:%.+]] = mul i32 [[CALC_I_1]], 1
438 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 1, [[CALC_I_1_MUL1]]
439 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
440 
441 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
442 // CHECK: [[IV1_2_1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
443 // CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2_1]], 60
444 // CHECK-NEXT: [[MUL_1:%.+]] = mul i32 [[CALC_J_1]], 60
445 // CHECK-NEXT: [[SUB_3:%.+]] = sub i32 [[IV1_2]], [[MUL_1]]
446 // CHECK-NEXT: [[CALC_J_2:%.+]] = udiv i32 [[SUB_3]], 20
447 // CHECK-NEXT: [[CALC_J_2_MUL1:%.+]] = mul i32 [[CALC_J_2]], 1
448 // CHECK-NEXT: [[CALC_J_3:%.+]] = add i32 2, [[CALC_J_2_MUL1]]
449 // CHECK-NEXT: store i32 [[CALC_J_3]], i32* [[LC_J:.+]]
450 
451 // CHECK: [[IV1_3:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
452 // CHECK: [[IV1_3_1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
453 // CHECK-NEXT: [[DIV_1:%.+]] = udiv i32 [[IV1_3_1]], 60
454 // CHECK-NEXT: [[MUL_2:%.+]] = mul i32 [[DIV_1]], 60
455 // CHECK-NEXT: [[ADD_3:%.+]] = sub i32 [[IV1_3]], [[MUL_2]]
456 
457 // CHECK: [[IV1_4:%.+]] = load i32, i32* [[OMP_IV]]
458 // CHECK: [[IV1_4_1:%.+]] = load i32, i32* [[OMP_IV]]
459 // CHECK-NEXT: [[DIV_2:%.+]] = udiv i32 [[IV1_4_1]], 60
460 // CHECK-NEXT: [[MUL_3:%.+]] = mul i32 [[DIV_2]], 60
461 // CHECK-NEXT: [[SUB_6:%.+]] = sub i32 [[IV1_4]], [[MUL_3]]
462 // CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[SUB_6]], 20
463 // CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 20
464 // CHECK-NEXT: [[ADD_5:%.+]] = sub i32 [[ADD_3]], [[MUL_4]]
465 // CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[ADD_5]], 5
466 // CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 1
467 // CHECK-NEXT: [[ADD_6:%.+]] = add i32 3, [[MUL_5]]
468 // CHECK-NEXT: store i32 [[ADD_6]], i32* [[LC_K:.+]]
469 
470 // CHECK: [[IV1_5:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
471 // CHECK: [[IV1_5_1:%.+]] = load i32, i32* [[OMP_IV]]{{.+}}!llvm.access.group
472 // CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[IV1_5_1]], 60
473 // CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 60
474 // CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[IV1_5]], [[MUL_6]]
475 
476 // CHECK: [[IV1_6:%.+]] = load i32, i32* [[OMP_IV]]
477 // CHECK: [[IV1_6_1:%.+]] = load i32, i32* [[OMP_IV]]
478 // CHECK-NEXT: [[DIV_6:%.+]] = udiv i32 [[IV1_6_1]], 60
479 // CHECK-NEXT: [[MUL_7:%.+]] = mul i32 [[DIV_6]], 60
480 // CHECK-NEXT: [[SUB_10:%.+]] = sub i32 [[IV1_6]], [[MUL_7]]
481 // CHECK-NEXT: [[DIV_7:%.+]] = udiv i32 [[SUB_10]], 20
482 // CHECK-NEXT: [[MUL_8:%.+]] = mul i32 [[DIV_7]], 20
483 // CHECK-NEXT: [[SUB_11:%.+]] = sub i32 [[SUB_7]], [[MUL_8]]
484 
485 // CHECK: [[IV1_7:%.+]] = load i32, i32* [[OMP_IV]]
486 // CHECK: [[IV1_7_1:%.+]] = load i32, i32* [[OMP_IV]]
487 // CHECK-NEXT: [[DIV_8:%.+]] = udiv i32 [[IV1_7_1]], 60
488 // CHECK-NEXT: [[MUL_9:%.+]] = mul i32 [[DIV_8]], 60
489 // CHECK-NEXT: [[SUB_12:%.+]] = sub i32 [[IV1_7]], [[MUL_9]]
490 
491 // CHECK: [[IV1_8:%.+]] = load i32, i32* [[OMP_IV]]
492 // CHECK: [[IV1_8_1:%.+]] = load i32, i32* [[OMP_IV]]
493 // CHECK-NEXT: [[DIV_3:%.+]] = udiv i32 [[IV1_8_1]], 60
494 // CHECK-NEXT: [[MUL_4:%.+]] = mul i32 [[DIV_3]], 60
495 // CHECK-NEXT: [[SUB_7:%.+]] = sub i32 [[IV1_8]], [[MUL_4]]
496 // CHECK-NEXT: [[DIV_4:%.+]] = udiv i32 [[SUB_7]], 20
497 // CHECK-NEXT: [[MUL_5:%.+]] = mul i32 [[DIV_4]], 20
498 // CHECK-NEXT: [[SUB_8:%.+]] = sub i32 [[SUB_12]], [[MUL_5]]
499 // CHECK-NEXT: [[DIV_5:%.+]] = udiv i32 [[SUB_8]], 5
500 // CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[DIV_5]], 5
501 // CHECK-NEXT: [[SUB_9:%.+]] = sub i32 [[SUB_11]], [[MUL_6]]
502 // CHECK-NEXT: [[MUL_6:%.+]] = mul i32 [[SUB_9]], 1
503 // CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[MUL_6]]
504 // CHECK-NEXT: [[CALC_L_3:%.+]] = trunc i32 [[CALC_L_2]] to i16
505 // CHECK-NEXT: store i16 [[CALC_L_3]], i16* [[LC_L:.+]]
506 // ... loop body ...
507 // End of body: store into a[i]:
508 // CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.access.group
509     float res = b[j] * c[k];
510     a[i] = res * d[l];
511 // CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
512 // CHECK-NEXT: [[ADD2:%.+]] = add i32 [[IV2]], 1
513 // CHECK-NEXT: store i32 [[ADD2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
514 // br label %{{[^,]+}}, !llvm.loop ![[COLL1_LOOP_ID]]
515 // CHECK: [[COLL1_END]]:
516   }
517 // i,j,l are updated; k is not updated.
518 // CHECK: store i32 3, i32*
519 // CHECK-NEXT: store i32 5, i32*
520 // CHECK-NEXT: store i32 7, i32*
521 // CHECK-NEXT: store i16 9, i16*
522 // CHECK: ret void
523 }
524 
525 extern char foo();
526 extern double globalfloat;
527 
528 // CHECK-LABEL: define {{.*void}} @{{.*}}widened{{.*}}
529 void widened(float *a, float *b, float *c, float *d) {
530   int i; // outer loop counter
531   short j; // inner loop counter
532   globalfloat = 1.0;
533   int localint = 1;
534 // CHECK: store double {{.+}}, double* [[GLOBALFLOAT:@.+]]
535 // Counter is widened to 64 bits.
536 // CHECK: store i64 0, i64* [[OMP_IV:[^,]+]]
537 //
538   #pragma omp simd collapse(2) private(globalfloat, localint)
539 
540 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.access.group
541 // CHECK-NEXT: [[LI:%.+]] = load i64, i64* [[OMP_LI:%[^,]+]]{{.+}}!llvm.access.group
542 // CHECK-NEXT: [[NUMIT:%.+]] = add nsw i64 [[LI]], 1
543 // CHECK-NEXT: [[CMP:%.+]] = icmp slt i64 [[IV]], [[NUMIT]]
544 // CHECK-NEXT: br i1 [[CMP]], label %[[WIDE1_BODY:[^,]+]], label %[[WIDE1_END:[^,]+]]
545   for (i = 1; i < 3; i++) // 2 iterations
546     for (j = 0; j < foo(); j++) // foo() iterations
547   {
548 // CHECK: [[WIDE1_BODY]]:
549 // Start of body: calculate i from index:
550 // CHECK: [[IV1:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.access.group
551 // Calculation of the loop counters values...
552 // CHECK: store i32 {{[^,]+}}, i32* [[LC_I:.+]]
553 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.+}}!llvm.access.group
554 // CHECK: store i16 {{[^,]+}}, i16* [[LC_J:.+]]
555 // ... loop body ...
556 //
557 // Here we expect store into private double var, not global
558 // CHECK-NOT: store double {{.+}}, double* [[GLOBALFLOAT]]
559     globalfloat = (float)j/i;
560     float res = b[j] * c[j];
561 // Store into a[i]:
562 // CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.access.group
563     a[i] = res * d[i];
564 // Then there's a store into private var localint:
565 // CHECK: store i32 {{.+}}, i32* [[LOCALINT:%[^,]+]]{{.+}}!llvm.access.group
566     localint = (int)j;
567 // CHECK: [[IV2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}!llvm.access.group
568 // CHECK-NEXT: [[ADD2:%.+]] = add nsw i64 [[IV2]], 1
569 // CHECK-NEXT: store i64 [[ADD2]], i64* [[OMP_IV]]{{.*}}!llvm.access.group
570 //
571 // br label %{{[^,]+}}, !llvm.loop ![[WIDE1_LOOP_ID]]
572 // CHECK: [[WIDE1_END]]:
573   }
574 // i,j are updated.
575 // CHECK: store i32 3, i32* [[I:%[^,]+]]
576 // CHECK: store i16
577 //
578 // Here we expect store into original localint, not its privatized version.
579 // CHECK-NOT: store i32 {{.+}}, i32* [[LOCALINT]]
580   localint = (int)j;
581 // CHECK: ret void
582 }
583 
584 // CHECK-LABEL: define {{.*void}} @{{.*}}linear{{.*}}(float* {{.+}})
585 void linear(float *a) {
586   // CHECK: [[VAL_ADDR:%.+]] = alloca i64,
587   // CHECK: [[K_ADDR:%.+]] = alloca i64*,
588   long long val = 0;
589   long long &k = val;
590 
591   #pragma omp simd linear(k : 3)
592 // CHECK: store i64* [[VAL_ADDR]], i64** [[K_ADDR]],
593 // CHECK: [[VAL_REF:%.+]] = load i64*, i64** [[K_ADDR]],
594 // CHECK: store i64* [[VAL_REF]], i64** [[K_ADDR_REF:%.+]],
595 // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
596 // CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
597 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]]
598 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
599 
600 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
601 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9
602 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]]
603   for (int i = 10; i > 1; i--) {
604 // CHECK: [[SIMPLE_LOOP_BODY]]:
605 // Start of body: calculate i from IV:
606 // CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
607 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
608 // CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1
609 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]]
610 // CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
611 //
612 // CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
613 // CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
614 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3
615 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
616 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
617 // Update of the privatized version of linear variable!
618 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
619     a[k]++;
620     k = k + 3;
621 // CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
622 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1
623 // CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
624 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]]
625   }
626 // CHECK: [[SIMPLE_LOOP_END]]:
627 //
628 // Update linear vars after loop, as the loop was operating on a private version.
629 // CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
630 // CHECK: store i64* [[K_REF]], i64** [[K_PRIV_REF:%.+]],
631 // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]]
632 // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27
633 // CHECK-NEXT: [[K_REF:%.+]] = load i64*, i64** [[K_PRIV_REF]],
634 // CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[K_REF]]
635 //
636 
637   #pragma omp simd linear(val(k) : 3)
638 // CHECK: [[VAL_REF:%.+]] = load i64*, i64** [[K_ADDR]],
639 // CHECK: store i64* [[VAL_REF]], i64** [[K_ADDR_REF:%.+]],
640 // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
641 // CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
642 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]]
643 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
644 
645 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
646 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9
647 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]]
648   for (int i = 10; i > 1; i--) {
649 // CHECK: [[SIMPLE_LOOP_BODY]]:
650 // Start of body: calculate i from IV:
651 // CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
652 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
653 // CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1
654 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]]
655 // CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
656 //
657 // CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
658 // CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
659 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3
660 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
661 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
662 // Update of the privatized version of linear variable!
663 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
664     a[k]++;
665     k = k + 3;
666 // CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
667 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1
668 // CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
669 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]]
670   }
671 // CHECK: [[SIMPLE_LOOP_END]]:
672 //
673 // Update linear vars after loop, as the loop was operating on a private version.
674 // CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
675 // CHECK: store i64* [[K_REF]], i64** [[K_PRIV_REF:%.+]],
676 // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]]
677 // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27
678 // CHECK-NEXT: [[K_REF:%.+]] = load i64*, i64** [[K_PRIV_REF]],
679 // CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[K_REF]]
680 //
681   #pragma omp simd linear(uval(k) : 3)
682 // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
683 // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[VAL_ADDR]]
684 // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
685 
686 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
687 // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9
688 // CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]]
689   for (int i = 10; i > 1; i--) {
690 // CHECK: [[SIMPLE_LOOP_BODY]]:
691 // Start of body: calculate i from IV:
692 // CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
693 // FIXME: It is interesting, why the following "mul 1" was not constant folded?
694 // CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1
695 // CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]]
696 // CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.access.group
697 //
698 // CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.access.group
699 // CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
700 // CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3
701 // CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64
702 // CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]]
703 // Update of the privatized version of linear variable!
704 // CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]]
705     a[k]++;
706     k = k + 3;
707 // CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
708 // CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1
709 // CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.access.group
710 // br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]]
711   }
712 // CHECK: [[SIMPLE_LOOP_END]]:
713 //
714 // Update linear vars after loop, as the loop was operating on a private version.
715 // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]]
716 // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27
717 // CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[VAL_ADDR]]
718 //
719 }
720 
721 // TERM_DEBUG-LABEL: bar
722 int bar() {return 0;};
723 
724 // TERM_DEBUG-LABEL: parallel_simd
725 void parallel_simd(float *a) {
726 #pragma omp parallel
727 #pragma omp simd
728   // TERM_DEBUG-NOT: __kmpc_global_thread_num
729   // TERM_DEBUG:     invoke i32 {{.*}}bar{{.*}}()
730   // TERM_DEBUG:     unwind label %[[TERM_LPAD:[^,]+]],
731   // TERM_DEBUG-NOT: __kmpc_global_thread_num
732   // TERM_DEBUG:     [[TERM_LPAD]]
733   // TERM_DEBUG:     call void @__clang_call_terminate
734   // TERM_DEBUG:     unreachable
735   for (unsigned i = 131071; i <= 2147483647; i += 127)
736     a[i] += bar();
737 }
738 // TERM_DEBUG: !{{[0-9]+}} = !DILocation(line: [[@LINE-11]],
739 
740 // CHECK-LABEL: S8
741 // CHECK-DAG: ptrtoint [[SS_TY]]* %{{.+}} to i64
742 // CHECK-DAG: ptrtoint [[SS_TY]]* %{{.+}} to i64
743 // CHECK-DAG: ptrtoint [[SS_TY]]* %{{.+}} to i64
744 // CHECK-DAG: ptrtoint [[SS_TY]]* %{{.+}} to i64
745 
746 // CHECK-DAG: and i64 %{{.+}}, 15
747 // CHECK-DAG: icmp eq i64 %{{.+}}, 0
748 // CHECK-DAG: call void @llvm.assume(i1
749 
750 // CHECK-DAG: and i64 %{{.+}}, 7
751 // CHECK-DAG: icmp eq i64 %{{.+}}, 0
752 // CHECK-DAG: call void @llvm.assume(i1
753 
754 // CHECK-DAG: and i64 %{{.+}}, 15
755 // CHECK-DAG: icmp eq i64 %{{.+}}, 0
756 // CHECK-DAG: call void @llvm.assume(i1
757 
758 // CHECK-DAG: and i64 %{{.+}}, 3
759 // CHECK-DAG: icmp eq i64 %{{.+}}, 0
760 // CHECK-DAG: call void @llvm.assume(i1
761 struct SS {
762   SS(): a(0) {}
763   SS(int v) : a(v) {}
764   int a;
765   typedef int type;
766 };
767 
768 template <typename T>
769 class S7 : public T {
770 protected:
771   T *a;
772   T b[2];
773   S7() : a(0) {}
774 
775 public:
776   S7(typename T::type &v) : a((T*)&v) {
777 #pragma omp simd aligned(a)
778     for (int k = 0; k < a->a; ++k)
779       ++this->a->a;
780 #pragma omp simd aligned(this->b : 8)
781     for (int k = 0; k < a->a; ++k)
782       ++a->a;
783   }
784 };
785 
786 class S8 : private IterDouble, public S7<SS> {
787   S8() {}
788 
789 public:
790   S8(int v) : S7<SS>(v){
791 #pragma omp parallel private(a)
792 #pragma omp simd aligned(S7<SS>::a)
793     for (int k = 0; k < a->a; ++k)
794       ++this->a->a;
795 #pragma omp parallel shared(b)
796 #pragma omp simd aligned(this->b: 4)
797     for (int k = 0; k < a->a; ++k)
798       ++a->a;
799   }
800 };
801 S8 s8(0);
802 
803 // TERM_DEBUG-NOT: line: 0,
804 // TERM_DEBUG: distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_simd_codegen.cpp",
805 // OMP50-DAG: ![[NOVECT:.+]] = !{!"llvm.loop.vectorize.enable", i1 false}
806 // OMP50-DAG: ![[DISABLE_VECT]] = distinct !{{.*}}![[NOVECT]]{{[,}]}}
807 #endif // HEADER
808 
809