blob: 2b610a270dd97d2659745cabb44fdadeb78345a3 [file] [log] [blame]
Alexey Bataev8b427062016-05-25 12:36:08 +00001// 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 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
Alexey Bataeva8a9153a2017-12-29 18:07:07 +00004
5// 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
6// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
7// 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
8// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
Alexey Bataev8b427062016-05-25 12:36:08 +00009// expected-no-diagnostics
10
11#ifndef HEADER
12#define HEADER
13
14// CHECK: [[KMP_DIM:%.+]] = type { i64, i64, i64 }
15extern int n;
16int a[10], b[10], c[10], d[10];
17void foo();
18
Alexey Bataev0d8fcdf2019-03-14 20:36:00 +000019// CHECK-LABEL:bar
20void bar() {
21 int i,j;
22// CHECK: call void @__kmpc_doacross_init(
23// CHECK: call void @__kmpc_doacross_fini(
24#pragma omp parallel for ordered(2)
25 for (i = 0; i < n; ++i)
26 for (j = 0; j < n; ++j)
27 a[i] = b[i] + 1;
28}
29
Alexey Bataev8b427062016-05-25 12:36:08 +000030// CHECK-LABEL: @main()
31int main() {
32 int i;
Alexey Bataevf138fda2018-08-13 19:04:24 +000033// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]],
Alexey Bataev8b427062016-05-25 12:36:08 +000034// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
35// CHECK: icmp
36// CHECK-NEXT: br i1 %
Alexey Bataevf138fda2018-08-13 19:04:24 +000037// CHECK: [[CAST:%.+]] = bitcast [1 x [[KMP_DIM]]]* [[DIMS]] to i8*
Daniel Neilson6e938ef2018-01-19 17:12:54 +000038// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, i64 24, i1 false)
Alexey Bataevf138fda2018-08-13 19:04:24 +000039// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
40// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], i32 0, i32 1
Alexey Bataev8b427062016-05-25 12:36:08 +000041// CHECK: store i64 %{{.+}}, i64* %
Alexey Bataevf138fda2018-08-13 19:04:24 +000042// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], i32 0, i32 2
Alexey Bataev8b427062016-05-25 12:36:08 +000043// CHECK: store i64 1, i64* %
Alexey Bataevf138fda2018-08-13 19:04:24 +000044// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
45// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
Alexey Bataev8b427062016-05-25 12:36:08 +000046// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
Alexey Bataevf6a53d62019-03-18 18:40:00 +000047// CHECK: call void @__kmpc_for_static_init_4(%struct.ident_t* @{{.+}}, i32 [[GTID]], i32 33, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
Alexey Bataev8b427062016-05-25 12:36:08 +000048#pragma omp for ordered(1)
Alexey Bataev0d8fcdf2019-03-14 20:36:00 +000049 for (int i = 0; i < n; ++i) {
Alexey Bataev8b427062016-05-25 12:36:08 +000050 a[i] = b[i] + 1;
51 foo();
52// CHECK: invoke void [[FOO:.+]](
Alexey Bataevf138fda2018-08-13 19:04:24 +000053// CHECK: load i32, i32* [[I:%.+]],
54// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
55// CHECK-NEXT: sdiv i32 %{{.+}}, 1
Alexey Bataev8b427062016-05-25 12:36:08 +000056// CHECK-NEXT: sext i32 %{{.+}} to i64
Alexey Bataevf138fda2018-08-13 19:04:24 +000057// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x i64]* [[CNT:%.+]], i64 0, i64 0
58// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
59// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x i64]* [[CNT]], i64 0, i64 0
Alexey Bataev8b427062016-05-25 12:36:08 +000060// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
61#pragma omp ordered depend(source)
62 c[i] = c[i] + 1;
63 foo();
64// CHECK: invoke void [[FOO]]
Alexey Bataevf138fda2018-08-13 19:04:24 +000065// CHECK: load i32, i32* [[I]],
Alexey Bataev8b427062016-05-25 12:36:08 +000066// CHECK-NEXT: sub nsw i32 %{{.+}}, 2
Alexey Bataevf138fda2018-08-13 19:04:24 +000067// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
68// CHECK-NEXT: sdiv i32 %{{.+}}, 1
Alexey Bataev8b427062016-05-25 12:36:08 +000069// CHECK-NEXT: sext i32 %{{.+}} to i64
Alexey Bataevf138fda2018-08-13 19:04:24 +000070// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x i64]* [[CNT:%.+]], i64 0, i64 0
71// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
72// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x i64]* [[CNT]], i64 0, i64 0
Alexey Bataev8b427062016-05-25 12:36:08 +000073// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
74#pragma omp ordered depend(sink : i - 2)
75 d[i] = a[i - 2];
76 }
77 // CHECK: landingpad
78 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
79 // CHECK: br label %
80
81 // CHECK: call void @__kmpc_for_static_fini(
82 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
83 // CHECK: ret i32 0
84 return 0;
85}
86
87// CHECK: define {{.+}}TestStruct
88template <typename T>
89struct TestStruct {
90 static const int M = 10;
91 static const int N = 20;
92 T i;
93 T a[N][M];
94 T b[N][M];
95 T foo(T, T);
96 T bar(T, T, T);
97 void baz(T, T);
98 TestStruct() {
Alexey Bataevf138fda2018-08-13 19:04:24 +000099// CHECK: [[DIMS:%.+]] = alloca [2 x [[KMP_DIM]]],
Alexey Bataev8b427062016-05-25 12:36:08 +0000100// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
Alexey Bataevf138fda2018-08-13 19:04:24 +0000101// CHECK: [[CAST:%.+]] = bitcast [2 x [[KMP_DIM]]]* [[DIMS]] to i8*
102// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, i64 48, i1 false)
103// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
104// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], i32 0, i32 1
105// CHECK: store i64 10, i64* %
106// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], i32 0, i32 2
Alexey Bataev0ce63602018-08-13 14:05:43 +0000107// CHECK: store i64 1, i64* %
Alexey Bataevf138fda2018-08-13 19:04:24 +0000108// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 1
109// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], i32 0, i32 1
110// CHECK: store i64 %{{.+}}, i64* %
111// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], i32 0, i32 2
112// CHECK: store i64 1, i64* %
113// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
114// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
115// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 2, i8* [[CAST]])
Alexey Bataevf6a53d62019-03-18 18:40:00 +0000116// CHECK: call void @__kmpc_for_static_init_4(%struct.ident_t* @{{.+}}, i32 [[GTID]], i32 33, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
Alexey Bataev8b427062016-05-25 12:36:08 +0000117#pragma omp for ordered(2)
118 for (T j = 0; j < M; j++)
119 for (i = 0; i < n; i += 2) {
120 a[i][j] = foo(i, j);
121// CHECK: invoke {{.+TestStruct.+foo}}
Alexey Bataevf138fda2018-08-13 19:04:24 +0000122// CHECK: load i32*, i32** %
123// CHECK: load i32, i32* %
124// CHECK: load i32, i32* %
125// CHECK: load i32, i32* [[J:%.+]],
126// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
127// CHECK-NEXT: sdiv i32 %{{.+}}, 1
Alexey Bataev0ce63602018-08-13 14:05:43 +0000128// CHECK-NEXT: sext i32 %{{.+}} to i64
Alexey Bataevf138fda2018-08-13 19:04:24 +0000129// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT:%.+]], i64 0, i64 0
Alexey Bataev0ce63602018-08-13 14:05:43 +0000130// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
Alexey Bataevf138fda2018-08-13 19:04:24 +0000131// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF:%.+]],
132// CHECK-NEXT: load i32, i32* [[I]],
133// CHECK-NEXT: sub nsw i32 %{{.+}}, 2
134// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
135// CHECK-NEXT: sdiv i32 %{{.+}}, 2
136// CHECK-NEXT: sext i32 %{{.+}} to i64
137// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT]], i64 0, i64 1
138// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
139// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT]], i64 0, i64 0
140// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
141// CHECK-NEXT: load i32, i32* [[J:%.+]],
142// CHECK-NEXT: sub nsw i32 %{{.+}}, 1
143// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
144// CHECK-NEXT: sdiv i32 %{{.+}}, 1
145// CHECK-NEXT: sext i32 %{{.+}} to i64
146// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT:%.+]], i64 0, i64 0
147// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
148// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF]],
149// CHECK-NEXT: load i32, i32* [[I]],
150// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
151// CHECK-NEXT: sdiv i32 %{{.+}}, 2
152// CHECK-NEXT: sext i32 %{{.+}} to i64
153// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT]], i64 0, i64 1
154// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
155// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT]], i64 0, i64 0
Alexey Bataev8b427062016-05-25 12:36:08 +0000156// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
157#pragma omp ordered depend(sink : j, i - 2) depend(sink : j - 1, i)
158 b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]);
159// CHECK: invoke {{.+TestStruct.+bar}}
Alexey Bataevf138fda2018-08-13 19:04:24 +0000160// CHECK: load i32*, i32** %
161// CHECK: load i32, i32* %
162// CHECK: load i32, i32* %
163// CHECK: load i32, i32* [[J]],
164// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
165// CHECK-NEXT: sdiv i32 %{{.+}}, 1
166// CHECK-NEXT: sext i32 %{{.+}} to i64
167// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT:%.+]], i64 0, i64 0
Alexey Bataev8b427062016-05-25 12:36:08 +0000168// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
Alexey Bataevf138fda2018-08-13 19:04:24 +0000169// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF]],
170// CHECK-NEXT: load i32, i32* [[I]],
171// CHECK-NEXT: sub nsw i32 %{{.+}}, 0
172// CHECK-NEXT: sdiv i32 %{{.+}}, 2
173// CHECK-NEXT: sext i32 %{{.+}} to i64
174// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT]], i64 0, i64 1
175// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]],
176// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[CNT]], i64 0, i64 0
Alexey Bataev8b427062016-05-25 12:36:08 +0000177// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
178#pragma omp ordered depend(source)
179 baz(a[i][j], b[i][j]);
180 }
181 }
182 // CHECK: landingpad
183 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
184 // CHECK: br label %
185
186 // CHECK: call void @__kmpc_for_static_fini(
187 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
188 // CHECK: ret
189};
190
191TestStruct<int> s;
192#endif // HEADER