1 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
3 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
4 
5 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
6 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
7 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
8 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
9 
10 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -disable-O0-optnone -o - | FileCheck %s --check-prefix=WOPT
11 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
12 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
13 // RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
14 
15 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
16 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
17 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
18 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
19 
20 // expected-no-diagnostics
21 #ifndef HEADER
22 #define HEADER
23 
24 void fn1();
25 void fn2();
26 void fn3();
27 void fn4();
28 void fn5();
29 void fn6();
30 
31 int Arg;
32 
33 // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test
gtid_test()34 void gtid_test() {
35 // CHECK:  call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void
36 #pragma omp parallel
37 #pragma omp parallel if (parallel: false)
38   gtid_test();
39 // CHECK: ret void
40 }
41 
42 // CHECK: define internal {{.*}}void [[GTID_TEST_REGION1]](i{{.+}}* noalias [[GTID_PARAM:%.+]], i32* noalias
43 // CHECK: store i32 0, i32* [[BND_ZERO_ADDR:%.+]],
44 // CHECK: store i{{[0-9]+}}* [[GTID_PARAM]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]],
45 // CHECK: [[GTID_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
46 // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_ADDR]]
47 // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]])
48 // CHECK: [[GTID_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
49 // CHECK: call void [[GTID_TEST_REGION2:@.+]](i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}* [[BND_ZERO_ADDR]]
50 // CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]])
51 // CHECK: ret void
52 
53 // CHECK: define internal {{.*}}void [[GTID_TEST_REGION2]](
54 // CHECK: call {{.*}}void @{{.+}}gtid_test
55 // CHECK: ret void
56 
57 template <typename T>
tmain(T Arg)58 int tmain(T Arg) {
59 #pragma omp parallel if (true)
60   fn1();
61 #pragma omp parallel if (false)
62   fn2();
63 #pragma omp parallel if (parallel: Arg)
64   fn3();
65   return 0;
66 }
67 
68 // CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main()
main()69 int main() {
70 // CHECK: store i32 0, i32* [[BND_ZERO_ADDR2:%.+]],
71 // CHECK: store i32 0, i32* [[BND_ZERO_ADDR1:%.+]],
72 // CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num(
73 // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN4:@.+]] to void
74 #pragma omp parallel if (true)
75   fn4();
76 // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
77 // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]],
78 // CHECK: call void [[CAP_FN5:@.+]](i32* [[GTID_ADDR]], i32* [[BND_ZERO_ADDR1]])
79 // CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
80 #pragma omp parallel if (false)
81   fn5();
82 
83 // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
84 // CHECK: [[OMP_THEN]]
85 // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN6:@.+]] to void
86 // CHECK: br label %[[OMP_END:.+]]
87 // CHECK: [[OMP_ELSE]]
88 // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
89 // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]],
90 // CHECK: call void [[CAP_FN6]](i32* [[GTID_ADDR]], i32* [[BND_ZERO_ADDR2]])
91 // CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
92 // CHECK: br label %[[OMP_END]]
93 // CHECK: [[OMP_END]]
94 #pragma omp parallel if (Arg)
95   fn6();
96   // CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain
97   return tmain(Arg);
98 }
99 
100 // WOPT:     noinline
101 // WOPT-NOT: optnone
102 // CHECK: define internal {{.*}}void [[CAP_FN4]]
103 // CHECK: call {{.*}}void @{{.+}}fn4
104 // CHECK: ret void
105 
106 // WOPT:     noinline
107 // WOPT-NOT: optnone
108 // CHECK: define internal {{.*}}void [[CAP_FN5]]
109 // CHECK: call {{.*}}void @{{.+}}fn5
110 // CHECK: ret void
111 
112 // WOPT:     noinline
113 // WOPT-NOT: optnone
114 // CHECK: define internal {{.*}}void [[CAP_FN6]]
115 // CHECK: call {{.*}}void @{{.+}}fn6
116 // CHECK: ret void
117 
118 // CHECK-LABEL: define {{.+}} @{{.+}}tmain
119 // CHECK: store i32 0, i32* [[BND_ZERO_ADDR2:%.+]],
120 // CHECK: store i32 0, i32* [[BND_ZERO_ADDR1:%.+]],
121 // CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num(
122 // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN1:@.+]] to void
123 // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
124 // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]],
125 // CHECK: call void [[CAP_FN2:@.+]](i32* [[GTID_ADDR]], i32* [[BND_ZERO_ADDR1]])
126 // CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
127 // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
128 // CHECK: [[OMP_THEN]]
129 // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN3:@.+]] to void
130 // CHECK: br label %[[OMP_END:.+]]
131 // CHECK: [[OMP_ELSE]]
132 // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
133 // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]],
134 // CHECK: call void [[CAP_FN3]](i32* [[GTID_ADDR]], i32* [[BND_ZERO_ADDR2]])
135 // CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]])
136 // CHECK: br label %[[OMP_END]]
137 // CHECK: [[OMP_END]]
138 
139 // WOPT:     noinline
140 // WOPT-NOT: optnone
141 // CHECK: define internal {{.*}}void [[CAP_FN1]]
142 // CHECK: call {{.*}}void @{{.+}}fn1
143 // CHECK: ret void
144 
145 // WOPT:     noinline
146 // WOPT-NOT: optnone
147 // CHECK: define internal {{.*}}void [[CAP_FN2]]
148 // CHECK: call {{.*}}void @{{.+}}fn2
149 // CHECK: ret void
150 
151 // WOPT:     noinline
152 // WOPT-NOT: optnone
153 // CHECK: define internal {{.*}}void [[CAP_FN3]]
154 // CHECK: call {{.*}}void @{{.+}}fn3
155 // CHECK: ret void
156 
157 #endif
158