1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --check-prefix=CHECK --check-prefix=LIFETIME
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 -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 -main-file-name for_codegen.cpp %s -o - -emit-llvm -fprofile-instrument=clang -fprofile-instrument-path=for_codegen-test.profraw | FileCheck %s --check-prefix=PROF-INSTR-PATH
6 
7 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s
8 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
9 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
10 // 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 SIMD-ONLY0 %s
11 // RUN: %clang_cc1 -main-file-name for_codegen.cpp %s -o - -emit-llvm -fprofile-instrument=clang -fprofile-instrument-path=for_codegen-test.profraw | FileCheck --check-prefix SIMD-ONLY0 %s
12 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
13 //
14 // expected-no-diagnostics
15 #ifndef HEADER
16 #define HEADER
17 // PROF-INSTR-PATH: constant [25 x i8] c"for_codegen-test.profraw\00"
18 
19 // CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
20 // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr global %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
21 // CHECK-DAG: [[LOOP_LOC:@.+]] = private unnamed_addr global %{{.+}} { i32 0, i32 514, i32 0, i32 0, i8*
22 // CHECK-DAG: [[I:@.+]] = global i8 1,
23 // CHECK-DAG: [[J:@.+]] = global i8 2,
24 // CHECK-DAG: [[K:@.+]] = global i8 3,
25 
26 // CHECK-LABEL: loop_with_counter_collapse
27 void loop_with_counter_collapse() {
28   // Captured initializations.
29   // CHECK: store i32 0, i32* [[I_TMP:%.+]],
30   // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]],
31   // CHECK: store i32 [[VAL]], i32* [[J_LB_MIN:%.+]],
32   // CHECK: store i32 3, i32* [[I_TMP]],
33   // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]],
34   // CHECK: store i32 [[VAL]], i32* [[J_LB_MAX:%.+]],
35   // CHECK: [[J_LB_MIN_VAL:%.+]] = load i32, i32* [[J_LB_MIN]],
36   // CHECK: [[J_LB_MAX_VAL:%.+]] = load i32, i32* [[J_LB_MAX]],
37   // CHECK: [[CMP:%.+]] = icmp slt i32 [[J_LB_MIN_VAL]], [[J_LB_MAX_VAL]]
38   // CHECK: [[BOOL:%.+]] = zext i1 [[CMP]] to i8
39   // CHECK: store i8 [[BOOL]], i8* [[J_LB_CMP:%.+]],
40   // CHECK: store i32 0, i32* [[I_TMP]],
41   // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]],
42   // CHECK: [[J_UB_MIN_VAL:%.+]] = add nsw i32 4, [[VAL]]
43   // CHECK: store i32 [[J_UB_MIN_VAL]], i32* [[J_UB_MIN:%.+]],
44   // CHECK: store i32 3, i32* [[I_TMP]],
45   // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]],
46   // CHECK: [[J_UB_MAX_VAL:%.+]] = add nsw i32 4, [[VAL]]
47   // CHECK: store i32 [[J_UB_MAX_VAL]], i32* [[J_UB_MAX:%.+]],
48   // CHECK: [[J_UB_MIN_VAL:%.+]] = load i32, i32* [[J_UB_MIN]],
49   // CHECK: [[J_UB_MAX_VAL:%.+]] = load i32, i32* [[J_UB_MAX]],
50   // CHECK: [[CMP:%.+]] = icmp sgt i32 [[J_UB_MIN_VAL]], [[J_UB_MAX_VAL]]
51   // CHECK: [[BOOL:%.+]] = zext i1 [[CMP]] to i8
52   // CHECK: store i8 [[BOOL]], i8* [[J_UB_CMP:%.+]],
53   // CHECK: [[J_UB_CMP_VAL:%.+]] = load i8, i8* [[J_UB_CMP]],
54   // CHECK: [[BOOL:%.+]] = trunc i8 [[J_UB_CMP_VAL]] to i1
55   // CHECK: br i1 [[BOOL]], label %[[TRUE:[^,]+]], label %[[FALSE:[^,]+]]
56   // CHECK: [[TRUE]]:
57   // CHECK: [[J_UB_MIN_VAL:%.+]] = load i32, i32* [[J_UB_MIN]],
58   // CHECK: br label %[[EXIT:[^,]+]]
59   // CHECK: [[FALSE]]:
60   // CHECK: [[J_UB_MAX_VAL:%.+]] = load i32, i32* [[J_UB_MAX]],
61   // CHECK: br label %[[EXIT]]
62   // CHECK: [[EXIT]]:
63   // CHECK: [[J_UB_VAL:%.+]] = phi i32 [ [[J_UB_MIN_VAL]], %[[TRUE]] ], [ [[J_UB_MAX_VAL]], %[[FALSE]] ]
64   // CHECK: store i32 [[J_UB_VAL]], i32* [[J_UB:%.+]],
65   // CHECK: [[J_LB_CMP_VAL:%.+]] = load i8, i8* [[J_LB_CMP]],
66   // CHECK: [[BOOL:%.+]] = trunc i8 [[J_LB_CMP_VAL]] to i1
67   // CHECK: br i1 [[BOOL]], label %[[TRUE:[^,]+]], label %[[FALSE:[^,]+]]
68   // CHECK: [[TRUE]]:
69   // CHECK: [[J_LB_MIN_VAL:%.+]] = load i32, i32* [[J_LB_MIN]],
70   // CHECK: br label %[[EXIT:[^,]+]]
71   // CHECK: [[FALSE]]:
72   // CHECK: [[J_LB_MAX_VAL:%.+]] = load i32, i32* [[J_LB_MAX]],
73   // CHECK: br label %[[EXIT]]
74   // CHECK: [[EXIT]]:
75   // CHECK: [[J_LB_VAL:%.+]] = phi i32 [ [[J_LB_MIN_VAL]], %[[TRUE]] ], [ [[J_LB_MAX_VAL]], %[[FALSE]] ]
76   // CHECK: store i32 [[J_LB_VAL]], i32* [[J_LB:%.+]],
77   // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]],
78   // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]],
79   // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]]
80   // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1
81   // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1
82   // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1
83   // CHECK: [[CAST:%.+]] = sext i32 [[DIV_ST]] to i64
84   // CHECK: [[MUL:%.+]] = mul nsw i64 4, [[CAST]]
85   // CHECK: [[NUM_ITERS_VAL:%.+]] = sub nsw i64 [[MUL]], 1
86   // CHECK: store i64 [[NUM_ITERS_VAL]], i64* [[NUM_ITERS:%.+]],
87 
88   // Initialization
89   // CHECK: store i32 0, i32* [[I:%.+]],
90   // CHECK: [[I_INIT:%.+]] = load i32, i32* [[I]],
91   // CHECK: store i32 [[I_INIT]], i32* [[J:%.+]],
92 
93   // LIFETIME: call void @llvm.lifetime.end
94   // LIFETIME: call void @llvm.lifetime.end
95 
96   // Precondition for j counter
97   // CHECK: store i32 0, i32* [[TMP_I:%.+]],
98   // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[TMP_I]],
99   // CHECK: [[I_VAL:%.+]] = load i32, i32* [[TMP_I]],
100   // CHECK: [[J_UB_VAL:%.+]] = add nsw i32 4, [[I_VAL]]
101   // CHECK: [[CMP:%.+]] = icmp slt i32 [[J_LB_VAL]], [[J_UB_VAL]]
102   // CHECK: br i1 [[CMP]], label %[[THEN:[^,]+]], label %[[ELSE:[^,]+]]
103 
104   // CHECK: [[THEN]]:
105   // CHECK: store i64 0, i64* [[LB:%.+]],
106   // CHECK: [[NUM_ITERS_VAL:%.+]] = load i64, i64* [[NUM_ITERS]],
107   // CHECK: store i64 [[NUM_ITERS_VAL]], i64* [[UB:%.+]],
108   // CHECK: store i64 1, i64* [[STRIDE:%.+]],
109   // CHECK: store i32 0, i32* [[IS_LAST:%.+]],
110   // CHECK: call void @__kmpc_for_static_init_8(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST]], i64* [[LB]], i64* [[UB]], i64* [[STRIDE]], i64 1, i64 1)
111   // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
112   // CHECK: [[NUM_ITERS_VAL:%.+]] = load i64, i64* [[NUM_ITERS]],
113   // CHECK: [[CMP:%.+]] = icmp sgt i64 [[UB_VAL]], [[NUM_ITERS_VAL]]
114   // CHECK: br i1 [[CMP]], label %[[TRUE:[^,]+]], label %[[FALSE:[^,]+]]
115   // CHECK: [[TRUE]]:
116   // CHECK: [[NUM_ITERS_VAL:%.+]] = load i64, i64* [[NUM_ITERS]],
117   // CHECK: br label %[[DONE:[^,]+]]
118   // CHECK: [[FALSE]]:
119   // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
120   // CHECK: br label %[[DONE]]
121   // CHECK: [[DONE]]:
122   // CHECK: [[TOP:%.+]] = phi i64 [ [[NUM_ITERS_VAL]], %[[TRUE]] ], [ [[UB_VAL]], %[[FALSE]] ]
123   // CHECK: store i64 [[TOP]], i64* [[UB]],
124   // CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
125   // CHECK: store i64 [[LB_VAL]], i64* [[IV:%.+]],
126   // CHECK: br label %[[COND:[^,]+]]
127   // CHECK: [[COND]]:
128   // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
129   // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
130   // CHECK: [[CMP:%.+]] = icmp sle i64 [[IV_VAL]], [[UB_VAL]]
131   // CHECK: br i1 [[CMP]], label %[[BODY:[^,]+]], label %[[CLEANUP:[^,]+]]
132   // LIFETIME: [[CLEANUP]]:
133   // LIFETIME: br label %[[CLEANUP:[^,]+]]
134   // CHECK: [[BODY]]:
135   // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
136   // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]],
137   // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]],
138   // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]]
139   // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1
140   // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1
141   // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1
142   // CHECK: [[MUL:%.+]] = mul nsw i32 1, [[DIV_ST]]
143   // CHECK: [[CAST:%.+]] = sext i32 [[MUL]] to i64
144   // CHECK: [[DIV:%.+]] = sdiv i64 [[IV_VAL]], [[CAST]]
145   // CHECK: [[MUL:%.+]] = mul nsw i64 [[DIV]], 1
146   // CHECK: [[ADD:%.+]] = add nsw i64 0, [[MUL]]
147   // CHECK: [[CAST:%.+]] = trunc i64 [[ADD]] to i32
148   // CHECK: store i32 [[CAST]], i32* [[I_PRIV:%.+]],
149   // CHECK: [[I_VAL:%.+]] = load i32, i32* [[I_PRIV]],
150   // CHECK: [[CONV:%.+]] = sext i32 [[I_VAL]] to i64
151   // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
152   // CHECK: [[IV_VAL1:%.+]] = load i64, i64* [[IV]],
153   // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]],
154   // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]],
155   // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]]
156   // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1
157   // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1
158   // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1
159   // CHECK: [[MUL:%.+]] = mul nsw i32 1, [[DIV_ST]]
160   // CHECK: [[CAST:%.+]] = sext i32 [[MUL]] to i64
161   // CHECK: [[DIV:%.+]] = sdiv i64 [[IV_VAL1]], [[CAST]]
162   // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]],
163   // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]],
164   // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]]
165   // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1
166   // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1
167   // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1
168   // CHECK: [[MUL:%.+]] = mul nsw i32 1, [[DIV_ST]]
169   // CHECK: [[CAST:%.+]] = sext i32 [[MUL]] to i64
170   // CHECK: [[MUL:%.+]] = mul nsw i64 [[DIV]], [[CAST]]
171   // CHECK: [[SUB:%.+]] = sub nsw i64 [[IV_VAL]], [[MUL]]
172   // CHECK: [[MUL:%.+]] = mul nsw i64 [[SUB:%.+]], 1
173   // CHECK: [[ADD:%.+]] = add nsw i64 [[CONV]], [[MUL]]
174   // CHECK: [[CAST:%.+]] = trunc i64 [[ADD]] to i32
175   // CHECK: store i32 [[CAST]], i32* [[J_PRIV:%.+]],
176 
177   // Check that the loop variable is not out of its boundaries.
178   // CHECK: [[J_VAL:%.+]] = load i32, i32* [[J_PRIV]],
179   // CHECK: [[I_VAL:%.+]] = load i32, i32* [[I_PRIV]],
180   // CHECK: [[J_COND:%.+]] = add nsw i32 4, [[I_VAL]]
181   // CHECK: [[CMP:%.+]] = icmp slt i32 [[J_VAL]], [[J_COND]]
182   // CHECK: br i1 [[CMP]], label %[[NEXT:[^,]+]], label %[[BODY_CONT:[^,]+]]
183   // CHECK: [[NEXT]]:
184 
185   // Main body is empty.
186   // CHECK: br label %[[BODY_CONT]]
187   // CHECK: [[BODY_CONT]]:
188   // CHECK: br label %[[INC:[^,]+]]
189   // CHECK: [[INC]]:
190   // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]],
191   // CHECK: [[ADD:%.+]] = add nsw i64 [[IV_VAL]], 1
192   // CHECK: store i64 [[ADD]], i64* [[IV]],
193   // CHECK: br label %[[COND]]
194   // CHECK: [[CLEANUP]]:
195   // CHECK: br label %[[EXIT:[^,]+]]
196   // CHECK: [[EXIT]]:
197   // CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @{{.+}}, i32 %{{.+}})
198   // LIFETIME: call void @llvm.lifetime.end
199   // LIFETIME: call void @llvm.lifetime.end
200   // LIFETIME: call void @llvm.lifetime.end
201   // LIFETIME: call void @llvm.lifetime.end
202   // LIFETIME: call void @llvm.lifetime.end
203   // LIFETIME: call void @llvm.lifetime.end
204   // LIFETIME: call void @llvm.lifetime.end
205   // LIFETIME: call void @llvm.lifetime.end
206   // LIFETIME: call void @llvm.lifetime.end
207   #pragma omp for collapse(2)
208   for (int i = 0; i < 4; i++) {
209     for (int j = i; j < 4 + i; j++) {
210     }
211   }
212 }
213 // CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
214 void without_schedule_clause(float *a, float *b, float *c, float *d) {
215 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
216   #pragma omp for nowait
217 // CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
218 // UB = min(UB, GlobalUB)
219 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
220 // CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423
221 // CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]]
222 // CHECK: [[UBRESULT:%.+]] = phi i32 [ 4571423, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ]
223 // CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]]
224 // CHECK-NEXT: [[LB:%.+]] = load i32, i32* [[OMP_LB]]
225 // CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]]
226 // Loop header
227 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]
228 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
229 // CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]]
230 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
231   for (int i = 33; i < 32000000; i += 7) {
232 // CHECK: [[LOOP1_BODY]]
233 // Start of body: calculate i from IV:
234 // CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]
235 // CHECK-NEXT: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 7
236 // CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 33, [[CALC_I_1]]
237 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
238 // ... loop body ...
239 // End of body: store into a[i]:
240 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
241 // CHECK-NOT: !llvm.access.group
242     a[i] = b[i] * c[i] * d[i];
243 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
244 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
245 // CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]
246 // CHECK-NEXT: br label %{{.+}}
247   }
248 // CHECK: [[LOOP1_END]]
249 // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
250 // CHECK-NOT: __kmpc_barrier
251 // CHECK: ret void
252 }
253 
254 // CHECK-LABEL: define {{.*void}} @{{.*}}static_not_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
255 void static_not_chunked(float *a, float *b, float *c, float *d) {
256 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
257   #pragma omp for schedule(static)
258 // CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
259 // UB = min(UB, GlobalUB)
260 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
261 // CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423
262 // CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]]
263 // CHECK: [[UBRESULT:%.+]] = phi i32 [ 4571423, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ]
264 // CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]]
265 // CHECK-NEXT: [[LB:%.+]] = load i32, i32* [[OMP_LB]]
266 // CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]]
267 // Loop header
268 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]
269 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
270 // CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]]
271 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
272   for (int i = 32000000; i > 33; i += -7) {
273 // CHECK: [[LOOP1_BODY]]
274 // Start of body: calculate i from IV:
275 // CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]
276 // CHECK-NEXT: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 7
277 // CHECK-NEXT: [[CALC_I_2:%.+]] = sub nsw i32 32000000, [[CALC_I_1]]
278 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
279 // ... loop body ...
280 // End of body: store into a[i]:
281 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
282 // CHECK-NOT: !llvm.access.group
283     a[i] = b[i] * c[i] * d[i];
284 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
285 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
286 // CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]
287 // CHECK-NEXT: br label %{{.+}}
288   }
289 // CHECK: [[LOOP1_END]]
290 // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
291 // CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
292 // CHECK: ret void
293 }
294 
295 // CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
296 void static_chunked(float *a, float *b, float *c, float *d) {
297 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
298   #pragma omp for schedule(monotonic: static, 5)
299 // CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]], i32 536870945, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
300 // UB = min(UB, GlobalUB)
301 // CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
302 // CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288
303 // CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]]
304 // CHECK: [[UBRESULT:%.+]] = phi i32 [ 16908288, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ]
305 // CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]]
306 // CHECK-NEXT: [[LB:%.+]] = load i32, i32* [[OMP_LB]]
307 // CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]]
308 
309 // Outer loop header
310 // CHECK: [[O_IV:%.+]] = load i32, i32* [[OMP_IV]]
311 // CHECK-NEXT: [[O_UB:%.+]] = load i32, i32* [[OMP_UB]]
312 // CHECK-NEXT: [[O_CMP:%.+]] = icmp ule i32 [[O_IV]], [[O_UB]]
313 // CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]]
314 
315 // Loop header
316 // CHECK: [[O_LOOP1_BODY]]
317 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]
318 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
319 // CHECK-NEXT: [[CMP:%.+]] = icmp ule i32 [[IV]], [[UB]]
320 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
321   for (unsigned i = 131071; i <= 2147483647; i += 127) {
322 // CHECK: [[LOOP1_BODY]]
323 // Start of body: calculate i from IV:
324 // CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]]
325 // CHECK-NEXT: [[CALC_I_1:%.+]] = mul i32 [[IV1_1]], 127
326 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 131071, [[CALC_I_1]]
327 // CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]
328 // ... loop body ...
329 // End of body: store into a[i]:
330 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
331 // CHECK-NOT: !llvm.access.group
332     a[i] = b[i] * c[i] * d[i];
333 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
334 // CHECK-NEXT: [[ADD1_2:%.+]] = add i32 [[IV1_2]], 1
335 // CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]
336 // CHECK-NEXT: br label %{{.+}}
337   }
338 // CHECK: [[LOOP1_END]]
339 // Update the counters, adding stride
340 // CHECK:  [[LB:%.+]] = load i32, i32* [[OMP_LB]]
341 // CHECK-NEXT: [[ST:%.+]] = load i32, i32* [[OMP_ST]]
342 // CHECK-NEXT: [[ADD_LB:%.+]] = add i32 [[LB]], [[ST]]
343 // CHECK-NEXT: store i32 [[ADD_LB]], i32* [[OMP_LB]]
344 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
345 // CHECK-NEXT: [[ST:%.+]] = load i32, i32* [[OMP_ST]]
346 // CHECK-NEXT: [[ADD_UB:%.+]] = add i32 [[UB]], [[ST]]
347 // CHECK-NEXT: store i32 [[ADD_UB]], i32* [[OMP_UB]]
348 
349 // CHECK: [[O_LOOP1_END]]
350 // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]])
351 // CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
352 // CHECK: ret void
353 }
354 
355 // CHECK-LABEL: define {{.*void}} @{{.*}}dynamic1{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
356 void dynamic1(float *a, float *b, float *c, float *d) {
357 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
358   #pragma omp for schedule(nonmonotonic: dynamic)
359 // CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741859, i64 0, i64 16908287, i64 1, i64 1)
360 //
361 // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
362 // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
363 // CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]]
364 
365 // Loop header
366 // CHECK: [[O_LOOP1_BODY]]
367 // CHECK: [[LB:%.+]] = load i64, i64* [[OMP_LB]]
368 // CHECK-NEXT: store i64 [[LB]], i64* [[OMP_IV:[^,]+]]
369 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
370 
371 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
372 // CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
373 // CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
374 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
375   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
376 // CHECK: [[LOOP1_BODY]]
377 // Start of body: calculate i from IV:
378 // CHECK: [[IV1_1:%.+]] = load i64, i64* [[OMP_IV]]
379 // CHECK-NEXT: [[CALC_I_1:%.+]] = mul i64 [[IV1_1]], 127
380 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i64 131071, [[CALC_I_1]]
381 // CHECK-NEXT: store i64 [[CALC_I_2]], i64* [[LC_I:.+]]
382 // ... loop body ...
383 // End of body: store into a[i]:
384 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}!llvm.access.group
385     a[i] = b[i] * c[i] * d[i];
386 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}
387 // CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1
388 // CHECK-NEXT: store i64 [[ADD1_2]], i64* [[OMP_IV]]
389 // CHECK-NEXT: br label %{{.+}}
390   }
391 // CHECK: [[LOOP1_END]]
392 // CHECK: [[O_LOOP1_END]]
393 // CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
394 // CHECK: ret void
395 }
396 
397 // CHECK-LABEL: define {{.*void}} @{{.*}}guided7{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
398 void guided7(float *a, float *b, float *c, float *d) {
399 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
400   #pragma omp for schedule(guided, 7)
401 // CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 36, i64 0, i64 16908287, i64 1, i64 7)
402 //
403 // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
404 // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
405 // CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]]
406 
407 // Loop header
408 // CHECK: [[O_LOOP1_BODY]]
409 // CHECK: [[LB:%.+]] = load i64, i64* [[OMP_LB]]
410 // CHECK-NEXT: store i64 [[LB]], i64* [[OMP_IV:[^,]+]]
411 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
412 
413 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
414 // CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
415 // CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
416 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
417   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
418 // CHECK: [[LOOP1_BODY]]
419 // Start of body: calculate i from IV:
420 // CHECK: [[IV1_1:%.+]] = load i64, i64* [[OMP_IV]]
421 // CHECK-NEXT: [[CALC_I_1:%.+]] = mul i64 [[IV1_1]], 127
422 // CHECK-NEXT: [[CALC_I_2:%.+]] = add i64 131071, [[CALC_I_1]]
423 // CHECK-NEXT: store i64 [[CALC_I_2]], i64* [[LC_I:.+]]
424 // ... loop body ...
425 // End of body: store into a[i]:
426 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}!llvm.access.group
427     a[i] = b[i] * c[i] * d[i];
428 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}
429 // CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1
430 // CHECK-NEXT: store i64 [[ADD1_2]], i64* [[OMP_IV]]
431 // CHECK-NEXT: br label %{{.+}}
432   }
433 // CHECK: [[LOOP1_END]]
434 // CHECK: [[O_LOOP1_END]]
435 // CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
436 // CHECK: ret void
437 }
438 
439 // CHECK-LABEL: define {{.*void}} @{{.*}}test_auto{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
440 void test_auto(float *a, float *b, float *c, float *d) {
441   unsigned int x = 0;
442   unsigned int y = 0;
443 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
444   #pragma omp for schedule(auto) collapse(2)
445 // CHECK: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 38, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1)
446 //
447 // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
448 // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
449 // CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]]
450 
451 // Loop header
452 // CHECK: [[O_LOOP1_BODY]]
453 // CHECK: [[LB:%.+]] = load i64, i64* [[OMP_LB]]
454 // CHECK-NEXT: store i64 [[LB]], i64* [[OMP_IV:[^,]+]]
455 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
456 
457 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
458 // CHECK-NEXT: [[CMP:%.+]] = icmp sle i64 [[IV]], [[UB]]
459 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
460 // FIXME: When the iteration count of some nested loop is not a known constant,
461 // we should pre-calculate it, like we do for the total number of iterations!
462   for (char i = static_cast<char>(y); i <= '9'; ++i)
463     for (x = 11; x > 0; --x) {
464 // CHECK: [[LOOP1_BODY]]
465 // Start of body: indices are calculated from IV:
466 // CHECK: store i8 {{%[^,]+}}, i8* {{%[^,]+}}
467 // CHECK: store i32 {{%[^,]+}}, i32* {{%[^,]+}}
468 // ... loop body ...
469 // End of body: store into a[i]:
470 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
471 // CHECK-NOT: !llvm.access.group
472     a[i] = b[i] * c[i] * d[i];
473 // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}}
474 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i64 [[IV1_2]], 1
475 // CHECK-NEXT: store i64 [[ADD1_2]], i64* [[OMP_IV]]
476 // CHECK-NEXT: br label %{{.+}}
477   }
478 // CHECK: [[LOOP1_END]]
479 // CHECK: [[O_LOOP1_END]]
480 // CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
481 // CHECK: ret void
482 }
483 
484 // CHECK-LABEL: define {{.*void}} @{{.*}}runtime{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
485 void runtime(float *a, float *b, float *c, float *d) {
486   int x = 0;
487 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
488   #pragma omp for collapse(2) schedule(runtime)
489 // CHECK: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 37, i32 0, i32 199, i32 1, i32 1)
490 //
491 // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]])
492 // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
493 // CHECK-NEXT: br i1 [[O_CMP]], label %[[O_LOOP1_BODY:[^,]+]], label %[[O_LOOP1_END:[^,]+]]
494 
495 // Loop header
496 // CHECK: [[O_LOOP1_BODY]]
497 // CHECK: [[LB:%.+]] = load i32, i32* [[OMP_LB]]
498 // CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]]
499 // CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]
500 
501 // CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
502 // CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]]
503 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
504   for (unsigned char i = '0' ; i <= '9'; ++i)
505     for (x = -10; x < 10; ++x) {
506 // CHECK: [[LOOP1_BODY]]
507 // Start of body: indices are calculated from IV:
508 // CHECK: store i8 {{%[^,]+}}, i8* {{%[^,]+}}
509 // CHECK: store i32 {{%[^,]+}}, i32* {{%[^,]+}}
510 // ... loop body ...
511 // End of body: store into a[i]:
512 // CHECK: store float [[RESULT:%.+]], float* {{%.+}}
513 // CHECK-NOT: !llvm.access.group
514     a[i] = b[i] * c[i] * d[i];
515 // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}
516 // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1
517 // CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]
518 // CHECK-NEXT: br label %{{.+}}
519   }
520 // CHECK: [[LOOP1_END]]
521 // CHECK: [[O_LOOP1_END]]
522 // CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
523 // CHECK: ret void
524 }
525 
526 // CHECK-LABEL: test_precond
527 void test_precond() {
528   // CHECK: [[A_ADDR:%.+]] = alloca i8,
529   // CHECK: [[I_ADDR:%.+]] = alloca i8,
530   // CHECK: [[CAP:%.+]] = alloca i8,
531   char a = 0;
532   // CHECK: store i8 0,
533   // CHECK: store i32
534   // CHECK: store i8
535   // CHECK: [[A:%.+]] = load i8, i8* [[CAP]],
536   // CHECK: [[CONV:%.+]] = sext i8 [[A]] to i32
537   // CHECK: [[CMP:%.+]] = icmp slt i32 [[CONV]], 10
538   // CHECK: br i1 [[CMP]], label %[[PRECOND_THEN:[^,]+]], label %[[PRECOND_END:[^,]+]]
539   // CHECK: [[PRECOND_THEN]]
540   // CHECK: call void @__kmpc_for_static_init_4
541 #pragma omp for
542   for(char i = a; i < 10; ++i);
543   // CHECK: call void @__kmpc_for_static_fini
544   // CHECK: [[PRECOND_END]]
545 }
546 
547 // TERM_DEBUG-LABEL: foo
548 int foo() {return 0;};
549 
550 // TERM_DEBUG-LABEL: parallel_for
551 void parallel_for(float *a) {
552 #pragma omp parallel
553 #pragma omp for schedule(static, 5)
554   // TERM_DEBUG-NOT: __kmpc_global_thread_num
555   // TERM_DEBUG:     call void @__kmpc_for_static_init_4u({{.+}}), !dbg [[DBG_LOC:![0-9]+]]
556   // TERM_DEBUG:     invoke i32 {{.*}}foo{{.*}}()
557   // TERM_DEBUG:     unwind label %[[TERM_LPAD:.+]],
558   // TERM_DEBUG-NOT: __kmpc_global_thread_num
559   // TERM_DEBUG:     call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC]]
560   // TERM_DEBUG:     call {{.+}} @__kmpc_barrier({{.+}}), !dbg [[DBG_LOC]]
561   // TERM_DEBUG:     [[TERM_LPAD]]
562   // TERM_DEBUG:     call void @__clang_call_terminate
563   // TERM_DEBUG:     unreachable
564   for (unsigned i = 131071; i <= 2147483647; i += 127)
565     a[i] += foo();
566 }
567 // Check source line corresponds to "#pragma omp for schedule(static, 5)" above:
568 // TERM_DEBUG: [[DBG_LOC]] = !DILocation(line: [[@LINE-15]],
569 
570 char i = 1, j = 2, k = 3;
571 // CHECK-LABEL: for_with_global_lcv
572 void for_with_global_lcv() {
573 // CHECK: alloca i8,
574 // CHECK: [[I_ADDR:%.+]] = alloca i8,
575 // CHECK: alloca i8,
576 // CHECK: [[J_ADDR:%.+]] = alloca i8,
577 
578 // CHECK: call void @__kmpc_for_static_init_4(
579 // CHECK-NOT: [[I]]
580 // CHECK: store i8 %{{.+}}, i8* [[I_ADDR]]
581 // CHECK-NOT: [[I]]
582 // CHECK: [[I_VAL:%.+]] = load i8, i8* [[I_ADDR]],
583 // CHECK-NOT: [[I]]
584 // CHECK: store i8 [[I_VAL]], i8* [[K]]
585 // CHECK-NOT: [[I]]
586 // CHECK: call void @__kmpc_for_static_fini(
587 // CHECK: call void @__kmpc_barrier(
588 #pragma omp for
589   for (i = 0; i < 2; ++i) {
590     k = i;
591   }
592 // CHECK: call void @__kmpc_for_static_init_4(
593 // CHECK-NOT: [[J]]
594 // CHECK: store i8 %{{.+}}, i8* [[J_ADDR]]
595 // CHECK-NOT: [[J]]
596 // CHECK: [[J_VAL:%.+]] = load i8, i8* [[J_ADDR]],
597 // CHECK-NOT: [[J]]
598 // CHECK: store i8 [[J_VAL]], i8* [[K]]
599 // CHECK-NOT: [[J]]
600 // CHECK: call void @__kmpc_for_static_fini(
601 #pragma omp for collapse(2)
602   for (int i = 0; i < 2; ++i)
603   for (j = 0; j < 2; ++j) {
604     k = i;
605     k = j;
606   }
607   char &cnt = i;
608 #pragma omp for
609   for (cnt = 0; cnt < 2; ++cnt)
610     k = cnt;
611 }
612 
613 // CHECK-LABEL: for_with_references
614 void for_with_references() {
615 // CHECK: [[I:%.+]] = alloca i8,
616 // CHECK: [[CNT:%.+]] = alloca i8*,
617 // CHECK: [[CNT_PRIV:%.+]] = alloca i8,
618 // CHECK: call void @__kmpc_for_static_init_8(
619 // CHECK-NOT: load i8, i8* [[CNT]],
620 // CHECK: call void @__kmpc_for_static_fini(
621   char i = 0;
622   char &cnt = i;
623 #pragma omp for collapse(2)
624   for (cnt = 0; cnt < 2; ++cnt)
625     for (int j = cnt; j < 4 + cnt; j++)
626     k = cnt;
627 }
628 
629 struct Bool {
630   Bool(bool b) : b(b) {}
631   operator bool() const { return b; }
632   const bool b;
633 };
634 
635 template <typename T>
636 struct It {
637   It() : p(0) {}
638   It(const It &, int = 0) ;
639   template <typename U>
640   It(U &, int = 0) ;
641   It &operator=(const It &);
642   It &operator=(It &);
643   ~It() {}
644 
645   It(T *p) : p(p) {}
646 
647   operator T *&() { return p; }
648   operator T *() const { return p; }
649   T *operator->() const { return p; }
650 
651   It &operator++() { ++p; return *this; }
652   It &operator--() { --p; return *this; }
653   It &operator+=(unsigned n) { p += n; return *this; }
654   It &operator-=(unsigned n) { p -= n; return *this; }
655 
656   T *p;
657 };
658 
659 template <typename T>
660 It<T> operator+(It<T> a, typename It<T>::difference_type n) { return a.p + n; }
661 
662 template <typename T>
663 It<T> operator+(typename It<T>::difference_type n, It<T> a) { return a.p + n; }
664 
665 template <typename T>
666 It<T> operator-(It<T> a, typename It<T>::difference_type n) { return a.p - n; }
667 
668 typedef Bool BoolType;
669 
670 template <typename T>
671 BoolType operator<(It<T> a, It<T> b) { return a.p < b.p; }
672 
673 void loop_with_It(It<char> begin, It<char> end) {
674 #pragma omp for
675   for (It<char> it = begin; it < end; ++it) {
676     *it = 0;
677   }
678 }
679 
680 // CHECK-LABEL: loop_with_It
681 // CHECK: call i32 @__kmpc_global_thread_num(
682 // CHECK: call void @__kmpc_for_static_init_8(
683 // CHECK: call void @__kmpc_for_static_fini(
684 
685 void loop_with_It_plus(It<char> begin, It<char> end) {
686 #pragma omp for
687   for (It<char> it = begin; it < end; it+=1u) {
688     *it = 0;
689   }
690 }
691 
692 // CHECK-LABEL: loop_with_It_plus
693 // CHECK: call i32 @__kmpc_global_thread_num(
694 // CHECK: call void @__kmpc_for_static_init_8(
695 // CHECK: call void @__kmpc_for_static_fini(
696 
697 void loop_with_stmt_expr() {
698 #pragma omp for collapse(2)
699   for (int i = __extension__({float b = 0;b; }); i < __extension__({double c = 1;c; }); i += __extension__({char d = 1; d; }))
700     for (int j = i; j < 4 + i; j++)
701     ;
702 }
703 // CHECK-LABEL: loop_with_stmt_expr
704 // CHECK: call i32 @__kmpc_global_thread_num(
705 // CHECK: call void @__kmpc_for_static_init_8(
706 // CHECK: call void @__kmpc_for_static_fini(
707 
708 
709 // CHECK-LABEL: fint
710 // CHECK: call {{.*}}i32 {{.*}}ftemplate
711 // CHECK: ret i32
712 
713 // CHECK: load i16, i16*
714 // CHECK: store i16 %
715 // CHECK: call void {{.+}}@__kmpc_fork_call(
716 // CHECK: call void @__kmpc_for_static_init_4(
717 template <typename T>
718 T ftemplate() {
719   short aa = 0;
720 
721 #pragma omp parallel for schedule(static, aa)
722   for (int i = 0; i < 100; i++) {
723   }
724   return T();
725 }
726 
727 int fint(void) { return ftemplate<int>(); }
728 
729 #endif // HEADER
730