Clang Project

clang_source_code/test/OpenMP/taskloop_codegen.cpp
1// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s
2// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
3// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s
4
5// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck --check-prefix SIMD-ONLY0 %s
6// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
7// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck --check-prefix SIMD-ONLY0 %s
8// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
9// expected-no-diagnostics
10#ifndef HEADER
11#define HEADER
12
13// CHECK-LABEL: @main
14int main(int argc, char **argv) {
15// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* [[DEFLOC:@.+]])
16// CHECK: call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[DEFLOC]], i32 [[GTID]],
17// CHECK: call i32 @__kmpc_omp_task(%struct.ident_t* [[DEFLOC]], i32 [[GTID]],
18#pragma omp task
19  ;
20// CHECK: call void @__kmpc_taskgroup(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
21// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
22// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
23// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
24// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
25// CHECK: store i64 0, i64* [[DOWN]],
26// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
27// CHECK: store i64 9, i64* [[UP]],
28// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
29// CHECK: store i64 1, i64* [[ST]],
30// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
31// CHECK: call void @__kmpc_taskloop(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 0, i64 0, i8* null)
32// CHECK: call void @__kmpc_end_taskgroup(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
33#pragma omp taskloop priority(argc)
34  for (int i = 0; i < 10; ++i)
35    ;
36// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
37// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
38// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
39// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
40// CHECK: store i64 0, i64* [[DOWN]],
41// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
42// CHECK: store i64 9, i64* [[UP]],
43// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
44// CHECK: store i64 1, i64* [[ST]],
45// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
46// CHECK: [[GRAINSIZE:%.+]] = zext i32 %{{.+}} to i64
47// CHECK: call void @__kmpc_taskloop(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 1, i64 [[GRAINSIZE]], i8* null)
48#pragma omp taskloop nogroup grainsize(argc)
49  for (int i = 0; i < 10; ++i)
50    ;
51// CHECK: call void @__kmpc_taskgroup(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
52// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
53// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
54// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
55// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0
56// CHECK: [[IF_INT:%.+]] = sext i1 [[IF]] to i32
57// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
58// CHECK: store i64 0, i64* [[DOWN]],
59// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
60// CHECK: store i64 %{{.+}}, i64* [[UP]],
61// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
62// CHECK: store i64 1, i64* [[ST]],
63// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
64// CHECK: call void @__kmpc_taskloop(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 2, i64 4, i8* null)
65// CHECK: call void @__kmpc_end_taskgroup(%struct.ident_t* [[DEFLOC]], i32 [[GTID]])
66  int i;
67#pragma omp taskloop if(argc) shared(argc, argv) collapse(2) num_tasks(4)
68  for (i = 0; i < argc; ++i)
69  for (int j = argc; j < argv[argc][argc]; ++j)
70    ;
71}
72
73// CHECK: define internal i32 [[TASK1]](
74// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
75// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
76// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
77// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
78// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
79// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
80// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
81// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
82// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
83// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
84// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
85// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
86// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
87// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
88// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
89// CHECK: br label
90// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
91// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
92// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
93// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
94// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
95// CHECK: load i32, i32* %
96// CHECK: store i32 %
97// CHECK: load i32, i32* %
98// CHECK: add nsw i32 %{{.+}}, 1
99// CHECK: store i32 %{{.+}}, i32* %
100// CHECK: br label %
101// CHECK: ret i32 0
102
103// CHECK: define internal i32 [[TASK2]](
104// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
105// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
106// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
107// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
108// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
109// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
110// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
111// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
112// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
113// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
114// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
115// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
116// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
117// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
118// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
119// CHECK: br label
120// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
121// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
122// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
123// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
124// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
125// CHECK: load i32, i32* %
126// CHECK: store i32 %
127// CHECK: load i32, i32* %
128// CHECK: add nsw i32 %{{.+}}, 1
129// CHECK: store i32 %{{.+}}, i32* %
130// CHECK: br label %
131// CHECK: ret i32 0
132
133// CHECK: define internal i32 [[TASK3]](
134// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
135// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
136// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
137// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
138// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
139// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
140// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
141// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
142// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
143// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
144// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
145// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
146// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
147// CHECK: store i64 [[LB_VAL]], i64* [[CNT:%.+]],
148// CHECK: br label
149// CHECK: ret i32 0
150
151// CHECK-LABEL: @_ZN1SC2Ei
152struct S {
153  int a;
154  S(int c) {
155// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* [[DEFLOC:@.+]])
156// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
157// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
158// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
159// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
160// CHECK: store i64 0, i64* [[DOWN]],
161// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
162// CHECK: store i64 %{{.+}}, i64* [[UP]],
163// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
164// CHECK: store i64 1, i64* [[ST]],
165// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
166// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64
167// CHECK: call void @__kmpc_taskloop(%struct.ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 2, i64 [[NUM_TASKS]], i8* null)
168#pragma omp taskloop shared(c) num_tasks(a)
169    for (a = 0; a < c; ++a)
170      ;
171  }
172} s(1);
173
174// CHECK: define internal i32 [[TASK4]](
175// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
176// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
177// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
178// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
179// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
180// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
181// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
182// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
183// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
184// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
185// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
186// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
187// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
188// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
189// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
190// CHECK: br label
191// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
192// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
193// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
194// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
195// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
196// CHECK: load i32, i32* %
197// CHECK: store i32 %
198// CHECK: load i32, i32* %
199// CHECK: add nsw i32 %{{.+}}, 1
200// CHECK: store i32 %{{.+}}, i32* %
201// CHECK: br label %
202// CHECK: ret i32 0
203
204#endif
205