• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-optzns | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-optzns
3 // RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-optzns | FileCheck --check-prefix=CHECK-LOAD %s
4 // expected-no-diagnostics
5 
6 #ifndef HEADER
7 #define HEADER
8 
9 // CHECK: [[SSS_INT:.+]] = type { i32 }
10 // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
11 
12 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
13 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
14 // CHECK: [[MUL:%.+]] = mul nsw i32
15 // CHECK-NEXT: store i32 [[MUL]], i32*
16 // CHECK-NEXT: ret void
17 // CHECK-NEXT: }
18 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
19 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
20 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
21 // CHECK-LOAD-NEXT: ret void
22 // CHECK-LOAD-NEXT: }
23 
24 // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
25 // CHECK: sext i8
26 // CHECK: sext i8
27 // CHECK: [[MUL:%.+]] = mul nsw i32
28 // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
29 // CHECK-NEXT: store i8 [[TRUNC]], i8*
30 // CHECK-NEXT: ret void
31 // CHECK-NEXT: }
32 
33 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
34 // CHECK-LOAD: sext i8
35 // CHECK-LOAD: sext i8
36 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
37 // CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
38 // CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8*
39 // CHECK-LOAD-NEXT: ret void
40 // CHECK-LOAD-NEXT: }
41 
42 template <class T>
43 struct SSS {
44   T a;
SSSSSS45   SSS() : a() {}
46 #pragma omp declare reduction(fun : T : omp_out ^= omp_in) initializer(omp_priv = 24 + omp_orig)
47 };
48 
49 SSS<int> d;
50 
51 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
52 // CHECK: [[XOR:%.+]] = xor i32
53 // CHECK-NEXT: store i32 [[XOR]], i32*
54 // CHECK-NEXT: ret void
55 // CHECK-NEXT: }
56 
57 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
58 // CHECK: [[ADD:%.+]] = add nsw i32 24,
59 // CHECK-NEXT: store i32 [[ADD]], i32*
60 // CHECK-NEXT: ret void
61 // CHECK-NEXT: }
62 
63 // CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
64 // CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
init(SSS<int> & lhs,SSS<int> & rhs)65 void init(SSS<int> &lhs, SSS<int> &rhs) {}
66 
67 #pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
68 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
69 // CHECK: call void @llvm.memcpy
70 // CHECK-NEXT: ret void
71 // CHECK-NEXT: }
72 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
73 // CHECK: call {{.*}}void [[INIT]](
74 // CHECK-NEXT: ret void
75 // CHECK-NEXT: }
76 
77 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
78 // CHECK-LOAD: call void @llvm.memcpy
79 // CHECK-LOAD-NEXT: ret void
80 // CHECK-LOAD-NEXT: }
81 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
82 // CHECK-LOAD: call {{.*}}void [[INIT]](
83 // CHECK-LOAD-NEXT: ret void
84 // CHECK-LOAD-NEXT: }
85 
86 template <typename T>
foo(T a)87 T foo(T a) {
88 #pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig)
89   {
90 #pragma omp declare reduction(fun : T : omp_out /= omp_in) initializer(omp_priv = 11 - omp_orig)
91   }
92   return a;
93 }
94 
95 // CHECK-LABEL: @main
main()96 int main() {
97   int i = 0;
98   SSS<int> sss;
99 #pragma omp parallel reduction(SSS < int > ::fun : i)
100   {
101     i += 1;
102   }
103 #pragma omp parallel reduction(::fun : sss)
104   {
105   }
106 #pragma omp declare reduction(fun : SSS < int > : init(omp_out, omp_in))
107 #pragma omp parallel reduction(fun : sss)
108   {
109   }
110   // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
111   // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
112   // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^ ]+]]
113   // CHECK-LABEL: foo
114   return foo(15);
115 }
116 
117 // CHECK: define internal {{.*}}void [[REGION]](
118 // CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS,
119 // CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]])
120 // CHECK-NOT: {{call |invoke }}
121 // CHECK: call {{.*}}i32 @__kmpc_reduce_nowait(
122 
123 // CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32
124 // CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32
125 
126 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
127 // CHECK-LOAD: [[XOR:%.+]] = xor i32
128 // CHECK-LOAD-NEXT: store i32 [[XOR]], i32*
129 // CHECK-LOAD-NEXT: ret void
130 // CHECK-LOAD-NEXT: }
131 
132 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
133 // CHECK-LOAD: [[ADD:%.+]] = add nsw i32 24,
134 // CHECK-LOAD-NEXT: store i32 [[ADD]], i32*
135 // CHECK-LOAD-NEXT: ret void
136 // CHECK-LOAD-NEXT: }
137 
138 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
139 // CHECK: [[ADD:%.+]] = add nsw i32
140 // CHECK-NEXT: store i32 [[ADD]], i32*
141 // CHECK-NEXT: ret void
142 // CHECK-NEXT: }
143 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
144 // CHECK-LOAD: [[ADD:%.+]] = add nsw i32
145 // CHECK-LOAD-NEXT: store i32 [[ADD]], i32*
146 // CHECK-LOAD-NEXT: ret void
147 // CHECK-LOAD-NEXT: }
148 
149 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
150 // CHECK: [[MUL:%.+]] = mul nsw i32 15,
151 // CHECK-NEXT: store i32 [[MUL]], i32*
152 // CHECK-NEXT: ret void
153 // CHECK-NEXT: }
154 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
155 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 15,
156 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
157 // CHECK-LOAD-NEXT: ret void
158 // CHECK-LOAD-NEXT: }
159 
160 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
161 // CHECK: [[DIV:%.+]] = sdiv i32
162 // CHECK-NEXT: store i32 [[DIV]], i32*
163 // CHECK-NEXT: ret void
164 // CHECK-NEXT: }
165 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
166 // CHECK-LOAD: [[DIV:%.+]] = sdiv i32
167 // CHECK-LOAD-NEXT: store i32 [[DIV]], i32*
168 // CHECK-LOAD-NEXT: ret void
169 // CHECK-LOAD-NEXT: }
170 
171 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
172 // CHECK: [[SUB:%.+]] = sub nsw i32 11,
173 // CHECK-NEXT: store i32 [[SUB]], i32*
174 // CHECK-NEXT: ret void
175 // CHECK-NEXT: }
176 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
177 // CHECK-LOAD: [[SUB:%.+]] = sub nsw i32 11,
178 // CHECK-LOAD-NEXT: store i32 [[SUB]], i32*
179 // CHECK-LOAD-NEXT: ret void
180 // CHECK-LOAD-NEXT: }
181 
182 #endif
183