1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s 2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes 3 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefixes=CHECK-LOAD,OMP50-LOAD %s 4 5 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,OMP45 6 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes 7 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefixes=CHECK-LOAD,OMP45-LOAD %s 8 9 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s 10 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes 11 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s 12 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} 13 // expected-no-diagnostics 14 15 #ifndef HEADER 16 #define HEADER 17 18 // CHECK: [[SSS_INT:.+]] = type { i32 } 19 // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 } 20 21 // OMP45: add 22 void add(short &out, short &in) {} 23 24 #pragma omp declare reduction(my_add : short : add(omp_out, omp_in)) 25 26 // OMP45: define internal void @. 27 // OMP45: call void @{{.+}}add{{.+}}( 28 // OMP45: ret void 29 30 // OMP45: foo_reduction_array 31 void foo_reduction_array() { 32 short y[1]; 33 // OMP45: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( 34 #pragma omp parallel for reduction(my_add : y) 35 for (int i = 0; i < 1; i++) { 36 } 37 } 38 39 // OMP45: define internal void @ 40 41 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in) 42 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 43 // CHECK: [[MUL:%.+]] = mul nsw i32 44 // CHECK-NEXT: store i32 [[MUL]], i32* 45 // CHECK-NEXT: ret void 46 // CHECK-NEXT: } 47 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 48 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 49 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32* 50 // CHECK-LOAD-NEXT: ret void 51 // CHECK-LOAD-NEXT: } 52 53 // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1) 54 // CHECK: sext i8 55 // CHECK: sext i8 56 // CHECK: [[MUL:%.+]] = mul nsw i32 57 // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 58 // CHECK-NEXT: store i8 [[TRUNC]], i8* 59 // CHECK-NEXT: ret void 60 // CHECK-NEXT: } 61 62 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1) 63 // CHECK-LOAD: sext i8 64 // CHECK-LOAD: sext i8 65 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 66 // CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 67 // CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8* 68 // CHECK-LOAD-NEXT: ret void 69 // CHECK-LOAD-NEXT: } 70 71 template <class T> 72 struct SSS { 73 T a; 74 SSS() : a() {} 75 #pragma omp declare reduction(fun : T : omp_out ^= omp_in) initializer(omp_priv = 24 + omp_orig) 76 #pragma omp declare reduction(sssss : T : ssssss(omp_in)) initializer(omp_priv = 18 + omp_orig) 77 static void ssssss(T &x); 78 }; 79 80 SSS<int> d; 81 82 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 83 // CHECK: [[XOR:%.+]] = xor i32 84 // CHECK-NEXT: store i32 [[XOR]], i32* 85 // CHECK-NEXT: ret void 86 // CHECK-NEXT: } 87 88 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 89 // CHECK: [[ADD:%.+]] = add nsw i32 24, 90 // CHECK-NEXT: store i32 [[ADD]], i32* 91 // CHECK-NEXT: ret void 92 // CHECK-NEXT: } 93 94 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 95 // CHECK: call void @_ZN3SSSIiE6ssssssERi(i32* nonnull align {{[0-9]+}} dereferenceable{{.*}}) 96 // CHECK-NEXT: ret void 97 // CHECK-NEXT: } 98 99 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 100 // CHECK: [[ADD:%.+]] = add nsw i32 18, 101 // CHECK-NEXT: store i32 [[ADD]], i32* 102 // CHECK-NEXT: ret void 103 // CHECK-NEXT: } 104 105 template <typename T> 106 void init(T &lhs, T &rhs) {} 107 108 #pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) 109 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1) 110 // CHECK: call void @llvm.memcpy 111 // CHECK-NEXT: ret void 112 // CHECK-NEXT: } 113 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1) 114 // CHECK: call {{.*}}void @_Z4initI3SSSIiEEvRT_S3_( 115 // CHECK-NEXT: ret void 116 // CHECK-NEXT: } 117 118 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1) 119 // CHECK-LOAD: call void @llvm.memcpy 120 // CHECK-LOAD-NEXT: ret void 121 // CHECK-LOAD-NEXT: } 122 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1) 123 // CHECK-LOAD: call {{.*}}void @_Z4initI3SSSIiEEvRT_S3_( 124 // CHECK-LOAD-NEXT: ret void 125 // CHECK-LOAD-NEXT: } 126 127 // CHECK: define {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(%struct.SSS* {{.+}}, %struct.SSS* {{.+}}) 128 // CHECK-LOAD: define {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(%struct.SSS* {{.+}}, %struct.SSS* {{.+}}) 129 130 template <typename T> 131 T foo(T a) { 132 #pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig) 133 { 134 #pragma omp declare reduction(fun : T : omp_out /= omp_in) initializer(omp_priv = 11 - omp_orig) 135 } 136 return a; 137 } 138 139 struct Summary { 140 void merge(const Summary& other) {} 141 }; 142 143 template <typename K> 144 void work() { 145 Summary global_summary; 146 #pragma omp declare reduction(+ : Summary : omp_out.merge(omp_in)) 147 #pragma omp parallel for reduction(+ : global_summary) 148 for (int k = 1; k <= 100; ++k) { 149 } 150 } 151 152 struct A {}; 153 154 155 // CHECK-LABEL: @main 156 int main() { 157 int i = 0; 158 SSS<int> sss; 159 #pragma omp parallel reduction(SSS < int > ::fun : i) 160 { 161 i += 1; 162 } 163 #pragma omp parallel reduction(::fun : sss) 164 { 165 } 166 #pragma omp declare reduction(fun : SSS < int > : init(omp_out, omp_in)) 167 #pragma omp parallel reduction(fun : sss) 168 { 169 } 170 // CHECK: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( 171 // CHECK: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( 172 // CHECK: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^ ]+]] 173 // CHECK-LABEL: work 174 work<A>(); 175 // CHECK-LABEL: foo 176 return foo(15); 177 } 178 179 // CHECK: define internal {{.*}}void [[REGION]]( 180 // CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS, 181 // CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]]) 182 // CHECK-NOT: {{call |invoke }} 183 // CHECK: call {{.*}}i32 @__kmpc_reduce_nowait( 184 185 // CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 186 // CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 187 188 // OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 189 // OMP45-LOAD: [[XOR:%.+]] = xor i32 190 // OMP45-LOAD-NEXT: store i32 [[XOR]], i32* 191 // OMP45-LOAD-NEXT: ret void 192 // OMP45-LOAD-NEXT: } 193 194 // OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 195 // OMP45-LOAD: [[ADD:%.+]] = add nsw i32 24, 196 // OMP45-LOAD-NEXT: store i32 [[ADD]], i32* 197 // OMP45-LOAD-NEXT: ret void 198 // OMP45-LOAD-NEXT: } 199 200 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 201 // CHECK: [[ADD:%.+]] = add nsw i32 202 // CHECK-NEXT: store i32 [[ADD]], i32* 203 // CHECK-NEXT: ret void 204 // CHECK-NEXT: } 205 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 206 // CHECK-LOAD: [[ADD:%.+]] = add nsw i32 207 // CHECK-LOAD-NEXT: store i32 [[ADD]], i32* 208 // CHECK-LOAD-NEXT: ret void 209 // CHECK-LOAD-NEXT: } 210 211 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 212 // CHECK: [[MUL:%.+]] = mul nsw i32 15, 213 // CHECK-NEXT: store i32 [[MUL]], i32* 214 // CHECK-NEXT: ret void 215 // CHECK-NEXT: } 216 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 217 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 15, 218 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32* 219 // CHECK-LOAD-NEXT: ret void 220 // CHECK-LOAD-NEXT: } 221 222 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 223 // CHECK: [[DIV:%.+]] = sdiv i32 224 // CHECK-NEXT: store i32 [[DIV]], i32* 225 // CHECK-NEXT: ret void 226 // CHECK-NEXT: } 227 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 228 // CHECK-LOAD: [[DIV:%.+]] = sdiv i32 229 // CHECK-LOAD-NEXT: store i32 [[DIV]], i32* 230 // CHECK-LOAD-NEXT: ret void 231 // CHECK-LOAD-NEXT: } 232 233 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 234 // CHECK: [[SUB:%.+]] = sub nsw i32 11, 235 // CHECK-NEXT: store i32 [[SUB]], i32* 236 // CHECK-NEXT: ret void 237 // CHECK-NEXT: } 238 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) 239 // CHECK-LOAD: [[SUB:%.+]] = sub nsw i32 11, 240 // CHECK-LOAD-NEXT: store i32 [[SUB]], i32* 241 // CHECK-LOAD-NEXT: ret void 242 // CHECK-LOAD-NEXT: } 243 244 #endif 245