245 lines · cpp
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 %s2// 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-passes3// 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 %s4 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,OMP456// 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-passes7// 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 %s8 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 %s10// 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-passes11// 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 %s12// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}13// expected-no-diagnostics14 15#ifndef HEADER16#define HEADER17 18// CHECK: [[SSS_INT:.+]] = type { i32 }19// CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }20 21// OMP45: add22void 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 void29 30// OMP45: foo_reduction_array31void foo_reduction_array() {32 short y[1];33 // OMP45: call void (ptr, i32, ptr, ...) @__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 @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)43// CHECK: [[MUL:%.+]] = mul nsw i32 %{{.+}}, %{{.+}}44// CHECK-NEXT: store i32 [[MUL]], ptr45// CHECK-NEXT: ret void46// CHECK-NEXT: }47// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)48// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 %{{.+}}, %{{.+}}49// CHECK-LOAD-NEXT: store i32 [[MUL]], ptr50// CHECK-LOAD-NEXT: ret void51// CHECK-LOAD-NEXT: }52 53// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)54// CHECK: sext i855// CHECK: sext i856// CHECK: [[MUL:%.+]] = mul nsw i32 %{{.+}}, %{{.+}}57// CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i858// CHECK-NEXT: store i8 [[TRUNC]], ptr59// CHECK-NEXT: ret void60// CHECK-NEXT: }61 62// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)63// CHECK-LOAD: sext i864// CHECK-LOAD: sext i865// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 %{{.+}}, %{{.+}}66// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i867// CHECK-LOAD-NEXT: store i8 [[TRUNC]], ptr68// CHECK-LOAD-NEXT: ret void69// CHECK-LOAD-NEXT: }70 71template <class T>72struct 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 80SSS<int> d;81 82// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)83// CHECK: [[XOR:%.+]] = xor i32 %{{.+}}, %{{.+}}84// CHECK-NEXT: store i32 [[XOR]], ptr85// CHECK-NEXT: ret void86// CHECK-NEXT: }87 88// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)89// CHECK: [[ADD:%.+]] = add nsw i32 24, %{{.+}}90// CHECK-NEXT: store i32 [[ADD]], ptr91// CHECK-NEXT: ret void92// CHECK-NEXT: }93 94// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)95// CHECK: call void @_ZN3SSSIiE6ssssssERi(ptr noundef nonnull align {{[0-9]+}} dereferenceable{{.*}})96// CHECK-NEXT: ret void97// CHECK-NEXT: }98 99// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)100// CHECK: [[ADD:%.+]] = add nsw i32 18, %{{.+}}101// CHECK-NEXT: store i32 [[ADD]], ptr102// CHECK-NEXT: ret void103// CHECK-NEXT: }104 105template <typename T>106void 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 @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)110// CHECK: call void @llvm.memcpy111// CHECK-NEXT: ret void112// CHECK-NEXT: }113// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)114// CHECK: call {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(115// CHECK-NEXT: ret void116// CHECK-NEXT: }117 118// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)119// CHECK-LOAD: call void @llvm.memcpy120// CHECK-LOAD-NEXT: ret void121// CHECK-LOAD-NEXT: }122// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)123// CHECK-LOAD: call {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(124// CHECK-LOAD-NEXT: ret void125// CHECK-LOAD-NEXT: }126 127// CHECK: define {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(ptr {{.+}}, ptr {{.+}})128// CHECK-LOAD: define {{.*}}void @_Z4initI3SSSIiEEvRT_S3_(ptr {{.+}}, ptr {{.+}})129 130template <typename T>131T 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 139struct Summary {140 void merge(const Summary& other) {}141};142 143template <typename K>144void 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 152struct A {};153 154 155// CHECK-LABEL: @main156int 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 (ptr, i32, ptr, ...) @__kmpc_fork_call(171 // CHECK: call {{.*}}void (ptr, i32, ptr, ...) @__kmpc_fork_call(172 // CHECK: call {{.*}}void (ptr, i32, ptr, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^,]+]]173 // CHECK-LABEL: work174 work<A>();175 // CHECK-LABEL: foo176 return foo(15);177}178 179// CHECK: define internal {{.*}}void [[REGION]](180// CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS,181// CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(ptr {{[^,]*}} [[SSS_PRIV]])182// CHECK-NOT: {{call |invoke }}183// CHECK: call {{.*}}i32 @__kmpc_reduce_nowait(184 185// CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32186// CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32187 188// OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)189// OMP45-LOAD: [[XOR:%.+]] = xor i32 %{{.+}}, %{{.+}}190// OMP45-LOAD-NEXT: store i32 [[XOR]], ptr191// OMP45-LOAD-NEXT: ret void192// OMP45-LOAD-NEXT: }193 194// OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)195// OMP45-LOAD: [[ADD:%.+]] = add nsw i32 24, %{{.+}}196// OMP45-LOAD-NEXT: store i32 [[ADD]], ptr197// OMP45-LOAD-NEXT: ret void198// OMP45-LOAD-NEXT: }199 200// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)201// CHECK: [[ADD:%.+]] = add nsw i32 %{{.+}}, %{{.+}}202// CHECK-NEXT: store i32 [[ADD]], ptr203// CHECK-NEXT: ret void204// CHECK-NEXT: }205// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)206// CHECK-LOAD: [[ADD:%.+]] = add nsw i32 %{{.+}}, %{{.+}}207// CHECK-LOAD-NEXT: store i32 [[ADD]], ptr208// CHECK-LOAD-NEXT: ret void209// CHECK-LOAD-NEXT: }210 211// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)212// CHECK: [[MUL:%.+]] = mul nsw i32 15, %{{.+}}213// CHECK-NEXT: store i32 [[MUL]], ptr214// CHECK-NEXT: ret void215// CHECK-NEXT: }216// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)217// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 15, %{{.+}}218// CHECK-LOAD-NEXT: store i32 [[MUL]], ptr219// CHECK-LOAD-NEXT: ret void220// CHECK-LOAD-NEXT: }221 222// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)223// CHECK: [[DIV:%.+]] = sdiv i32 %{{.+}}, %{{.+}}224// CHECK-NEXT: store i32 [[DIV]], ptr225// CHECK-NEXT: ret void226// CHECK-NEXT: }227// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)228// CHECK-LOAD: [[DIV:%.+]] = sdiv i32 %{{.+}}, %{{.+}}229// CHECK-LOAD-NEXT: store i32 [[DIV]], ptr230// CHECK-LOAD-NEXT: ret void231// CHECK-LOAD-NEXT: }232 233// CHECK: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)234// CHECK: [[SUB:%.+]] = sub nsw i32 11, %{{.+}}235// CHECK-NEXT: store i32 [[SUB]], ptr236// CHECK-NEXT: ret void237// CHECK-NEXT: }238// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(ptr noalias noundef %0, ptr noalias noundef %1)239// CHECK-LOAD: [[SUB:%.+]] = sub nsw i32 11, %{{.+}}240// CHECK-LOAD-NEXT: store i32 [[SUB]], ptr241// CHECK-LOAD-NEXT: ret void242// CHECK-LOAD-NEXT: }243 244#endif245