blob: 28b02c35358be83ab8be3adde39b7307701efc6d [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 Bataev8b427062016-05-25 12:36:08 +00004// expected-no-diagnostics
5
6#ifndef HEADER
7#define HEADER
8
9// CHECK: [[KMP_DIM:%.+]] = type { i64, i64, i64 }
10extern int n;
11int a[10], b[10], c[10], d[10];
12void foo();
13
14// CHECK-LABEL: @main()
15int main() {
16 int i;
17// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
18// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
19// CHECK: icmp
20// CHECK-NEXT: br i1 %
21// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
22// CHECK: call void @llvm.memset.p0i8.i64(i8* [[CAST]], i8 0, i64 24, i32 8, i1 false)
23// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1
24// CHECK: store i64 %{{.+}}, i64* %
25// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2
26// CHECK: store i64 1, i64* %
27// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
28// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
29// CHECK: call void @__kmpc_for_static_init_4(
30#pragma omp for ordered(1)
31 for (i = 0; i < n; ++i) {
32 a[i] = b[i] + 1;
33 foo();
34// CHECK: invoke void [[FOO:.+]](
35// CHECK: load i32, i32* [[CNT:%.+]],
36// CHECK-NEXT: sext i32 %{{.+}} to i64
37// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
38// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
39#pragma omp ordered depend(source)
40 c[i] = c[i] + 1;
41 foo();
42// CHECK: invoke void [[FOO]]
43// CHECK: load i32, i32* [[CNT]],
44// CHECK-NEXT: sub nsw i32 %{{.+}}, 2
45// CHECK-NEXT: sext i32 %{{.+}} to i64
46// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
47// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
48#pragma omp ordered depend(sink : i - 2)
49 d[i] = a[i - 2];
50 }
51 // CHECK: landingpad
52 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
53 // CHECK: br label %
54
55 // CHECK: call void @__kmpc_for_static_fini(
56 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
57 // CHECK: ret i32 0
58 return 0;
59}
60
61// CHECK: define {{.+}}TestStruct
62template <typename T>
63struct TestStruct {
64 static const int M = 10;
65 static const int N = 20;
66 T i;
67 T a[N][M];
68 T b[N][M];
69 T foo(T, T);
70 T bar(T, T, T);
71 void baz(T, T);
72 TestStruct() {
73// CHECK: [[CNT:%.+]] = alloca i64,
74// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
75// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
76// CHECK: icmp
77// CHECK-NEXT: br i1 %
78// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
79// CHECK: call void @llvm.memset.p0i8.i64(i8* [[CAST]], i8 0, i64 24, i32 8, i1 false)
80// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1
81// CHECK: store i64 %{{.+}}, i64* %
82// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2
83// CHECK: store i64 1, i64* %
84// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
85// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
86// CHECK: call void @__kmpc_for_static_init_8(
87#pragma omp for ordered(2)
88 for (T j = 0; j < M; j++)
89 for (i = 0; i < n; i += 2) {
90 a[i][j] = foo(i, j);
91// CHECK: invoke {{.+TestStruct.+foo}}
92// CHECK: load i64, i64* [[CNT]],
93// CHECK-NEXT: sub nsw i64 %{{.+}}, 1
94// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
95// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
96// CHECK-NEXT: load i64, i64* [[CNT]],
97// CHECK-NEXT: load i32, i32* %
98// CHECK-NEXT: mul nsw i32 1, %
99// CHECK-NEXT: sext i32 %{{.+}} to i64
100// CHECK-NEXT: sub nsw i64 %
101// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
102// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
103#pragma omp ordered depend(sink : j, i - 2) depend(sink : j - 1, i)
104 b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]);
105// CHECK: invoke {{.+TestStruct.+bar}}
106// CHECK: load i64, i64* [[CNT]],
107// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
108// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
109#pragma omp ordered depend(source)
110 baz(a[i][j], b[i][j]);
111 }
112 }
113 // CHECK: landingpad
114 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
115 // CHECK: br label %
116
117 // CHECK: call void @__kmpc_for_static_fini(
118 // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
119 // CHECK: ret
120};
121
122TestStruct<int> s;
123#endif // HEADER