diff options
Diffstat (limited to 'test/OpenMP')
285 files changed, 48693 insertions, 961 deletions
diff --git a/test/OpenMP/critical_codegen.cpp b/test/OpenMP/critical_codegen.cpp index e44e2202e9a2e..be749a65f0cb7 100644 --- a/test/OpenMP/critical_codegen.cpp +++ b/test/OpenMP/critical_codegen.cpp @@ -39,7 +39,11 @@ int main() { #pragma omp critical(the_name1) hint(23) foo(); // CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]]) +// CHECK: br label // CHECK-NOT: call {{.*}}void @__kmpc_end_critical( +// CHECK: br label +// CHECK-NOT: call {{.*}}void @__kmpc_end_critical( +// CHECK: br label if (a) #pragma omp critical(the_name) while (1) @@ -60,6 +64,8 @@ void critical_ref(S &s) { // CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]], // CHECK: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0 ++s.a; + // CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]], + // CHECK: store %struct.S* [[S_REF]], %struct.S** [[S_ADDR:%.+]], // CHECK: call void @__kmpc_critical( #pragma omp critical // CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]], diff --git a/test/OpenMP/declare_reduction_ast_print.c b/test/OpenMP/declare_reduction_ast_print.c new file mode 100644 index 0000000000000..7b97a7c1da7c3 --- /dev/null +++ b/test/OpenMP/declare_reduction_ast_print.c @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) +// CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in) +// CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in) + +#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) +// CHECK: #pragma omp declare reduction (fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + +// CHECK: struct SSS { +struct SSS { + int field; +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) + // CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in) + // CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in) +}; +// CHECK: }; + +void init(struct SSS *priv, struct SSS orig); + +#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) +// CHECK: #pragma omp declare reduction (fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + +// CHECK: int main() { +int main() { +#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + // CHECK: #pragma omp declare reduction (fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + { +#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + // CHECK: #pragma omp declare reduction (fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + } + return 0; +} +// CHECK: } + +#endif diff --git a/test/OpenMP/declare_reduction_ast_print.cpp b/test/OpenMP/declare_reduction_ast_print.cpp new file mode 100644 index 0000000000000..26b2ff96ac022 --- /dev/null +++ b/test/OpenMP/declare_reduction_ast_print.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) +// CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in) +// CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in) + +// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + +template <class T> +class SSS { +public: +#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + // CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) +}; + +SSS<int> d; + +void init(SSS<int> &lhs, SSS<int> rhs); + +#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) +// CHECK: #pragma omp declare reduction (fun : SSS<int> : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) + +// CHECK: template <typename T = int> int foo(int a) { +// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); +// CHECK: { +// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); +// CHECK: } +// CHECK: return a; +// CHECK: } + +// CHECK: template <typename T> T foo(T a) { +// CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); +// CHECK: { +// CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15); +// CHECK: } +// CHECK: return a; +// CHECK: } +template <typename T> +T foo(T a) { +#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + { +#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + } + return a; +} + +int main() { + int i = 0; + SSS<int> sss; + // TODO: Add support for scoped reduction identifiers + // #pragma omp parallel reduction(SSS<int>::fun : i) + // TODO-CHECK: #pragma omp parallel reduction(SSS<int>::fun: i) + { + i += 1; + } + // #pragma omp parallel reduction(::fun:sss) + // TODO-CHECK: #pragma omp parallel reduction(::fun: sss) + { + } + return foo(15); +} + +#endif diff --git a/test/OpenMP/declare_reduction_codegen.c b/test/OpenMP/declare_reduction_codegen.c new file mode 100644 index 0000000000000..ecb97269d4db5 --- /dev/null +++ b/test/OpenMP/declare_reduction_codegen.c @@ -0,0 +1,158 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-optzns | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-optzns +// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-optzns | FileCheck --check-prefix=CHECK-LOAD %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK: [[SSS_INT:.+]] = type { i32 } +// CHECK-LOAD: [[SSS_INT:.+]] = type { i32 } + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[MUL:%.+]] = mul nsw i32 +// CHECK-NEXT: store i32 [[MUL]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 +// CHECK-LOAD-NEXT: store i32 [[MUL]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias) +// CHECK: sext i8 +// CHECK: sext i8 +// CHECK: [[MUL:%.+]] = mul nsw i32 +// CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 +// CHECK-NEXT: store i8 [[TRUNC]], i8* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias) +// CHECK-LOAD: sext i8 +// CHECK-LOAD: sext i8 +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 +// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 +// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = 15 + omp_orig) +// CHECK: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias) +// CHECK: [[ADD:%.+]] = fadd float +// CHECK-NEXT: store float [[ADD]], float* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias) +// CHECK: [[ADD:%.+]] = fadd float 1.5 +// CHECK-NEXT: store float [[ADD]], float* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias) +// CHECK-LOAD: [[ADD:%.+]] = fadd float +// CHECK-LOAD-NEXT: store float [[ADD]], float* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias) +// CHECK-LOAD: [[ADD:%.+]] = fadd float 1.5 +// CHECK-LOAD-NEXT: store float [[ADD]], float* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +struct SSS { + int field; +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) + // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) + // CHECK: [[MUL:%.+]] = mul nsw i32 + // CHECK-NEXT: store i32 [[MUL]], i32* + // CHECK-NEXT: ret void + // CHECK-NEXT: } + + // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias) + // CHECK: sext i8 + // CHECK: sext i8 + // CHECK: [[MUL:%.+]] = mul nsw i32 + // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 + // CHECK-NEXT: store i8 [[TRUNC]], i8* + // CHECK-NEXT: ret void + // CHECK-NEXT: } +}; + +void init(struct SSS *priv, struct SSS orig); + +#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) +// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK: call void @llvm.memcpy +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK: call void @init( +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK-LOAD: call void @llvm.memcpy +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK-LOAD: call void @init( +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK-LABEL: @main +// CHECK-LOAD-LABEL: @main +int main() { +#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK: call void @llvm.memcpy + // CHECK-NEXT: ret void + // CHECK-NEXT: } + // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK: call void @init( + // CHECK-NEXT: ret void + // CHECK-NEXT: } + // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK-LOAD: call void @llvm.memcpy + // CHECK-LOAD-NEXT: ret void + // CHECK-LOAD-NEXT: } + // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK-LOAD: call void @init( + // CHECK-LOAD-NEXT: ret void + // CHECK-LOAD-NEXT: } + { +#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig)) + // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK: call void @llvm.memcpy + // CHECK-NEXT: ret void + // CHECK-NEXT: } + // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK: call void @init( + // CHECK-NEXT: ret void + // CHECK-NEXT: } + // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK-LOAD: call void @llvm.memcpy + // CHECK-LOAD-NEXT: ret void + // CHECK-LOAD-NEXT: } + // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) + // CHECK-LOAD: call void @init( + // CHECK-LOAD-NEXT: ret void + // CHECK-LOAD-NEXT: } + } + return 0; +} + +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 +// CHECK-LOAD-NEXT: store i32 [[MUL]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias) +// CHECK-LOAD: sext i8 +// CHECK-LOAD: sext i8 +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 +// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 +// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } +#endif diff --git a/test/OpenMP/declare_reduction_codegen.cpp b/test/OpenMP/declare_reduction_codegen.cpp new file mode 100644 index 0000000000000..a18e73f8a10f7 --- /dev/null +++ b/test/OpenMP/declare_reduction_codegen.cpp @@ -0,0 +1,182 @@ +// 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 +// 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 +// 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 +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK: [[SSS_INT:.+]] = type { i32 } +// CHECK-LOAD: [[SSS_INT:.+]] = type { i32 } + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[MUL:%.+]] = mul nsw i32 +// CHECK-NEXT: store i32 [[MUL]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 +// CHECK-LOAD-NEXT: store i32 [[MUL]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias) +// CHECK: sext i8 +// CHECK: sext i8 +// CHECK: [[MUL:%.+]] = mul nsw i32 +// CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 +// CHECK-NEXT: store i8 [[TRUNC]], i8* +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias) +// CHECK-LOAD: sext i8 +// CHECK-LOAD: sext i8 +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 +// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 +// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +template <class T> +struct SSS { + T a; + SSS() : a() {} +#pragma omp declare reduction(fun : T : omp_out ^= omp_in) initializer(omp_priv = 24 + omp_orig) +}; + +SSS<int> d; + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[XOR:%.+]] = xor i32 +// CHECK-NEXT: store i32 [[XOR]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[ADD:%.+]] = add nsw i32 24, +// CHECK-NEXT: store i32 [[ADD]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +// CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]* +// CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]* +void init(SSS<int> &lhs, SSS<int> &rhs) {} + +#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig)) +// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK: call void @llvm.memcpy +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK: call {{.*}}void [[INIT]]( +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK-LOAD: call void @llvm.memcpy +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias) +// CHECK-LOAD: call {{.*}}void [[INIT]]( +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +template <typename T> +T foo(T a) { +#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig) + { +#pragma omp declare reduction(fun : T : omp_out /= omp_in) initializer(omp_priv = 11 - omp_orig) + } + return a; +} + +// CHECK-LABEL: @main +int main() { + int i = 0; + SSS<int> sss; +#pragma omp parallel reduction(SSS < int > ::fun : i) + { + i += 1; + } +#pragma omp parallel reduction(::fun : sss) + { + } +#pragma omp declare reduction(fun : SSS < int > : init(omp_out, omp_in)) +#pragma omp parallel reduction(fun : sss) + { + } + // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^ ]+]] + // CHECK-LABEL: foo + return foo(15); +} + +// CHECK: define internal {{.*}}void [[REGION]]( +// CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS, +// CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]]) +// CHECK-NOT: {{call |invoke }} +// CHECK: call {{.*}}i32 @__kmpc_reduce_nowait( + +// CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 +// CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 + +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[XOR:%.+]] = xor i32 +// CHECK-LOAD-NEXT: store i32 [[XOR]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[ADD:%.+]] = add nsw i32 24, +// CHECK-LOAD-NEXT: store i32 [[ADD]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[ADD:%.+]] = add nsw i32 +// CHECK-NEXT: store i32 [[ADD]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[ADD:%.+]] = add nsw i32 +// CHECK-LOAD-NEXT: store i32 [[ADD]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[MUL:%.+]] = mul nsw i32 15, +// CHECK-NEXT: store i32 [[MUL]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 15, +// CHECK-LOAD-NEXT: store i32 [[MUL]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[DIV:%.+]] = sdiv i32 +// CHECK-NEXT: store i32 [[DIV]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[DIV:%.+]] = sdiv i32 +// CHECK-LOAD-NEXT: store i32 [[DIV]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK: [[SUB:%.+]] = sub nsw i32 11, +// CHECK-NEXT: store i32 [[SUB]], i32* +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias) +// CHECK-LOAD: [[SUB:%.+]] = sub nsw i32 11, +// CHECK-LOAD-NEXT: store i32 [[SUB]], i32* +// CHECK-LOAD-NEXT: ret void +// CHECK-LOAD-NEXT: } + +#endif diff --git a/test/OpenMP/declare_reduction_messages.c b/test/OpenMP/declare_reduction_messages.c new file mode 100644 index 0000000000000..fb9eacc90aa26 --- /dev/null +++ b/test/OpenMP/declare_reduction_messages.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +int temp; // expected-note 6 {{'temp' declared here}} + +#pragma omp declare reduction // expected-error {{expected '(' after 'declare reduction'}} +#pragma omp declare reduction { // expected-error {{expected '(' after 'declare reduction'}} +#pragma omp declare reduction( // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(# // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(/ // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(+ // expected-error {{expected ':'}} +#pragma omp declare reduction(for // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(if: // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} expected-error {{expected a type}} +#pragma omp declare reduction(oper: // expected-error {{expected a type}} +#pragma omp declare reduction(oper; // expected-error {{expected ':'}} expected-error {{expected a type}} +#pragma omp declare reduction(fun : int // expected-error {{expected ':'}} expected-error {{expected expression}} +#pragma omp declare reduction(+ : const int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}} +#pragma omp declare reduction(- : volatile int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}} +#pragma omp declare reduction(* : int; // expected-error {{expected ','}} expected-error {{expected a type}} +#pragma omp declare reduction(& : double char: // expected-error {{cannot combine with previous 'double' declaration specifier}} expected-error {{expected expression}} +#pragma omp declare reduction(^ : double, char, : // expected-error {{expected a type}} expected-error {{expected expression}} +#pragma omp declare reduction(&& : int, S: // expected-error {{unknown type name 'S'}} expected-error {{expected expression}} +#pragma omp declare reduction(|| : int, double : temp += omp_in) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(| : char, float : omp_out += temp) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(fun : long : omp_out += omp_in) { // expected-error {{expected 'initializer'}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} +#pragma omp declare reduction(fun : unsigned : omp_out += temp)) // expected-error {{expected 'initializer'}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(fun : long(void) : omp_out += omp_in) // expected-error {{reduction type cannot be a function type}} +#pragma omp declare reduction(fun : long[3] : omp_out += omp_in) // expected-error {{reduction type cannot be an array type}} +#pragma omp declare reduction(fun23 : long, int, long : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'long'}} expected-note {{previous definition is here}} + +#pragma omp declare reduction(fun222 : long : omp_out += omp_in) +#pragma omp declare reduction(fun1 : long : omp_out += omp_in) initializer // expected-error {{expected '(' after 'initializer'}} +#pragma omp declare reduction(fun2 : long : omp_out += omp_in) initializer { // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} +#pragma omp declare reduction(fun3 : long : omp_out += omp_in) initializer[ // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} +#pragma omp declare reduction(fun4 : long : omp_out += omp_in) initializer() // expected-error {{expected expression}} +#pragma omp declare reduction(fun5 : long : omp_out += omp_in) initializer(temp) // expected-error {{only 'omp_priv' or 'omp_orig' variables are allowed in initializer expression}} +#pragma omp declare reduction(fun6 : long : omp_out += omp_in) initializer(omp_orig // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare reduction(fun7 : long : omp_out += omp_in) initializer(omp_priv 12) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv = 23) // expected-note {{previous definition is here}} +#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv = 23)) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{redefinition of user-defined reduction for type 'long'}} +#pragma omp declare reduction(fun9 : long : omp_out += omp_in) initializer(omp_priv = ) // expected-error {{expected expression}} + +int fun(int arg) { +#pragma omp declare reduction(red : int : omp_out++) + { +#pragma omp declare reduction(red : int : omp_out++) // expected-note {{previous definition is here}} +#pragma omp declare reduction(red : int : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'int'}} + { +#pragma omp declare reduction(red : int : omp_out++) + } + } + return arg; +} diff --git a/test/OpenMP/declare_reduction_messages.cpp b/test/OpenMP/declare_reduction_messages.cpp new file mode 100644 index 0000000000000..a1373b1dcb9bd --- /dev/null +++ b/test/OpenMP/declare_reduction_messages.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +int temp; // expected-note 7 {{'temp' declared here}} + +#pragma omp declare reduction // expected-error {{expected '(' after 'declare reduction'}} +#pragma omp declare reduction { // expected-error {{expected '(' after 'declare reduction'}} +#pragma omp declare reduction( // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(# // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(/ // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(+ // expected-error {{expected ':'}} +#pragma omp declare reduction(operator // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} +#pragma omp declare reduction(operator: // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} expected-error {{expected a type}} +#pragma omp declare reduction(oper: // expected-error {{expected a type}} +#pragma omp declare reduction(oper; // expected-error {{expected ':'}} expected-error {{expected a type}} +#pragma omp declare reduction(fun : int // expected-error {{expected ':'}} expected-error {{expected expression}} +#pragma omp declare reduction(+ : const int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}} +#pragma omp declare reduction(- : volatile int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}} +#pragma omp declare reduction(* : int; // expected-error {{expected ','}} expected-error {{expected a type}} +#pragma omp declare reduction(& : double char: // expected-error {{cannot combine with previous 'double' declaration specifier}} expected-error {{expected expression}} +#pragma omp declare reduction(^ : double, char, : // expected-error {{expected a type}} expected-error {{expected expression}} +#pragma omp declare reduction(&& : int, S: // expected-error {{unknown type name 'S'}} expected-error {{expected expression}} +#pragma omp declare reduction(|| : int, double : temp += omp_in) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(| : char, float : omp_out += ::temp) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(fun : long : omp_out += omp_in) { // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{expected 'initializer'}} +#pragma omp declare reduction(fun : unsigned : omp_out += ::temp)) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{expected 'initializer'}} expected-error {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(fun : long & : omp_out += omp_in) // expected-error {{reduction type cannot be a reference type}} +#pragma omp declare reduction(fun : long(void) : omp_out += omp_in) // expected-error {{reduction type cannot be a function type}} +#pragma omp declare reduction(fun : long[3] : omp_out += omp_in) // expected-error {{reduction type cannot be an array type}} +#pragma omp declare reduction(fun23 : long, int, long : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'long'}} expected-note {{previous definition is here}} + +template <class T> +class Class1 { + T a; +public: + Class1() : a() {} +#pragma omp declare reduction(fun : T : temp) // expected-error {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}} +#pragma omp declare reduction(fun1 : T : omp_out++) // expected-note {{previous definition is here}} expected-error {{reduction type cannot be a reference type}} +#pragma omp declare reduction(fun1 : T : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'T'}} +#pragma omp declare reduction(fun2 : T, T : omp_out++) // expected-error {{reduction type cannot be a reference type}} expected-error {{redefinition of user-defined reduction for type 'T'}} expected-note {{previous definition is here}} +#pragma omp declare reduction(foo : T : omp_out += this->a) // expected-error {{invalid use of 'this' outside of a non-static member function}} +}; + +Class1<char &> e; // expected-note {{in instantiation of template class 'Class1<char &>' requested here}} + +template <class T> +class Class2 : public Class1<T> { +#pragma omp declare reduction(fun : T : omp_out += omp_in) +}; + +#pragma omp declare reduction(fun222 : long : omp_out += omp_in) // expected-note {{previous definition is here}} +#pragma omp declare reduction(fun222 : long : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'long'}} +#pragma omp declare reduction(fun1 : long : omp_out += omp_in) initializer // expected-error {{expected '(' after 'initializer'}} +#pragma omp declare reduction(fun2 : long : omp_out += omp_in) initializer { // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} +#pragma omp declare reduction(fun3 : long : omp_out += omp_in) initializer[ // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} +#pragma omp declare reduction(fun4 : long : omp_out += omp_in) initializer() // expected-error {{expected expression}} +#pragma omp declare reduction(fun5 : long : omp_out += omp_in) initializer(temp) // expected-error {{only 'omp_priv' or 'omp_orig' variables are allowed in initializer expression}} +#pragma omp declare reduction(fun6 : long : omp_out += omp_in) initializer(omp_orig // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare reduction(fun7 : long : omp_out += omp_in) initializer(omp_priv Class1 < int > ()) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare reduction(fun77 : long : omp_out += omp_in) initializer(omp_priv Class2 < int > ()) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv 23) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare reduction(fun88 : long : omp_out += omp_in) initializer(omp_priv 23)) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} +#pragma omp declare reduction(fun9 : long : omp_out += omp_priv) initializer(omp_in = 23) // expected-error {{use of undeclared identifier 'omp_priv'; did you mean 'omp_in'?}} expected-note {{'omp_in' declared here}} +#pragma omp declare reduction(fun10 : long : omp_out += omp_in) initializer(omp_priv = 23) + +template <typename T> +T fun(T arg) { +#pragma omp declare reduction(red : T : omp_out++) + { +#pragma omp declare reduction(red : T : omp_out++) // expected-note {{previous definition is here}} +#pragma omp declare reduction(red : T : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'T'}} +#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 23) + } + return arg; +} + +template <typename T> +T foo(T arg) { + T i; + { +#pragma omp declare reduction(red : T : omp_out++) +#pragma omp declare reduction(red1 : T : omp_out++) // expected-note {{previous definition is here}} +#pragma omp declare reduction(red1 : int : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'int'}} + #pragma omp parallel reduction (red : i) + { + } + #pragma omp parallel reduction (red1 : i) + { + } + #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + { + } + } + { +#pragma omp declare reduction(red1 : int : omp_out++) // expected-note {{previous definition is here}} +#pragma omp declare reduction(red : T : omp_out++) +#pragma omp declare reduction(red1 : T : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'int'}} + #pragma omp parallel reduction (red : i) + { + } + #pragma omp parallel reduction (red1 : i) + { + } + #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + { + } + } + return arg; +} + +#pragma omp declare reduction(foo : int : ({int a = omp_in; a = a * 2; omp_out += a; })) +int main() { + Class1<int> c1; + int i; + #pragma omp parallel reduction (::fun : c1) + { + } + #pragma omp parallel reduction (::Class1<int>::fun : c1) + { + } + #pragma omp parallel reduction (::Class2<int>::fun : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + { + } + return fun(15) + foo(15); // expected-note {{in instantiation of function template specialization 'foo<int>' requested here}} +} diff --git a/test/OpenMP/declare_simd_ast_print.c b/test/OpenMP/declare_simd_ast_print.c new file mode 100644 index 0000000000000..04fd73f272d8b --- /dev/null +++ b/test/OpenMP/declare_simd_ast_print.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp declare simd aligned(b : 64) +#pragma omp declare simd simdlen(32) aligned(d, b) +#pragma omp declare simd inbranch, uniform(d) linear(val(s1, s2) : 32) +#pragma omp declare simd notinbranch simdlen(2), uniform(s1, s2) linear(d: s1) +void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold)); + +// CHECK: #pragma omp declare simd notinbranch simdlen(2) uniform(s1, s2) linear(val(d): s1) +// CHECK-NEXT: #pragma omp declare simd inbranch uniform(d) linear(val(s1): 32) linear(val(s2): 32) +// CHECK-NEXT: #pragma omp declare simd simdlen(32) aligned(d) aligned(b) +// CHECK-NEXT: #pragma omp declare simd aligned(b: 64) +// CHECK-NEXT: void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold)) + +#endif diff --git a/test/OpenMP/declare_simd_ast_print.cpp b/test/OpenMP/declare_simd_ast_print.cpp new file mode 100644 index 0000000000000..5a32e61d9922f --- /dev/null +++ b/test/OpenMP/declare_simd_ast_print.cpp @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp declare simd linear(d: 8) +#pragma omp declare simd inbranch simdlen(32) +#pragma omp declare simd notinbranch +void add_1(float *d) __attribute__((cold)); + +// CHECK: #pragma omp declare simd notinbranch +// CHECK-NEXT: #pragma omp declare simd inbranch simdlen(32) +// CHECK-NEXT: #pragma omp declare simd linear(val(d): 8) +// CHECK-NEXT: void add_1(float *d) __attribute__((cold)); +// + +#pragma omp declare simd aligned(hp, hp2) +template <class C> void h(C *hp, C *hp2, C *hq, C *lin) { +} + +// CHECK: #pragma omp declare simd aligned(hp) aligned(hp2) +// CHECK-NEXT: template <class C = int> void h(int *hp, int *hp2, int *hq, int *lin) { +// CHECK-NEXT: h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); +// CHECK-NEXT: } + +// CHECK: #pragma omp declare simd aligned(hp) aligned(hp2) +// CHECK-NEXT: template <class C = float> void h(float *hp, float *hp2, float *hq, float *lin) { +// CHECK-NEXT: } + +// CHECK: #pragma omp declare simd aligned(hp) aligned(hp2) +// CHECK: template <class C> void h(C *hp, C *hp2, C *hq, C *lin) { +// CHECK-NEXT: } +// + +// Explicit specialization with <C=int>. +// Pragmas need to be same, otherwise standard says that's undefined behavior. +#pragma omp declare simd aligned(hp, hp2) +template <> +void h(int *hp, int *hp2, int *hq, int *lin) +{ + // Implicit specialization with <C=float>. + // This is special case where the directive is stored by Sema and is + // generated together with the (pending) function instatiation. + h((float*) hp, (float*) hp2, (float*) hq, (float*) lin); +} + +class VV { + // CHECK: #pragma omp declare simd uniform(this, a) linear(val(b): a) + // CHECK-NEXT: int add(int a, int b) __attribute__((cold)) { + // CHECK-NEXT: return a + b; + // CHECK-NEXT: } + #pragma omp declare simd uniform(this, a) linear(val(b): a) + int add(int a, int b) __attribute__((cold)) { return a + b; } + + // CHECK: #pragma omp declare simd aligned(b: 4) aligned(a) linear(ref(b): 4) linear(val(this)) linear(val(a)) + // CHECK-NEXT: float taddpf(float *a, float *&b) { + // CHECK-NEXT: return *a + *b; + // CHECK-NEXT: } + #pragma omp declare simd aligned (b: 4) aligned(a) linear(ref(b): 4) linear(this, a) + float taddpf(float *a, float *&b) { return *a + *b; } + +// CHECK: #pragma omp declare simd aligned(b: 8) +// CHECK-NEXT: #pragma omp declare simd linear(uval(c): 8) +// CHECK-NEXT: int tadd(int (&b)[], int &c) { +// CHECK-NEXT: return this->x[b[0]] + b[0]; +// CHECK-NEXT: } + #pragma omp declare simd linear(uval(c): 8) + #pragma omp declare simd aligned(b : 8) + int tadd(int (&b)[], int &c) { return x[b[0]] + b[0]; } + +private: + int x[10]; +}; + +// CHECK: template <int X = 16, typename T = float> class TVV { +// CHECK: #pragma omp declare simd +// CHECK-NEXT: int tadd(int a, int b); +// CHECK: #pragma omp declare simd aligned(a: 16 * 2) aligned(b) linear(ref(b): 16) +// CHECK-NEXT: float taddpf(float *a, float *&b) { +// CHECK-NEXT: return *a + *b; +// CHECK-NEXT: } +// CHECK: #pragma omp declare simd +// CHECK-NEXT: #pragma omp declare simd +// CHECK-NEXT: int tadd(int b) { +// CHECK-NEXT: return this->x[b] + b; +// CHECK-NEXT: } +// CHECK: } +template <int X, typename T> +class TVV { +public: +// CHECK: template <int X, typename T> class TVV { + #pragma omp declare simd simdlen(X) + int tadd(int a, int b) { return a + b; } + +// CHECK: #pragma omp declare simd simdlen(X) +// CHECK-NEXT: int tadd(int a, int b) { +// CHECK-NEXT: return a + b; +// CHECK-NEXT: } + + #pragma omp declare simd aligned(a : X * 2) aligned(b) linear(ref(b): X) + float taddpf(float *a, T *&b) { return *a + *b; } + +// CHECK: #pragma omp declare simd aligned(a: X * 2) aligned(b) +// CHECK-NEXT: float taddpf(float *a, T *&b) { +// CHECK-NEXT: return *a + *b; +// CHECK-NEXT: } + + #pragma omp declare simd + #pragma omp declare simd uniform(this, b) + int tadd(int b) { return x[b] + b; } + +// CHECK: #pragma omp declare simd uniform(this, b) +// CHECK-NEXT: #pragma omp declare simd +// CHECK-NEXT: int tadd(int b) { +// CHECK-NEXT: return this->x[b] + b; +// CHECK-NEXT: } + +private: + int x[X]; +}; +// CHECK: }; + +// CHECK: #pragma omp declare simd simdlen(64) aligned(b: 64 * 2) linear(uval(c): 64) +// CHECK: template <int N = 64> void foo(int (&b)[64], float *&c) +// CHECK: #pragma omp declare simd simdlen(N) aligned(b: N * 2) linear(uval(c): N) +// CHECK: template <int N> void foo(int (&b)[N], float *&c) +#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(uval(c): N) +template <int N> +void foo(int (&b)[N], float *&c); + +// CHECK: TVV<16, float> t16; +TVV<16, float> t16; + +void f() { + float a = 1.0f, b = 2.0f; + float *p = &b; + float r = t16.taddpf(&a, p); + int res = t16.tadd(b); + int c[64]; + foo(c, p); +} + +#endif diff --git a/test/OpenMP/declare_simd_codegen.cpp b/test/OpenMP/declare_simd_codegen.cpp new file mode 100644 index 0000000000000..4ed7fb2801b8f --- /dev/null +++ b/test/OpenMP/declare_simd_codegen.cpp @@ -0,0 +1,288 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +#ifndef HEADER +#define HEADER + +#pragma omp declare simd linear(d : 8) +#pragma omp declare simd inbranch simdlen(32) +#pragma omp declare simd notinbranch +void add_1(float *d) {} + +#pragma omp declare simd aligned(hp, hp2) +template <class C> +void h(C *hp, C *hp2, C *hq, C *lin) { +} + +// Explicit specialization with <C=int>. +// Pragmas need to be same, otherwise standard says that's undefined behavior. +#pragma omp declare simd aligned(hp, hp2) +template <> +void h(int *hp, int *hp2, int *hq, int *lin) { + // Implicit specialization with <C=float>. + // This is special case where the directive is stored by Sema and is + // generated together with the (pending) function instatiation. + h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); +} + +class VV { +public: +#pragma omp declare simd uniform(this, a) linear(val(b) : a) + int add(int a, int b) __attribute__((cold)) { return a + b; } + +#pragma omp declare simd aligned(b : 4) aligned(a) linear(ref(b) : 4) linear(this, a) + float taddpf(float *a, float *&b) { return *a + *b; } + +#pragma omp declare simd linear(uval(c) : 8) +#pragma omp declare simd aligned(b : 8) + int tadd(int (&b)[], int &c) { return x[b[0]] + b[0]; } + +private: + int x[10]; +} vv; + +template <int X, typename T> +class TVV { +public: +#pragma omp declare simd simdlen(X) + int tadd(int a, int b) { return a + b; } + +#pragma omp declare simd aligned(a : X * 2) aligned(b) linear(ref(b) : X) + float taddpf(float *a, T *&b) { return *a + *b; } + +#pragma omp declare simd +#pragma omp declare simd uniform(this, b) + int tadd(int b) { return x[b] + b; } + +private: + int x[X]; +}; + +#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(uval(c) : N) +template <int N> +void foo(int (&b)[N], float *&c) {} + +TVV<16, float> t16; + +void f(int (&g)[]) { + float a = 1.0f, b = 2.0f; + float *p = &b; + float r = t16.taddpf(&a, p); + int res = t16.tadd(b); + int c[64]; + vv.add(res, res); + vv.taddpf(p, p); + vv.tadd(g, res); + foo(c, p); +} + +#pragma omp declare simd +#pragma omp declare simd notinbranch aligned(a : 32) +int bar(VV v, float *a) { return 0; } +#pragma omp declare simd +#pragma omp declare simd notinbranch aligned(a) +float baz(VV v, int a[]) { return 0; } +#pragma omp declare simd +#pragma omp declare simd notinbranch aligned(a) +double bay(VV v, double *&a) { return 0; } +#pragma omp declare simd +#pragma omp declare simd inbranch linear(a : b) uniform(v, b) +void bax(VV v, double *a, int b) {} +#pragma omp declare simd uniform(q) aligned(q : 16) linear(k : 1) +float foo(float *q, float x, int k) { return 0; } +#pragma omp declare simd notinbranch +double foo(double x) { return 0; } + +// CHECK-DAG: define {{.+}}@_Z5add_1Pf( +// CHECK-DAG: define {{.+}}@_Z1hIiEvPT_S1_S1_S1_( +// CHECK-DAG: define {{.+}}@_Z1hIfEvPT_S1_S1_S1_( +// CHECK-DAG: define {{.+}}@_ZN2VV3addEii( +// CHECK-DAG: define {{.+}}@_ZN2VV6taddpfEPfRS0_( +// CHECK-DAG: define {{.+}}@_ZN2VV4taddERA_iRi( +// CHECK-DAG: define {{.+}}@_Z1fRA_i( +// CHECK-DAG: define {{.+}}@_ZN3TVVILi16EfE6taddpfEPfRS1_( +// CHECK-DAG: define {{.+}}@_ZN3TVVILi16EfE4taddEi( +// CHECK-DAG: define {{.+}}@_Z3fooILi64EEvRAT__iRPf( +// CHECK-DAG: define {{.+}}@_Z3bar2VVPf( +// CHECK-DAG: define {{.+}}@_Z3baz2VVPi( +// CHECK-DAG: define {{.+}}@_Z3bay2VVRPd( +// CHECK-DAG: define {{.+}}@_Z3bax2VVPdi( +// CHECK-DAG: define {{.+}}@_Z3fooPffi( +// CHECK-DAG: define {{.+}}@_Z3food( + +// CHECK-DAG: "_ZGVbM4l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVbN4l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVcM8l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVcN8l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVdM8l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVdN8l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVeM16l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVeN16l8__Z5add_1Pf" +// CHECK-DAG: "_ZGVbM32v__Z5add_1Pf" +// CHECK-DAG: "_ZGVcM32v__Z5add_1Pf" +// CHECK-DAG: "_ZGVdM32v__Z5add_1Pf" +// CHECK-DAG: "_ZGVeM32v__Z5add_1Pf" +// CHECK-DAG: "_ZGVbN2v__Z5add_1Pf" +// CHECK-DAG: "_ZGVcN4v__Z5add_1Pf" +// CHECK-DAG: "_ZGVdN4v__Z5add_1Pf" +// CHECK-DAG: "_ZGVeN8v__Z5add_1Pf" + +// CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVcN4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVdM4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVdN4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVeM8va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVeN8va16va16vv__Z1hIiEvPT_S1_S1_S1_" + +// CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVcN4va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVdM4va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVdN4va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVeM8va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// CHECK-DAG: "_ZGVeN8va16va16vv__Z1hIfEvPT_S1_S1_S1_" + +// CHECK-DAG: "_ZGVbM4uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVbN4uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVcM8uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVcN8uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVdM8uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVdN8uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVeM16uus1__ZN2VV3addEii" +// CHECK-DAG: "_ZGVeN16uus1__ZN2VV3addEii" + +// CHECK-DAG: "_ZGVbM4lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVbN4lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVcM8lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVcN8lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVdM8lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVdN8lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVeM16lla16l4a4__ZN2VV6taddpfEPfRS0_" +// CHECK-DAG: "_ZGVeN16lla16l4a4__ZN2VV6taddpfEPfRS0_" + +// CHECK-DAG: "_ZGVbM4vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVbN4vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVcM8vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVcN8vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVdM8vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVdN8vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVeM16vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVeN16vvl8__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVbM4vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVbN4vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVcM8vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVcN8vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVdM8vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVdN8vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVeM16vva8v__ZN2VV4taddERA_iRi" +// CHECK-DAG: "_ZGVeN16vva8v__ZN2VV4taddERA_iRi" + +// CHECK-DAG: "_ZGVbM4vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVbN4vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVcM8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVcN8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVdM8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVdN8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVeM16vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" +// CHECK-DAG: "_ZGVeN16vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_" + +// CHECK-DAG: "_ZGVbM4uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVbN4uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVcM8uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVcN8uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVdM8uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVdN8uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVeM16uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVeN16uu__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVbM4vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVbN4vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVcM8vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVcN8vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVdM8vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVdN8vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVeM16vv__ZN3TVVILi16EfE4taddEi" +// CHECK-DAG: "_ZGVeN16vv__ZN3TVVILi16EfE4taddEi" + +// CHECK-DAG: "_ZGVbM64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVbN64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVcM64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVcN64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVdM64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVdN64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVeM64va128l64__Z3fooILi64EEvRAT__iRPf" +// CHECK-DAG: "_ZGVeN64va128l64__Z3fooILi64EEvRAT__iRPf" + +// CHECK-DAG: "_ZGVbM4vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVbN4vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVcM8vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVcN8vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVdM8vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVdN8vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVeM16vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVeN16vv__Z3bar2VVPf" +// CHECK-DAG: "_ZGVbN4vva32__Z3bar2VVPf" +// CHECK-DAG: "_ZGVcN8vva32__Z3bar2VVPf" +// CHECK-DAG: "_ZGVdN8vva32__Z3bar2VVPf" +// CHECK-DAG: "_ZGVeN16vva32__Z3bar2VVPf" + +// CHECK-DAG: "_ZGVbM4vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVbN4vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVcM8vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVcN8vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVdM8vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVdN8vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVeM16vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVeN16vv__Z3baz2VVPi" +// CHECK-DAG: "_ZGVbN4vva16__Z3baz2VVPi" +// CHECK-DAG: "_ZGVcN8vva16__Z3baz2VVPi" +// CHECK-DAG: "_ZGVdN8vva16__Z3baz2VVPi" +// CHECK-DAG: "_ZGVeN16vva16__Z3baz2VVPi" + +// CHECK-DAG: "_ZGVbM2vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVbN2vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVcM4vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVcN4vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVdM4vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVdN4vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVeM8vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVeN8vv__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVbN2vva16__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVcN4vva16__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVdN4vva16__Z3bay2VVRPd" +// CHECK-DAG: "_ZGVeN8vva16__Z3bay2VVRPd" + +// CHECK-DAG: "_ZGVbM4us2u__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVcM8us2u__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVdM8us2u__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVeM16us2u__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVbM4vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVbN4vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVcM8vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVcN8vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVdM8vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVdN8vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVeM16vvv__Z3bax2VVPdi" +// CHECK-DAG: "_ZGVeN16vvv__Z3bax2VVPdi" + +// CHECK-DAG: "_ZGVbM4ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVbN4ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVcM8ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVcN8ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVdM8ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVdN8ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVeM16ua16vl1__Z3fooPffi" +// CHECK-DAG: "_ZGVeN16ua16vl1__Z3fooPffi" + +// CHECK-DAG: "_ZGVbN2v__Z3food" +// CHECK-DAG: "_ZGVcN4v__Z3food" +// CHECK-DAG: "_ZGVdN4v__Z3food" +// CHECK-DAG: "_ZGVeN8v__Z3food" + +// CHECK-NOT: "_ZGV{{.+}}__Z1fRA_i + +#endif diff --git a/test/OpenMP/declare_simd_messages.cpp b/test/OpenMP/declare_simd_messages.cpp new file mode 100644 index 0000000000000..15971eb14de5a --- /dev/null +++ b/test/OpenMP/declare_simd_messages.cpp @@ -0,0 +1,231 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c++ -std=c++11 -fms-extensions %s + +// expected-error@+1 {{expected an OpenMP directive}} +#pragma omp declare + +// expected-error@+2 {{'#pragma omp declare simd' can only be applied to functions}} +#pragma omp declare simd +int a; +// expected-error@+2 {{'#pragma omp declare simd' can only be applied to functions}} +#pragma omp declare simd +#pragma omp threadprivate(a) +int var; +#pragma omp threadprivate(var) + +// expected-error@+2 {{expected an OpenMP directive}} expected-error@+1 {{function declaration is expected after 'declare simd' directive}} +#pragma omp declare simd +#pragma omp declare + +// expected-error@+3 {{function declaration is expected after 'declare simd' directive}} +// expected-error@+1 {{function declaration is expected after 'declare simd' directive}} +#pragma omp declare simd +#pragma omp declare simd +#pragma options align=packed +int main(); + +// expected-error@+3 {{function declaration is expected after 'declare simd' directive}} +// expected-error@+1 {{function declaration is expected after 'declare simd' directive}} +#pragma omp declare simd +#pragma omp declare simd +#pragma init_seg(compiler) +int main(); + +// expected-error@+1 {{single declaration is expected after 'declare simd' directive}} +#pragma omp declare simd +// expected-note@+1 {{declared here}} +int b, c; + +// expected-error@+1 {{'C' does not refer to a value}} +#pragma omp declare simd simdlen(C) +// expected-note@+1 {{declared here}} +template <class C> +void h(C *hp, C *hp2, C *hq, C *lin) { + b = 0; +} + +#pragma omp declare simd +template <> +void h(int *hp, int *hp2, int *hq, int *lin) { + h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); +} + +#pragma omp declare simd inbranch inbranch +#pragma omp declare simd notinbranch notinbranch +#pragma omp declare simd inbranch inbranch notinbranch // expected-error {{unexpected 'notinbranch' clause, 'inbranch' is specified already}} +#pragma omp declare simd notinbranch notinbranch inbranch // expected-error {{unexpected 'inbranch' clause, 'notinbranch' is specified already}} +// expected-note@+2 {{read of non-const variable 'b' is not allowed in a constant expression}} +// expected-error@+1 {{expression is not an integral constant expression}} +#pragma omp declare simd simdlen(b) +// expected-error@+1 {{directive '#pragma omp declare simd' cannot contain more than one 'simdlen' clause}} +#pragma omp declare simd simdlen(32) simdlen(c) +// expected-error@+1 {{expected '(' after 'simdlen'}} +#pragma omp declare simd simdlen +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd simdlen( +// expected-error@+2 {{expected '(' after 'simdlen'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd simdlen(), simdlen +// expected-error@+1 2 {{expected expression}} +#pragma omp declare simd simdlen(), simdlen() +// expected-warning@+3 {{extra tokens at the end of '#pragma omp declare simd' are ignored}} +// expected-error@+2 {{expected '(' after 'simdlen'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd simdlen() simdlen) +void foo(); + +// expected-error@+3 4 {{expected reference to one of the parameters of function 'foo'}} +// expected-error@+2 {{invalid use of 'this' outside of a non-static member function}} +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp declare simd simdlen(N) uniform(this, var) aligned(var) +template<int N> +void foo() {} + +void test() { + // expected-note@+1 {{in instantiation of function template specialization 'foo<-3>' requested here}} + foo<-3>(); +} + +// expected-error@+1 {{expected '(' after 'uniform'}} +#pragma omp declare simd uniform +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd uniform( +// expected-error@+1 {{expected expression}} +#pragma omp declare simd uniform() +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}} +#pragma omp declare simd uniform(this +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}} +#pragma omp declare simd uniform(this,a +// expected-error@+1 {{expected expression}} +#pragma omp declare simd uniform(,a) +// expected-error@+1 {{expected '(' after 'aligned'}} +#pragma omp declare simd aligned +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd aligned( +// expected-error@+1 {{expected expression}} +#pragma omp declare simd aligned() +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd aligned(a: +// expected-error@+1 {{expected expression}} +#pragma omp declare simd aligned(a:) +// expected-warning@+2 {{extra tokens at the end of '#pragma omp declare simd' are ignored}} +// expected-error@+1 {{expected '(' after 'aligned'}} +#pragma omp declare simd aligned :) +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}} +#pragma omp declare simd aligned(this +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}} +#pragma omp declare simd aligned(this,b +// expected-error@+1 {{expected expression}} +#pragma omp declare simd aligned(, b) +// expected-note@+4 {{defined as aligned}} +// expected-error@+3 {{a parameter cannot appear in more than one aligned clause}} +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ',' or ')' in 'aligned' clause}} +#pragma omp declare simd aligned(b) aligned(b ; 64) +// expected-note@+2 {{defined as aligned}} +// expected-error@+1 {{a parameter cannot appear in more than one aligned clause}} +#pragma omp declare simd aligned(b) aligned(b: 64) +// expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} +#pragma omp declare simd aligned(b: -1) +// expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}} +#pragma omp declare simd aligned(b: 3) +// expected-error@+1 {{expected '(' after 'linear'}} +#pragma omp declare simd linear +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd linear( +// expected-error@+1 {{expected expression}} +#pragma omp declare simd linear() +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{expected expression}} +#pragma omp declare simd linear(a: +// expected-error@+1 {{expected expression}} +#pragma omp declare simd linear(a:) +// expected-warning@+2 {{extra tokens at the end of '#pragma omp declare simd' are ignored}} +// expected-error@+1 {{expected '(' after 'linear'}} +#pragma omp declare simd linear :) +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}} +#pragma omp declare simd linear(this +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}} +#pragma omp declare simd linear(this,b +// expected-error@+1 {{expected expression}} +#pragma omp declare simd linear(, b) +// expected-note@+4 {{defined as linear}} +// expected-error@+3 {{linear variable cannot be linear}} +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ',' or ')' in 'linear' clause}} +#pragma omp declare simd linear(b) linear(b ; 64) +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be linear}} +#pragma omp declare simd linear(b) linear(b: 64) +#pragma omp declare simd linear(b: -1) +#pragma omp declare simd linear(b: 3) +// expected-error@+1 {{expected a reference to a parameter specified in a 'uniform' clause}} +#pragma omp declare simd linear(b: a) +// expected-note@+2 {{defined as uniform}} +// expected-error@+1 {{linear variable cannot be uniform}} +#pragma omp declare simd uniform(a), linear(a: 4) +// expected-note@+2 {{defined as uniform}} +// expected-error@+1 {{linear variable cannot be uniform}} +#pragma omp declare simd linear(a: 4) uniform(a) +// expected-error@+1 {{variable of non-reference type 'int *' can be used only with 'val' modifier, but used with 'uval'}} +#pragma omp declare simd linear(uval(b)) +// expected-error@+1 {{variable of non-reference type 'int *' can be used only with 'val' modifier, but used with 'ref'}} +#pragma omp declare simd linear(ref(b)) +// expected-error@+1 {{expected one of 'ref', val' or 'uval' modifiers}} +#pragma omp declare simd linear(uref(b)) +void bar(int a, int *b); + +template <class T> +struct St { +// expected-error@+2 {{function declaration is expected after 'declare simd' directive}} +#pragma init_seg(compiler) +#pragma omp declare simd +#pragma init_seg(compiler) +// expected-note@+7 {{defined as uniform}} +// expected-error@+6 {{expected a reference to a parameter specified in a 'uniform' clause}} +// expected-error@+5 {{linear variable cannot be uniform}} +// expected-note@+4 {{defined as aligned}} +// expected-error@+3 {{argument to 'aligned' clause must be a strictly positive integer value}} +// expected-error@+2 {{'this' cannot appear in more than one aligned clause}} +// expected-error@+1 {{use of undeclared identifier 't'}} +#pragma omp declare simd uniform(this, t) aligned(this: 4) aligned(this: -4) linear(this: hp) + void h(T *hp) { +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp declare simd'}} +#pragma omp declare simd + *hp = *t; + } + +private: + T t; +}; + +namespace N { + // expected-error@+1 {{function declaration is expected after 'declare simd' directive}} + #pragma omp declare simd +} +// expected-error@+1 {{function declaration is expected after 'declare simd' directive}} +#pragma omp declare simd +// expected-error@+1 {{function declaration is expected after 'declare simd' directive}} +#pragma omp declare simd diff --git a/test/OpenMP/declare_target_ast_print.cpp b/test/OpenMP/declare_target_ast_print.cpp new file mode 100644 index 0000000000000..78a9cf634af89 --- /dev/null +++ b/test/OpenMP/declare_target_ast_print.cpp @@ -0,0 +1,138 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp declare target +// CHECK: #pragma omp declare target +void foo() {} +// CHECK-NEXT: void foo() +#pragma omp end declare target +// CHECK: #pragma omp end declare target + +extern "C" { +#pragma omp declare target +// CHECK: #pragma omp declare target +void foo_c() {} +// CHECK-NEXT: void foo_c() +#pragma omp end declare target +// CHECK: #pragma omp end declare target +} + +extern "C++" { +#pragma omp declare target +// CHECK: #pragma omp declare target +void foo_cpp() {} +// CHECK-NEXT: void foo_cpp() +#pragma omp end declare target +// CHECK: #pragma omp end declare target +} + +#pragma omp declare target +template <class T> +struct C { +// CHECK: template <class T = int> struct C + T t; +// CHECK-NEXT: int t; + static T ts; +// CHECK-NEXT: #pragma omp declare target +// CHECK-NEXT: static int ts; +// CHECK: #pragma omp end declare target + + C(T t) : t(t) { + } +// CHECK: #pragma omp declare target +// CHECK-NEXT: C(int t) : t(t) { +// CHECK-NEXT: } +// CHECK: #pragma omp end declare target + + T foo() { + return t; + } +// CHECK: #pragma omp declare target +// CHECK-NEXT: int foo() { +// CHECK-NEXT: return this->t; +// CHECK-NEXT: } +// CHECK: #pragma omp end declare target +}; + +// CHECK: template <class T> struct C { +// CHECK: #pragma omp declare target +// CHECK-NEXT: static T ts; +// CHECK-NEXT: #pragma omp end declare target + +template<class T> +T C<T>::ts = 1; +// CHECK: #pragma omp declare target +// CHECK: T ts = 1; +// CHECK: #pragma omp end declare target + +// CHECK: #pragma omp declare target +// CHECK: int test1() +int test1() { + C<int> c(1); + return c.foo() + c.ts; +} +#pragma omp end declare target +// CHECK: #pragma omp end declare target + +int a1; +void f1() { +} +#pragma omp declare target (a1, f1) +// CHECK: #pragma omp declare target +// CHECK: int a1; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: void f1() +// CHECK: #pragma omp end declare target + +int b1, b2, b3; +void f2() { +} +#pragma omp declare target to(b1) to(b2), to(b3, f2) +// CHECK: #pragma omp declare target +// CHECK: int b1; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: int b2; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: int b3; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: void f2() +// CHECK: #pragma omp end declare target + +int c1, c2, c3; +void f3() { +} +#pragma omp declare target link(c1) link(c2), link(c3, f3) +// CHECK: #pragma omp declare target link +// CHECK: int c1; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target link +// CHECK: int c2; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target link +// CHECK: int c3; +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target link +// CHECK: void f3() +// CHECK: #pragma omp end declare target + +int main (int argc, char **argv) { + foo(); + foo_c(); + foo_cpp(); + test1(); + return (0); +} + +// CHECK: #pragma omp declare target +// CHECK-NEXT: int ts = 1; +// CHECK-NEXT: #pragma omp end declare target +#endif diff --git a/test/OpenMP/declare_target_messages.cpp b/test/OpenMP/declare_target_messages.cpp new file mode 100644 index 0000000000000..b858d53c1ecf5 --- /dev/null +++ b/test/OpenMP/declare_target_messages.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -o - %s + +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} + +int a, b; // expected-warning {{declaration is not declared in any declare target region}} +__thread int t; // expected-note {{defined as threadprivate or thread local}} + +#pragma omp declare target . // expected-error {{expected '(' after 'declare target'}} + +#pragma omp declare target +void f(); +#pragma omp end declare target shared(a) // expected-warning {{extra tokens at the end of '#pragma omp end declare target' are ignored}} + +#pragma omp declare target map(a) // expected-error {{unexpected 'map' clause, only 'to' or 'link' clauses expected}} + +void c(); // expected-warning {{declaration is not declared in any declare target region}} + +extern int b; + +struct NonT { + int a; +}; + +typedef int sint; + +#pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}} +#pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}} +extern int b; +int g; + +struct T { // expected-note {{mappable type cannot be polymorphic}} + int a; + virtual int method(); +}; + +class VC { // expected-note {{mappable type cannot be polymorphic}} + T member; + NonT member1; + public: + virtual int method() { T a; return 0; } // expected-error {{type 'T' is not mappable to target}} +}; + +struct C { + NonT a; + sint b; + int method(); + int method1(); +}; + +int C::method1() { + return 0; +} + +void foo() { + a = 0; // expected-error {{threadprivate variables cannot be used in target constructs}} + b = 0; // expected-note {{used here}} + t = 1; // expected-error {{threadprivate variables cannot be used in target constructs}} + C object; + VC object1; // expected-error {{type 'VC' is not mappable to target}} + g = object.method(); + g += object.method1(); + g += object1.method(); + f(); + c(); // expected-note {{used here}} +} +#pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}} +void foo1() {} +#pragma omp end declare target +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} + +int C::method() { + return 0; +} + +struct S { +#pragma omp declare target // expected-error {{directive must be at file or namespace scope}} + int v; +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} +}; + +int main (int argc, char **argv) { +#pragma omp declare target // expected-error {{unexpected OpenMP directive '#pragma omp declare target'}} + int v; +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} + foo(); + return (0); +} + +namespace { +#pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}} + int x; +} // expected-error {{expected '#pragma omp end declare target'}} +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} + +#pragma omp declare target link(S) // expected-error {{'S' used in declare target directive is not a variable or a function name}} + +#pragma omp declare target (x, x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}} +#pragma omp declare target to(x) to(x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}} +#pragma omp declare target link(x) // expected-error {{'x' must not appear in both clauses 'to' and 'link'}} + +#pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}} expected-note {{to match this '#pragma omp declare target'}} diff --git a/test/OpenMP/distribute_ast_print.cpp b/test/OpenMP/distribute_ast_print.cpp index c3a175a5e5e84..5748fc79ed67f 100644 --- a/test/OpenMP/distribute_ast_print.cpp +++ b/test/OpenMP/distribute_ast_print.cpp @@ -8,6 +8,75 @@ void foo() {} +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, g; diff --git a/test/OpenMP/distribute_codegen.cpp b/test/OpenMP/distribute_codegen.cpp new file mode 100644 index 0000000000000..37f00f09178b0 --- /dev/null +++ b/test/OpenMP/distribute_codegen.cpp @@ -0,0 +1,263 @@ +// Test host codegen. +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix HCHECK +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix HCHECK +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix HCHECK + +// Test target codegen - host bc file has to be created first. (no significant differences with host version of target region) +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s + +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* } +// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" +// CHECK-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) } + +// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void without_schedule_clause(float *a, float *b, float *c, float *d) { + #pragma omp target + #pragma omp teams + #pragma omp distribute + for (int i = 33; i < 32000000; i += 7) { + a[i] = b[i] * c[i] * d[i]; + } +} + +// CHECK: define {{.*}}void @.omp_outlined.(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]]) +// CHECK: [[TID_ADDR:%.+]] = alloca i32* +// CHECK: [[IV:%.+iv]] = alloca i32 +// CHECK: [[LB:%.+lb]] = alloca i32 +// CHECK: [[UB:%.+ub]] = alloca i32 +// CHECK: [[ST:%.+stride]] = alloca i32 +// CHECK: [[LAST:%.+last]] = alloca i32 +// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]] +// CHECK-DAG: store i32 0, i32* [[LB]] +// CHECK-DAG: store i32 4571423, i32* [[UB]] +// CHECK-DAG: store i32 1, i32* [[ST]] +// CHECK-DAG: store i32 0, i32* [[LAST]] +// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]] +// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]] +// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1) +// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]] +// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423 +// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]] +// CHECK-DAG: [[BBCT]]: +// CHECK-DAG: br label %[[BBCE:.+]] +// CHECK-DAG: [[BBCF]]: +// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]] +// CHECK-DAG: br label %[[BBCE]] +// CHECK: [[BBCE]]: +// CHECK: [[SELUB:%.+]] = phi i32 [ 4571423, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ] +// CHECK: store i32 [[SELUB]], i32* [[UB]] +// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]] +// CHECK: store i32 [[LBV0]], i32* [[IV]] +// CHECK: br label %[[BBINNFOR:.+]] +// CHECK: [[BBINNFOR]]: +// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]] +// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]] +// CHECK: [[IVLEUB:%.+]] = icmp sle i32 [[IVVAL0]], [[UBV2]] +// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]] +// CHECK: [[BBINNBODY]]: +// CHECK: {{.+}} = load i32, i32* [[IV]] +// ... loop body ... +// CHECK: br label %[[BBBODYCONT:.+]] +// CHECK: [[BBBODYCONT]]: +// CHECK: br label %[[BBINNINC:.+]] +// CHECK: [[BBINNINC]]: +// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]] +// CHECK: [[IVINC:%.+]] = add nsw i32 [[IVVAL1]], 1 +// CHECK: store i32 [[IVINC]], i32* [[IV]] +// CHECK: br label %[[BBINNFOR]] +// CHECK: [[BBINNEND]]: +// CHECK: br label %[[LPEXIT:.+]] +// CHECK: [[LPEXIT]]: +// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]]) +// CHECK: ret void + + +// CHECK-LABEL: define {{.*void}} @{{.*}}static_not_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void static_not_chunked(float *a, float *b, float *c, float *d) { + #pragma omp target + #pragma omp teams + #pragma omp distribute dist_schedule(static) + for (int i = 32000000; i > 33; i += -7) { + a[i] = b[i] * c[i] * d[i]; + } +} + +// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]]) +// CHECK: [[TID_ADDR:%.+]] = alloca i32* +// CHECK: [[IV:%.+iv]] = alloca i32 +// CHECK: [[LB:%.+lb]] = alloca i32 +// CHECK: [[UB:%.+ub]] = alloca i32 +// CHECK: [[ST:%.+stride]] = alloca i32 +// CHECK: [[LAST:%.+last]] = alloca i32 +// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]] +// CHECK-DAG: store i32 0, i32* [[LB]] +// CHECK-DAG: store i32 4571423, i32* [[UB]] +// CHECK-DAG: store i32 1, i32* [[ST]] +// CHECK-DAG: store i32 0, i32* [[LAST]] +// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]] +// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]] +// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1) +// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]] +// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423 +// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]] +// CHECK-DAG: [[BBCT]]: +// CHECK-DAG: br label %[[BBCE:.+]] +// CHECK-DAG: [[BBCF]]: +// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]] +// CHECK-DAG: br label %[[BBCE]] +// CHECK: [[BBCE]]: +// CHECK: [[SELUB:%.+]] = phi i32 [ 4571423, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ] +// CHECK: store i32 [[SELUB]], i32* [[UB]] +// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]] +// CHECK: store i32 [[LBV0]], i32* [[IV]] +// CHECK: br label %[[BBINNFOR:.+]] +// CHECK: [[BBINNFOR]]: +// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]] +// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]] +// CHECK: [[IVLEUB:%.+]] = icmp sle i32 [[IVVAL0]], [[UBV2]] +// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]] +// CHECK: [[BBINNBODY]]: +// CHECK: {{.+}} = load i32, i32* [[IV]] +// ... loop body ... +// CHECK: br label %[[BBBODYCONT:.+]] +// CHECK: [[BBBODYCONT]]: +// CHECK: br label %[[BBINNINC:.+]] +// CHECK: [[BBINNINC]]: +// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]] +// CHECK: [[IVINC:%.+]] = add nsw i32 [[IVVAL1]], 1 +// CHECK: store i32 [[IVINC]], i32* [[IV]] +// CHECK: br label %[[BBINNFOR]] +// CHECK: [[BBINNEND]]: +// CHECK: br label %[[LPEXIT:.+]] +// CHECK: [[LPEXIT]]: +// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]]) +// CHECK: ret void + + +// CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void static_chunked(float *a, float *b, float *c, float *d) { + #pragma omp target + #pragma omp teams +#pragma omp distribute dist_schedule(static, 5) + for (unsigned i = 131071; i <= 2147483647; i += 127) { + a[i] = b[i] * c[i] * d[i]; + } +} + +// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]]) +// CHECK: [[TID_ADDR:%.+]] = alloca i32* +// CHECK: [[IV:%.+iv]] = alloca i32 +// CHECK: [[LB:%.+lb]] = alloca i32 +// CHECK: [[UB:%.+ub]] = alloca i32 +// CHECK: [[ST:%.+stride]] = alloca i32 +// CHECK: [[LAST:%.+last]] = alloca i32 +// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]] +// CHECK-DAG: store i32 0, i32* [[LB]] +// CHECK-DAG: store i32 16908288, i32* [[UB]] +// CHECK-DAG: store i32 1, i32* [[ST]] +// CHECK-DAG: store i32 0, i32* [[LAST]] +// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]] +// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]] +// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 91, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 5) +// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]] +// CHECK-DAG: [[USWITCH:%.+]] = icmp ugt i32 [[UBV0]], 16908288 +// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]] +// CHECK-DAG: [[BBCT]]: +// CHECK-DAG: br label %[[BBCE:.+]] +// CHECK-DAG: [[BBCF]]: +// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]] +// CHECK-DAG: br label %[[BBCE]] +// CHECK: [[BBCE]]: +// CHECK: [[SELUB:%.+]] = phi i32 [ 16908288, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ] +// CHECK: store i32 [[SELUB]], i32* [[UB]] +// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]] +// CHECK: store i32 [[LBV0]], i32* [[IV]] +// CHECK: br label %[[BBINNFOR:.+]] +// CHECK: [[BBINNFOR]]: +// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]] +// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]] +// CHECK: [[IVLEUB:%.+]] = icmp ule i32 [[IVVAL0]], [[UBV2]] +// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]] +// CHECK: [[BBINNBODY]]: +// CHECK: {{.+}} = load i32, i32* [[IV]] +// ... loop body ... +// CHECK: br label %[[BBBODYCONT:.+]] +// CHECK: [[BBBODYCONT]]: +// CHECK: br label %[[BBINNINC:.+]] +// CHECK: [[BBINNINC]]: +// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]] +// CHECK: [[IVINC:%.+]] = add i32 [[IVVAL1]], 1 +// CHECK: store i32 [[IVINC]], i32* [[IV]] +// CHECK: br label %[[BBINNFOR]] +// CHECK: [[BBINNEND]]: +// CHECK: br label %[[LPEXIT:.+]] +// CHECK: [[LPEXIT]]: +// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]]) +// CHECK: ret void + +// CHECK-LABEL: test_precond +void test_precond() { + char a = 0; + #pragma omp target + #pragma omp teams + #pragma omp distribute + for(char i = a; i < 10; ++i); +} + +// a is passed as a parameter to the outlined functions +// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], i8* dereferenceable({{[0-9]+}}) [[APARM:%.+]]) +// CHECK: store i8* [[APARM]], i8** [[APTRADDR:%.+]] +// ..many loads of %0.. +// CHECK: [[A2:%.+]] = load i8*, i8** [[APTRADDR]] +// CHECK: [[AVAL0:%.+]] = load i8, i8* [[A2]] +// CHECK: store i8 [[AVAL0]], i8* [[CAP_EXPR:%.+]], +// CHECK: [[AVAL1:%.+]] = load i8, i8* [[CAP_EXPR]] +// CHECK: load i8, i8* [[CAP_EXPR]] +// CHECK: [[AVAL2:%.+]] = load i8, i8* [[CAP_EXPR]] +// CHECK: [[ACONV:%.+]] = sext i8 [[AVAL2]] to i32 +// CHECK: [[ACMP:%.+]] = icmp slt i32 [[ACONV]], 10 +// CHECK: br i1 [[ACMP]], label %[[PRECOND_THEN:.+]], label %[[PRECOND_END:.+]] +// CHECK: [[PRECOND_THEN]] +// CHECK: call void @__kmpc_for_static_init_4 +// CHECK: call void @__kmpc_for_static_fini +// CHECK: [[PRECOND_END]] + +// no templates for now, as these require special handling in target regions and/or declare target + +// HCHECK-LABEL: fint +// HCHECK: call {{.*}}i32 {{.+}}ftemplate +// HCHECK: ret i32 + +// HCHECK: load i16, i16* +// HCHECK: store i16 % +// HCHECK: call i32 @__tgt_target_teams( +// HCHECK: call void @__kmpc_for_static_init_4( +template <typename T> +T ftemplate() { + short aa = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute dist_schedule(static, aa) + for (int i = 0; i < 100; i++) { + } + return T(); +} + +int fint(void) { return ftemplate<int>(); } + +#endif diff --git a/test/OpenMP/distribute_dist_schedule_ast_print.cpp b/test/OpenMP/distribute_dist_schedule_ast_print.cpp new file mode 100644 index 0000000000000..32389ef1496e1 --- /dev/null +++ b/test/OpenMP/distribute_dist_schedule_ast_print.cpp @@ -0,0 +1,106 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, g; + static T a; +// CHECK: static T a; +#pragma omp distribute dist_schedule(static,10) +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 10) + for (int i=0; i < 2; ++i)a=2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp distribute dist_schedule(static,a) +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, a) + for (int i=0; i < 2; ++i)a=2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams +#pragma omp distribute dist_schedule(static,2) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j)foo(); +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 2) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) +// CHECK-NEXT: foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute dist_schedule(static,a) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j)foo(); +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, a) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) +// CHECK-NEXT: foo(); + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); +#pragma omp distribute +// CHECK: #pragma omp distribute + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); + return T(); +} + +int main (int argc, char **argv) { + int b = argc, c, d, e, f, g; + static int a; +// CHECK: static int a; +#pragma omp distribute dist_schedule(static,10) +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 10) + for (int i=0; i < 2; ++i)a=2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp distribute dist_schedule(static,b) +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, b) + for (int i=0; i < 2; ++i)a=2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams +#pragma omp distribute dist_schedule(static,2) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j)foo(); +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 2) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) +// CHECK-NEXT: foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute dist_schedule(static,a) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j)foo(); +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute dist_schedule(static, a) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) +// CHECK-NEXT: foo(); + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); +#pragma omp distribute +// CHECK: #pragma omp distribute + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); +} + +#endif diff --git a/test/OpenMP/distribute_dist_schedule_messages.cpp b/test/OpenMP/distribute_dist_schedule_messages.cpp new file mode 100644 index 0000000000000..98652a20034ea --- /dev/null +++ b/test/OpenMP/distribute_dist_schedule_messages.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note {{declared here}} + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, g; + char ** argv; + static T a; +// CHECK: static T a; + #pragma omp distribute dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute' are ignored}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + return T(); +} + +int main(int argc, char **argv) { + #pragma omp distribute dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute' are ignored}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); + #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_ast_print.cpp b/test/OpenMP/distribute_parallel_for_ast_print.cpp new file mode 100644 index 0000000000000..993cc2a7151f7 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_ast_print.cpp @@ -0,0 +1,139 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, h; + static T a; +// CHECK: static T a; + static T g; +#pragma omp threadprivate(g) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a) + // CHECK: #pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + a++; + // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: a++; + return T(); +} + +int main(int argc, char **argv) { + int b = argc, c, d, e, f, h; + static int a; +// CHECK: static int a; + static float g; +#pragma omp threadprivate(g) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) + // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) dist_schedule(static, b) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + a++; + // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) dist_schedule(static, b) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: a++; + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); +} + +#endif diff --git a/test/OpenMP/distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/distribute_parallel_for_collapse_messages.cpp new file mode 100644 index 0000000000000..41976a69ee2c9 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_collapse_messages.cpp @@ -0,0 +1,154 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp distribute parallel for collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute parallel for', but found only 1}} + // expected-error@+8 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}} + // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+6 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for'}} + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for', but found only 1}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for', but found only 1}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+8 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + // expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}} + // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+5 {{statement after '#pragma omp distribute parallel for' must be a for loop}} + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/distribute_parallel_for_copyin_messages.cpp b/test/OpenMP/distribute_parallel_for_copyin_messages.cpp new file mode 100644 index 0000000000000..7d703413488df --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_copyin_messages.cpp @@ -0,0 +1,190 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2 &operator=(S2 &s2) { return *this; } +}; +class S3 { + int a; + +public: + S3() : a(0) {} + S3 &operator=(S3 &s3) { return *this; } +}; +class S4 { + int a; + S4(); + S4 &operator=(const S4 &s4); // expected-note 3 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} + S5 &operator=(const S5 &s5) { return *this; } // expected-note 3 {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; +template <class T> +class ST { +public: + static T s; +}; + +S2 k; +S3 h; +S4 l(3); +S5 m(4); +#pragma omp threadprivate(h, k, l, m) + +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + +template <class T, typename S, int N> +T tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin // expected-error {{expected '(' after 'copyin'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(l) // expected-error 2 {{'operator=' is a private member of 'S4'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(m) // expected-error 2 {{'operator=' is a private member of 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin // expected-error {{expected '(' after 'copyin'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(l) // expected-error {{'operator=' is a private member of 'S4'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_default_messages.cpp b/test/OpenMP/distribute_parallel_for_default_messages.cpp new file mode 100644 index 0000000000000..3437bd55cf3fb --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_default_messages.cpp @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +template <class T, int N> +T tmain(T argc) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(none) + for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(none) + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp new file mode 100644 index 0000000000000..0f5820ed4bbb8 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note {{declared here}} + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, g; + char ** argv; + static T a; +// CHECK: static T a; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + return T(); +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp new file mode 100644 index 0000000000000..3e288c37d42ce --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp @@ -0,0 +1,359 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}} + foo(); + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp distribute parallel for'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel shared(xa) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}} + foo(); + static int si; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_if_messages.cpp b/test/OpenMP/distribute_parallel_for_if_messages.cpp new file mode 100644 index 0000000000000..c864340a46bfb --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_if_messages.cpp @@ -0,0 +1,179 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for'}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for'}} + for (i = 0; i < argc; ++i) foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp new file mode 100644 index 0000000000000..745007fc48a8d --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp @@ -0,0 +1,333 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + const S2 &operator =(const S2&) const; + S2 &operator =(const S2&); + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { + int a; + S4(); // expected-note 3 {{implicitly declared private here}} + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; + + int v = 0; +#pragma omp target +#pragma omp teams + { +#pragma omp distribute parallel for lastprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp target +#pragma omp teams private(i) +#pragma omp distribute parallel for lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(a) + for (int i = 0; i < 2; ++i) + foo(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp distribute parallel for'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(i) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_num_threads_messages.cpp b/test/OpenMP/distribute_parallel_for_num_threads_messages.cpp new file mode 100644 index 0000000000000..7939514249a07 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_num_threads_messages.cpp @@ -0,0 +1,107 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_private_messages.cpp b/test/OpenMP/distribute_parallel_for_private_messages.cpp new file mode 100644 index 0000000000000..465357a433886 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_private_messages.cpp @@ -0,0 +1,315 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int m; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; + + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp b/test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp new file mode 100644 index 0000000000000..9898f9dc65b69 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +template <class T, typename S, int N> +T tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + return tmain<int, char, 3>(argc, argv); +} diff --git a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp new file mode 100644 index 0000000000000..f23a25e28c029 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp @@ -0,0 +1,441 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + int b; + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+(const S3 &arg1) { return arg1; } +}; +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 3 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + S4(const S4 &s4); + S4 &operator+(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} +#endif + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + static int m; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_schedule_messages.cpp new file mode 100644 index 0000000000000..6363cd7caef01 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_schedule_messages.cpp @@ -0,0 +1,151 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (guided argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{argument to 'schedule' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (guided, (ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'schedule' clause}} + // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (dynamic, 1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (dynamic, foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'schedule' clause}} + // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+5 {{statement after '#pragma omp distribute parallel for' must be a for loop}} + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/distribute_parallel_for_shared_messages.cpp b/test/OpenMP/distribute_parallel_for_shared_messages.cpp new file mode 100644 index 0000000000000..d5725e7f1b09d --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_shared_messages.cpp @@ -0,0 +1,396 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note 2 {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +template <class T, typename S, int N> +T tmain(T argc, S **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int acc = 0; + int n = 1000; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared // expected-error {{expected '(' after 'shared'}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared () // expected-error {{expected expression}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (S1) // expected-error {{'S1' does not refer to a value}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (a, b, c, d, f) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argv[1]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(ba) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(ca) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(da) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(e, g) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } +return T(); +} + + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int acc = 0; + int n = argc; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared // expected-error {{expected '(' after 'shared'}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared () // expected-error {{expected expression}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argc) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (S1) // expected-error {{'S1' does not refer to a value}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (a, b, c, d, f) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared (argv[1]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(ba) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(ca) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(da) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(e, g) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for private(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for firstprivate(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +return tmain<int, char, 1000>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 1000>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp new file mode 100644 index 0000000000000..9c9f3dda281ab --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp @@ -0,0 +1,306 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s + +struct B { + static int ib[20]; // expected-note 0 {{'B::ib' declared here}} + static constexpr int bfoo() { return 8; } +}; +namespace X { + B x; // expected-note {{'x' defined here}} +}; +constexpr int bfoo() { return 4; } + +int **z; +const int C1 = 1; +const int C2 = 2; +void test_aligned_colons(int *&rp) +{ + int *B = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(z:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(X::x : ::z) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(B,rp,::z: X::x) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'B'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(::z) + for (int i = 0; i < 10; ++i) ; + +#pragma omp distribute parallel for simd aligned(B::bfoo()) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(B::ib,B:C1+C2) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (int i = 0; i < 10; ++i) ; +} + +// expected-note@+1 {{'num' defined here}} +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; + // Negative number is passed as L. + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(arr:L) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}} + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(num:4) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (i = 0; i < num; ++i); + + return T(); +} + +template<int LEN> int test_warn() { + int *ind2 = 0; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(ind2:LEN) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}} + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return 0; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; // expected-note {{'a' declared here}} +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 1 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; // expected-note 2 {{'h' defined here}} +#pragma omp threadprivate(h) + +template<class I, class C> int foomain(I argc, C **argv) { + I e(argc); + I g(argc); + int i; // expected-note {{declared here}} expected-note {{'i' defined here}} + // expected-note@+2 {{declared here}} + // expected-note@+1 {{reference to 'i' is not a constant expression}} + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned () // expected-error {{expected expression}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(e, g) + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(i) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (I k = 0; k < argc; ++k) ++k; + + #pragma omp parallel + { + int *v = 0; + I i; + #pragma omp target + #pragma omp teams + #pragma omp distribute parallel for simd aligned(v:16) + for (I k = 0; k < argc; ++k) { i = k; v += 2; } + } + float *f; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + + int v = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(f:j) // expected-note {{initializer of 'j' is not a constant expression}} expected-error {{expression is not an integral constant expression}} + + for (I k = 0; k < argc; ++k) { ++k; v += j; } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + + return 0; +} + +// expected-note@+1 2 {{'argc' defined here}} +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + test_warn<4>(); // ok + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + int i; + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argc) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (a, b) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + for (int k = 0; k < argc; ++k) ++k; + + int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} + foomain<int*,char>(pargc,argv); + return 0; +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp new file mode 100644 index 0000000000000..56809dcd8bd29 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp @@ -0,0 +1,152 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, h; + static T a; +// CHECK: static T a; + static T g; +#pragma omp threadprivate(g) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a) + // CHECK: #pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + a++; + // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: a++; + return T(); +} + +int main(int argc, char **argv) { + int b = argc, c, d, e, f, h; + int x[200]; + static int a; +// CHECK: static int a; + static float g; +#pragma omp threadprivate(g) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) + // CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) dist_schedule(static, b) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + a++; + // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) dist_schedule(static, b) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: a++; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(x:8) linear(h:2) safelen(8) simdlen(8) + for (int i = 0; i < 100; i++) + for (int j = 0; j < 200; j++) + a += h + x[j]; + // CHECK: #pragma omp distribute parallel for simd aligned(x: 8) linear(h: 2) safelen(8) simdlen(8) + // CHECK-NEXT: for (int i = 0; i < 100; i++) + // CHECK-NEXT: for (int j = 0; j < 200; j++) + // CHECK-NEXT: a += h + x[j]; + + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); +} + +#endif diff --git a/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp new file mode 100644 index 0000000000000..8690b4aac432a --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp @@ -0,0 +1,154 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp distribute parallel for simd collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute parallel for simd', but found only 1}} + // expected-error@+8 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+6 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for simd'}} + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+8 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + // expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+5 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp new file mode 100644 index 0000000000000..2d1a3dc5124b8 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp @@ -0,0 +1,190 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2 &operator=(S2 &s2) { return *this; } +}; +class S3 { + int a; + +public: + S3() : a(0) {} + S3 &operator=(S3 &s3) { return *this; } +}; +class S4 { + int a; + S4(); + S4 &operator=(const S4 &s4); // expected-note 3 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} + S5 &operator=(const S5 &s5) { return *this; } // expected-note 3 {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; +template <class T> +class ST { +public: + static T s; +}; + +S2 k; +S3 h; +S4 l(3); +S5 m(4); +#pragma omp threadprivate(h, k, l, m) + +namespace A { +double x; +#pragma omp threadprivate(x) +} +namespace B { +using A::x; +} + +template <class T, typename S, int N> +T tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin // expected-error {{expected '(' after 'copyin'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(l) // expected-error 2 {{'operator=' is a private member of 'S4'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(i) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(m) // expected-error 2 {{'operator=' is a private member of 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin // expected-error {{expected '(' after 'copyin'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(l) // expected-error {{'operator=' is a private member of 'S4'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(i) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(m) // expected-error {{'operator=' is a private member of 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp new file mode 100644 index 0000000000000..5c32306d96d16 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +template <class T, int N> +T tmain(T argc) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(none) + for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(none) + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp new file mode 100644 index 0000000000000..2e3ee2b1d50e4 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note {{declared here}} + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, g; + char ** argv; + static T a; +// CHECK: static T a; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + return T(); +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp new file mode 100644 index 0000000000000..07d30e48312bf --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp @@ -0,0 +1,359 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen(5) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel shared(xa) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); + static int si; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp new file mode 100644 index 0000000000000..01236b5563aba --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp @@ -0,0 +1,179 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp new file mode 100644 index 0000000000000..109fde0577c40 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp @@ -0,0 +1,333 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + const S2 &operator =(const S2&) const; + S2 &operator =(const S2&); + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { + int a; + S4(); // expected-note 3 {{implicitly declared private here}} + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; + + int v = 0; +#pragma omp target +#pragma omp teams + { +#pragma omp distribute parallel for simd lastprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp target +#pragma omp teams private(i) +#pragma omp distribute parallel for simd lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(a) + for (int i = 0; i < 2; ++i) + foo(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen(5) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(i) // expected-note {{defined as lastprivate}} + for (i = 0; i < argc; ++i) // expected-error{{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be lastprivate, predetermined as linear}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp new file mode 100644 index 0000000000000..632ef066c0fac --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp @@ -0,0 +1,338 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +namespace X { + int x; +}; + +struct B { + static int ib; // expected-note {{'B::ib' declared here}} + static int bfoo() { return 8; } +}; + +int bfoo() { return 4; } + +int z; +const int C1 = 1; +const int C2 = 2; +void test_linear_colons() +{ + int B = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B,::z, X::x) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(::z) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B::bfoo()) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; // expected-note {{'ind2' defined here}} + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}} + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template<int LEN> int test_warn() { + int ind2 = 0; + #pragma omp target + #pragma omp teams + #pragma omp parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}} + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return ind2; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template<class I, class C> int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc : 5) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + #pragma omp parallel + { + int v = 0; + int i; + #pragma omp target + #pragma omp teams + #pragma omp distribute parallel for simd linear(v:i) + for (int k = 0; k < argc; ++k) { i = k; v += i; } + } + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd linear(j) + for (int k = 0; k < argc; ++k) ++k; + + int v = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(v:j) + for (int k = 0; k < argc; ++k) { ++k; v += j; } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argc) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + + #pragma omp parallel + { + int i; + #pragma omp target + #pragma omp teams + #pragma omp distribute parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + #pragma omp target + #pragma omp teams + #pragma omp distribute parallel for simd linear(i : 4) + for (int k = 0; k < argc; ++k) { ++k; i += 4; } + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(j) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} + return 0; +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp new file mode 100644 index 0000000000000..6c322e6f60be0 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp @@ -0,0 +1,816 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s + +class S { + int a; + S() : a(0) {} + +public: + S(int v) : a(v) {} + S(const S &s) : a(s.a) {} +}; + +static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} +#pragma omp threadprivate(sii) +static int globalii; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp distribute parallel for simd + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp distribute parallel for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp distribute parallel for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (int &ref = ii; ref < 10; ref++) { + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (int i; i < 10; i++) + c[i] = a[i]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// Ok to skip parenthesises. +#pragma omp distribute parallel for simd + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp distribute parallel for simd + for (int i = 0; i; i++) + c[i] = a[i]; + +#pragma omp target +#pragma omp teams +// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} +#pragma omp distribute parallel for simd + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp distribute parallel for simd + for (int i = 0; !!i; i++) + c[i] = a[i]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp distribute parallel for simd + for (int i = 0; i != 1; i++) + c[i] = a[i]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp distribute parallel for simd + for (int i = 0;; i++) + c[i] = a[i]; + +// Ok. +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +// Ok. +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +// Ok. +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +// Ok - step was converted to integer type. +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-warning@+3 {{relational comparison result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} +#pragma omp distribute parallel for simd firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as private}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be private, predetermined as linear}} +#pragma omp distribute parallel for simd private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be lastprivate, predetermined as linear}} +#pragma omp distribute parallel for simd lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}} +#pragma omp distribute parallel for simd + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + + { +#pragma omp distribute parallel for simd + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + + { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} +#pragma omp distribute parallel for simd + for (auto &item : a) { + item = item + 1; + } + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template <class Iter> +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template <class Iter> +typename iterator_traits<Iter>::difference_type +distance(Iter first, Iter last) { return first - last; } +} +class Iter0 { +public: + Iter0() {} + Iter0(const Iter0 &) {} + Iter0 operator++() { return *this; } + Iter0 operator--() { return *this; } + bool operator<(Iter0 a) { return true; } +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} +int operator-(Iter0 a, Iter0 b) { return 0; } +class Iter1 { +public: + Iter1(float f = 0.0f, double d = 0.0) {} + Iter1(const Iter1 &) {} + Iter1 operator++() { return *this; } + Iter1 operator--() { return *this; } + bool operator<(Iter1 a) { return true; } + bool operator>=(Iter1 a) { return false; } +}; +class GoodIter { +public: + GoodIter() {} + GoodIter(const GoodIter &) {} + GoodIter(int fst, int snd) {} + GoodIter &operator=(const GoodIter &that) { return *this; } + GoodIter &operator=(const Iter0 &that) { return *this; } + GoodIter &operator+=(int x) { return *this; } + explicit GoodIter(void *) {} + GoodIter operator++() { return *this; } + GoodIter operator--() { return *this; } + bool operator!() { return true; } + bool operator<(GoodIter a) { return true; } + bool operator<=(GoodIter a) { return true; } + bool operator>=(GoodIter a) { return false; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} +GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +GoodIter operator-(GoodIter a, int v) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} +GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} +GoodIter operator-(int v, GoodIter a) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}} +GoodIter operator+(int v, GoodIter a) { return GoodIter(); } + +int test_with_random_access_iterator() { + GoodIter begin, end; + Iter0 begin0, end0; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I >= end; --I) + ++I; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (GoodIter I(begin); I < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (GoodIter I(nullptr); I < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (GoodIter I(0); I < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (begin = GoodIter(0); begin < end; ++begin) + ++begin; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} +// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp distribute parallel for simd + for (begin = begin0; begin < end; ++begin) + ++begin; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (begin = end; begin < end; ++begin) + ++begin; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I - I; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; begin < end; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; !I; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I >= end; I = I - 1) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I >= end; I = -I) + ++I; +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I >= end; I = 2 + I) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp distribute parallel for simd + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}} +#pragma omp distribute parallel for simd + for (Iter0 I = begin0; I < end0; ++I) + ++I; +#pragma omp target +#pragma omp teams +// Initializer is constructor without params. +// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (Iter0 I; I < end0; ++I) + ++I; + Iter1 begin1, end1; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp distribute parallel for simd + for (Iter1 I = begin1; I < end1; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +#pragma omp target +#pragma omp teams +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}} +// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +// Initializer is constructor with all default params. +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp distribute parallel for simd + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template <typename IT, int ST> +class TC { +public: + int dotest_lt(IT begin, IT end) { +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template <typename IT, int ST = 0> +int dotest_gt(IT begin, IT end) { +#pragma omp target +#pragma omp teams +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +#pragma omp target +#pragma omp teams +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (IT I = begin; I >= end; I += ST) { + ++I; + } + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp distribute parallel for simd + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp distribute parallel for simd + for (IT I = begin; I < end; I += TC<int, ST>::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC<GoodIter, 100> t1; + TC<GoodIter, -100> t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} + dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + break; // OK in nested loop + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + if (c[i] > 10) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + + if (c[i] > 11) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + c[i] = a[i] + b[i]; + if (c[i] > 10) { + if (c[i] < 20) { + break; // OK + } + } + } + } +} + +void test_loop_eh() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + try { // expected-error {{'try' statement cannot be used in OpenMP simd region}} + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } catch (float f) { + if (f > 0.1) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + return; // expected-error {{cannot return from OpenMP region}} + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + for (int j = 0; j < 10; j++) { + if (c[i] > 10) + throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + } + if (c[9] > 10) + throw c[9]; // OK + +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} + +void test_ordered() { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp distribute parallel for simd'}} + for (int i = 0; i < 16; ++i) + ; +} + +void test_nowait() { +#pragma omp target +#pragma omp teams +// expected-error@+1 2 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}} +#pragma omp distribute parallel for simd nowait nowait // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'nowait' clause}} + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_misc_messages.c b/test/OpenMP/distribute_parallel_for_simd_misc_messages.c new file mode 100644 index 0000000000000..01c079e3dac13 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_misc_messages.c @@ -0,0 +1,971 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute parallel for simd'}} +#pragma omp distribute parallel for simd + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute parallel for simd'}} +#pragma omp distribute parallel for simd foo + +void test_no_clause() { + int i; +#pragma omp distribute parallel for simd + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} +#pragma omp distribute parallel for simd + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (i = 0; i < 16; ++i) { + if (i == 5) + goto L1; // expected-error {{use of undeclared label 'L1'}} + else if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + else if (i == 7) + goto L2; + else if (i == 8) { + L2: + x[i]++; + } + } + + if (x[0] == 0) + goto L2; // expected-error {{use of undeclared label 'L2'}} + else if (x[1] == 1) + goto L1; +} + +void test_invalid_clause() { + int i; +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +#pragma omp distribute parallel for simd foo bar + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +#pragma omp distribute parallel for simd; + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +#pragma omp distribute parallel for simd linear(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +#pragma omp distribute parallel for simd private(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +#pragma omp distribute parallel for simd, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); +void test_safelen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected '('}} +#pragma omp distribute parallel for simd safelen + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd safelen() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp distribute parallel for simd safelen 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(4 + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(4, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute parallel for simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute parallel for simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd safelen(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_simdlen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected '('}} +#pragma omp distribute parallel for simd simdlen + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd simdlen() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp distribute parallel for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute parallel for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute parallel for simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute parallel for simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute parallel for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + +void test_collapse() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected '('}} +#pragma omp distribute parallel for simd collapse + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd collapse( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd collapse() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd collapse(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp distribute parallel for simd collapse 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse(4) + for (int i1 = 0; i1 < 16; ++i1) + for (int i2 = 0; i2 < 16; ++i2) + for (int i3 = 0; i3 < 16; ++i3) + for (int i4 = 0; i4 < 16; ++i4) + foo(); +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute parallel for simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute parallel for simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute parallel for simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd collapse(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute parallel for simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd collapse(2) + for (i = 0; i < 16; ++i) + for (int j = 0; j < 16; ++j) +// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp distribute parallel for simd reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; +} + +void test_linear() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd linear( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd linear(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd linear(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd linear() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd linear(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute parallel for simd linear(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp distribute parallel for simd linear(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp distribute parallel for simd linear(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp distribute parallel for simd linear(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int x, y; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd linear(x :) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd linear(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd linear(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd linear(x : 1, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd linear(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be linear}} +#pragma omp distribute parallel for simd linear(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as private}} +// expected-error@+1 {{private variable cannot be linear}} +#pragma omp distribute parallel for simd private(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be private}} +#pragma omp distribute parallel for simd linear(x) private(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}} +#pragma omp distribute parallel for simd linear(x, y : 0) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be lastprivate}} +#pragma omp distribute parallel for simd linear(x) lastprivate(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+1 {{lastprivate variable cannot be linear}} +#pragma omp distribute parallel for simd lastprivate(x) linear(x) + for (i = 0; i < 16; ++i) + ; +} + +void test_aligned() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd aligned( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd aligned(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd aligned(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd aligned() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd aligned(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute parallel for simd aligned(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp distribute parallel for simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp distribute parallel for simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp distribute parallel for simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int *x, y, z[25]; // expected-note 4 {{'y' defined here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(z) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd aligned(x :) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd aligned(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd aligned(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd aligned(x : 1, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd aligned(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp distribute parallel for simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp distribute parallel for simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as aligned}} +// expected-error@+1 {{a variable cannot appear in more than one aligned clause}} +#pragma omp distribute parallel for simd aligned(x) aligned(z, x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{defined as aligned}} +// expected-error@+2 {{a variable cannot appear in more than one aligned clause}} +// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp distribute parallel for simd aligned(x, y, z) aligned(y, z) + for (i = 0; i < 16; ++i) + ; +} + + +void test_private() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute parallel for simd private( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute parallel for simd private(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute parallel for simd private(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd private() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd private(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute parallel for simd private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute parallel for simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute parallel for simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd lastprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute parallel for simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd firstprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute parallel for simd firstprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute parallel for simd firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd firstprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute parallel for simd firstprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute parallel for simd firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd lastprivate(x, y, z) firstprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_loop_messages() { + float a[100], b[100], c[100]; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp distribute parallel for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp distribute parallel for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp new file mode 100644 index 0000000000000..0d6376d76b7ba --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp @@ -0,0 +1,107 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp new file mode 100644 index 0000000000000..9df368890c8d5 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp @@ -0,0 +1,315 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int m; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; + + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp new file mode 100644 index 0000000000000..6b64cc3879ea4 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +template <class T, typename S, int N> +T tmain(T argc, S **argv) { + T i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + return tmain<int, char, 3>(argc, argv); +} diff --git a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp new file mode 100644 index 0000000000000..7b7e9ea53ccb4 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp @@ -0,0 +1,441 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + int b; + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+(const S3 &arg1) { return arg1; } +}; +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 3 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + S4(const S4 &s4); + S4 &operator+(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} +#endif + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + static int m; +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp new file mode 100644 index 0000000000000..a5fd1aeb8436a --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp @@ -0,0 +1,177 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (4) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); // expected-error {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} + + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp new file mode 100644 index 0000000000000..b3003dd9f2a1b --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp @@ -0,0 +1,151 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (guided argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{argument to 'schedule' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (guided, (ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (dynamic, 1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (dynamic, foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+5 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp new file mode 100644 index 0000000000000..134b852579333 --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp @@ -0,0 +1,396 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note 2 {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +template <class T, typename S, int N> +T tmain(T argc, S **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int acc = 0; + int n = 1000; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared // expected-error {{expected '(' after 'shared'}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared () // expected-error {{expected expression}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (S1) // expected-error {{'S1' does not refer to a value}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (a, b, c, d, f) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argv[1]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(ba) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(ca) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(da) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(e, g) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } +return T(); +} + + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int acc = 0; + int n = argc; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared // expected-error {{expected '(' after 'shared'}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared () // expected-error {{expected expression}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argc) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (S1) // expected-error {{'S1' does not refer to a value}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (a, b, c, d, f) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared (argv[1]) // expected-error {{expected variable name}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(ba) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(ca) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(da) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(e, g) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd private(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd firstprivate(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(i) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd shared(j) + for(int k = 0 ; k < n ; k++) { + acc++; + } + +return tmain<int, char, 1000>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 1000>' requested here}} +} diff --git a/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp new file mode 100644 index 0000000000000..2d813ec232adc --- /dev/null +++ b/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +// expected-error@+5 {{expected ')'}} expected-note@+5 {{to match this '('}} +// expected-error@+4 2 {{expression is not an integral constant expression}} +// expected-note@+3 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (argc + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +// expected-error@+3 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}} expected-error 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (4) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) // expected-error {{expression is not an integral constant expression}} expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}} expected-error 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + foo(); // expected-error {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} + + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/distribute_private_messages.cpp b/test/OpenMP/distribute_private_messages.cpp index 94ba4659c6841..518b64d9e9ca0 100644 --- a/test/OpenMP/distribute_private_messages.cpp +++ b/test/OpenMP/distribute_private_messages.cpp @@ -98,6 +98,7 @@ int main(int argc, char **argv) { #pragma omp target #pragma omp teams firstprivate(i) #pragma omp parallel private(i) + {} #pragma omp target #pragma omp teams reduction(+:i) #pragma omp distribute private(i) @@ -113,20 +114,20 @@ int main(int argc, char **argv) { #pragma omp teams #pragma omp distribute firstprivate(i) for (int k = 0; k < 10; ++k) { - #pragma omp target - #pragma omp teams firstprivate(i) - #pragma omp distribute private(i) - for (int x = 0; x < 10; ++x) foo(); } #pragma omp target + #pragma omp teams firstprivate(i) + #pragma omp distribute private(i) + for (int x = 0; x < 10; ++x) foo(); + #pragma omp target #pragma omp teams reduction(+:i) #pragma omp distribute for (int k = 0; k < 10; ++k) { - #pragma omp target - #pragma omp teams reduction(+:i) - #pragma omp distribute private(i) - for (int x = 0; x < 10; ++x) foo(); } + #pragma omp target + #pragma omp teams reduction(+:i) + #pragma omp distribute private(i) + for (int x = 0; x < 10; ++x) foo(); return 0; } diff --git a/test/OpenMP/distribute_simd_aligned_messages.cpp b/test/OpenMP/distribute_simd_aligned_messages.cpp new file mode 100644 index 0000000000000..59e5be271d0bd --- /dev/null +++ b/test/OpenMP/distribute_simd_aligned_messages.cpp @@ -0,0 +1,306 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s + +struct B { + static int ib[20]; // expected-note 0 {{'B::ib' declared here}} + static constexpr int bfoo() { return 8; } +}; +namespace X { + B x; // expected-note {{'x' defined here}} +}; +constexpr int bfoo() { return 4; } + +int **z; +const int C1 = 1; +const int C2 = 2; +void test_aligned_colons(int *&rp) +{ + int *B = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(z:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(X::x : ::z) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(B,rp,::z: X::x) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'B'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(::z) + for (int i = 0; i < 10; ++i) ; + +#pragma omp distribute simd aligned(B::bfoo()) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(B::ib,B:C1+C2) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (int i = 0; i < 10; ++i) ; +} + +// expected-note@+1 {{'num' defined here}} +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; + // Negative number is passed as L. + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(arr:L) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}} + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(num:4) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (i = 0; i < num; ++i); + + return T(); +} + +template<int LEN> int test_warn() { + int *ind2 = 0; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(ind2:LEN) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}} + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return 0; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; // expected-note {{'a' declared here}} +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 1 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; // expected-note 2 {{'h' defined here}} +#pragma omp threadprivate(h) + +template<class I, class C> int foomain(I argc, C **argv) { + I e(argc); + I g(argc); + int i; // expected-note {{declared here}} expected-note {{'i' defined here}} + // expected-note@+2 {{declared here}} + // expected-note@+1 {{reference to 'i' is not a constant expression}} + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned // expected-error {{expected '(' after 'aligned'}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned () // expected-error {{expected expression}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argv[1]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(e, g) + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + for (I k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(i) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (I k = 0; k < argc; ++k) ++k; + + #pragma omp parallel + { + int *v = 0; + I i; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd aligned(v:16) + for (I k = 0; k < argc; ++k) { i = k; v += 2; } + } + float *f; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + + int v = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(f:j) // expected-note {{initializer of 'j' is not a constant expression}} expected-error {{expression is not an integral constant expression}} + + for (I k = 0; k < argc; ++k) { ++k; v += j; } + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + + return 0; +} + +// expected-note@+1 2 {{'argc' defined here}} +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + test_warn<4>(); // ok + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + int i; + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned // expected-error {{expected '(' after 'aligned'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argc) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (a, b) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + for (int k = 0; k < argc; ++k) ++k; + + int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} + foomain<int*,char>(pargc,argv); + return 0; +} + diff --git a/test/OpenMP/distribute_simd_ast_print.cpp b/test/OpenMP/distribute_simd_ast_print.cpp new file mode 100644 index 0000000000000..04358150b994a --- /dev/null +++ b/test/OpenMP/distribute_simd_ast_print.cpp @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp distribute simd private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp distribute simd private(this->a) private(this->a) + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, h; + static T a; +// CHECK: static T a; + static T g; +#pragma omp threadprivate(g) + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule(static, a) firstprivate(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK: #pragma omp distribute simd dist_schedule(static, a) firstprivate(a) +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) reduction(+ : h) dist_schedule(static,N) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int k = 0; k < 10; ++k) + for (int m = 0; m < 10; ++m) + for (int n = 0; n < 10; ++n) + a++; +// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) reduction(+: h) dist_schedule(static, N) +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: for (int j = 0; j < 2; ++j) +// CHECK-NEXT: for (int k = 0; k < 10; ++k) +// CHECK-NEXT: for (int m = 0; m < 10; ++m) +// CHECK-NEXT: for (int n = 0; n < 10; ++n) +// CHECK-NEXT: a++; + return T(); +} + +int main(int argc, char **argv) { + int b = argc, c, d, e, f, h; + int x[200]; + static int a; +// CHECK: static int a; + static float g; +#pragma omp threadprivate(g) + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule(static, a) private(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK: #pragma omp distribute simd dist_schedule(static, a) private(a) +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) reduction(+ : h) dist_schedule(static, b) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + a++; +// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) +// CHECK-NEXT: a++; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(x:8) linear(h:2) safelen(8) simdlen(8) + for (int i = 0; i < 100; i++) + for (int j = 0; j < 200; j++) + a += h + x[j]; +// CHECK: #pragma omp distribute simd aligned(x: 8) linear(h: 2) safelen(8) simdlen(8) +// CHECK-NEXT: for (int i = 0; i < 100; i++) +// CHECK-NEXT: for (int j = 0; j < 200; j++) +// CHECK-NEXT: a += h + x[j]; + + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); +} + +#endif diff --git a/test/OpenMP/distribute_simd_collapse_messages.cpp b/test/OpenMP/distribute_simd_collapse_messages.cpp new file mode 100644 index 0000000000000..182a09a92b6c8 --- /dev/null +++ b/test/OpenMP/distribute_simd_collapse_messages.cpp @@ -0,0 +1,154 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp distribute simd collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute simd', but found only 1}} + // expected-error@+8 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'collapse' clause}} + // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+6 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute simd'}} + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+8 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + // expected-error@+4 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'collapse' clause}} + // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+5 {{statement after '#pragma omp distribute simd' must be a for loop}} + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/distribute_simd_dist_schedule_messages.cpp b/test/OpenMP/distribute_simd_dist_schedule_messages.cpp new file mode 100644 index 0000000000000..6a8482d8be09b --- /dev/null +++ b/test/OpenMP/distribute_simd_dist_schedule_messages.cpp @@ -0,0 +1,120 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note {{declared here}} + +template <class T, int N> +T tmain(T argc) { + T b = argc, c, d, e, f, g; + char ** argv; + static T a; +// CHECK: static T a; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute simd' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + return T(); +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute simd' cannot contain more than one 'dist_schedule' clause}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) foo(); + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) foo(); + return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}} +} diff --git a/test/OpenMP/distribute_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_simd_firstprivate_messages.cpp new file mode 100644 index 0000000000000..b9267a3037f0b --- /dev/null +++ b/test/OpenMP/distribute_simd_firstprivate_messages.cpp @@ -0,0 +1,359 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}} + foo(); + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen(5) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel shared(xa) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}} + foo(); + static int si; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/distribute_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_simd_lastprivate_messages.cpp new file mode 100644 index 0000000000000..0f96cb4c3ec82 --- /dev/null +++ b/test/OpenMP/distribute_simd_lastprivate_messages.cpp @@ -0,0 +1,333 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + const S2 &operator =(const S2&) const; + S2 &operator =(const S2&); + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { + int a; + S4(); // expected-note 3 {{implicitly declared private here}} + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; + + int v = 0; +#pragma omp target +#pragma omp teams + { +#pragma omp distribute simd lastprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp target +#pragma omp teams private(i) +#pragma omp distribute simd lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(a) + for (int i = 0; i < 2; ++i) + foo(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen(5) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(i) // expected-note {{defined as lastprivate}} + for (i = 0; i < argc; ++i) // expected-error{{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be lastprivate, predetermined as linear}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/distribute_simd_linear_messages.cpp b/test/OpenMP/distribute_simd_linear_messages.cpp new file mode 100644 index 0000000000000..c60e0a2470710 --- /dev/null +++ b/test/OpenMP/distribute_simd_linear_messages.cpp @@ -0,0 +1,338 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +namespace X { + int x; +}; + +struct B { + static int ib; // expected-note {{'B::ib' declared here}} + static int bfoo() { return 8; } +}; + +int bfoo() { return 4; } + +int z; +const int C1 = 1; +const int C2 = 2; +void test_linear_colons() +{ + int B = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B,::z, X::x) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(::z) + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B::bfoo()) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; // expected-note {{'ind2' defined here}} + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}} + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template<int LEN> int test_warn() { + int ind2 = 0; + #pragma omp target + #pragma omp teams + #pragma omp parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}} + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return ind2; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template<class I, class C> int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc : 5) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + #pragma omp parallel + { + int v = 0; + int i; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd linear(v:i) + for (int k = 0; k < argc; ++k) { i = k; v += i; } + } + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd linear(j) + for (int k = 0; k < argc; ++k) ++k; + + int v = 0; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(v:j) + for (int k = 0; k < argc; ++k) { ++k; v += j; } + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argc) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}} + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + + #pragma omp parallel + { + int i; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + #pragma omp target + #pragma omp teams + #pragma omp distribute simd linear(i : 4) + for (int k = 0; k < argc; ++k) { ++k; i += 4; } + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(j) + for (int k = 0; k < argc; ++k) ++k; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} + return 0; +} + diff --git a/test/OpenMP/distribute_simd_loop_messages.cpp b/test/OpenMP/distribute_simd_loop_messages.cpp new file mode 100644 index 0000000000000..b69005578f493 --- /dev/null +++ b/test/OpenMP/distribute_simd_loop_messages.cpp @@ -0,0 +1,782 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s + +static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} +#pragma omp threadprivate(sii) +static int globalii; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 0; i < 10; i+=1) { + c[i] = a[i] + b[i]; + } + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (char i = 0; i < 10; i+='\1') { + c[i] = a[i] + b[i]; + } + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } + #pragma omp target + #pragma omp teams + // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} + #pragma omp distribute simd + for (long long i = 0; i < 10; i+=1.5) { + c[i] = a[i] + b[i]; + } + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (long long i = 0; i < 'z'; i+=1u) { + c[i] = a[i] + b[i]; + } + #pragma omp target + #pragma omp teams + // expected-error@+2 {{variable must be of integer or random access iterator type}} + #pragma omp distribute simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } + #pragma omp target + #pragma omp teams + // expected-error@+2 {{variable must be of integer or random access iterator type}} + #pragma omp distribute simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (int &ref = ii; ref < 10; ref++) { + } + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (int i; i < 10; i++) + c[i] = a[i]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (;ii < 10; ++ii) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-warning@+3 {{expression result unused}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (ii + 1;ii < 10; ++ii) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (c[ii] = 0;ii < 10; ++ii) + c[ii] = a[ii]; + + // Ok to skip parenthesises. + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (((ii)) = 0;ii < 10; ++ii) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} + #pragma omp distribute simd + for (int i = 0; i; i++) + c[i] = a[i]; + + #pragma omp target + #pragma omp teams + // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} + #pragma omp distribute simd + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} + #pragma omp distribute simd + for (int i = 0; !!i; i++) + c[i] = a[i]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} + #pragma omp distribute simd + for (int i = 0; i != 1; i++) + c[i] = a[i]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} + #pragma omp distribute simd + for (int i = 0; ; i++) + c[i] = a[i]; + + // Ok. + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 11; i > 10; i--) + c[i] = a[i]; + + // Ok. + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + + // Ok. + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ++ ++ ii) + c[ii] = a[ii]; + + // Ok but undefined behavior (in general, cannot check that incr + // is really loop-invariant). + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + + // Ok - step was converted to integer type. + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-warning@+3 {{relational comparison result unused}} + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; jj > kk + 2) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-warning@+3 {{expression result unused}} + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; (ii) < 10; ii-=25) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; (ii < 10); ii-=0) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; ii > 10; (ii+=0)) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; ii < 10; (ii) = (1-1)+(ii)) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for ((ii = 0); ii > 10; (ii-=0)) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (ii = 0; (ii < 10); (ii-=0)) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-note@+2 {{defined as private}} + // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be private, predetermined as linear}} + #pragma omp distribute simd private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + // expected-error@+3 {{unexpected OpenMP clause 'shared' in directive '#pragma omp distribute simd'}} + // expected-note@+2 {{defined as shared}} + // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be shared, predetermined as linear}} + #pragma omp distribute simd shared(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + #pragma omp distribute simd linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + #pragma omp target + #pragma omp teams + #pragma omp distribute simd lastprivate(ii) linear(jj) collapse(2) // expected-note {{defined as linear}} + for (ii = 0; ii < 10; ii++) + for (jj = 0; jj < 10; jj++) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be linear, predetermined as lastprivate}} + c[ii] = a[jj]; + + + #pragma omp parallel + { + #pragma omp target + #pragma omp teams +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be threadprivate or thread local, predetermined as linear}} + #pragma omp distribute simd + for (sii = 0; sii < 10; sii+=1) + c[sii] = a[sii]; + } + + #pragma omp parallel + { + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (globalii = 0; globalii < 10; globalii+=1) + c[globalii] = a[globalii]; + } + + #pragma omp parallel + { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + + #pragma omp target + #pragma omp teams + // expected-error@+2 {{statement after '#pragma omp distribute simd' must be a for loop}} + #pragma omp distribute simd + for (auto &item : a) { + item = item + 1; + } + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int (*lb)[4] = nullptr; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int (*p)[4] = lb; p < lb + 8; ++p) { + } + + #pragma omp target + #pragma omp teams + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (int a{0}; a<10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag { }; +template <class Iter> struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template <class Iter> +typename iterator_traits<Iter>::difference_type +distance(Iter first, Iter last) { return first - last; } +} +class Iter0 { + public: + Iter0() { } + Iter0(const Iter0 &) { } + Iter0 operator ++() { return *this; } + Iter0 operator --() { return *this; } + Iter0 operator + (int delta) { return *this; } + bool operator <(Iter0 a) { return true; } +}; +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} +int operator -(Iter0 a, Iter0 b) { return 0; } +class Iter1 { + public: + Iter1(float f=0.0f, double d=0.0) { } + Iter1(const Iter1 &) { } + Iter1 operator ++() { return *this; } + Iter1 operator --() { return *this; } + bool operator <(Iter1 a) { return true; } + bool operator >=(Iter1 a) { return false; } +}; +class GoodIter { + public: + GoodIter() { } + GoodIter(const GoodIter &) { } + GoodIter(int fst, int snd) { } + GoodIter &operator =(const GoodIter &that) { return *this; } + GoodIter &operator =(const Iter0 &that) { return *this; } + GoodIter &operator +=(int x) { return *this; } + explicit GoodIter(void *) { } + GoodIter operator ++() { return *this; } + GoodIter operator --() { return *this; } + bool operator !() { return true; } + bool operator <(GoodIter a) { return true; } + bool operator <=(GoodIter a) { return true; } + bool operator >=(GoodIter a) { return false; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +int operator -(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 2 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} +GoodIter operator -(GoodIter a) { return a; } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +GoodIter operator -(GoodIter a, int v) { return GoodIter(); } +GoodIter operator +(GoodIter a, int v) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} +GoodIter operator -(int v, GoodIter a) { return GoodIter(); } +GoodIter operator +(int v, GoodIter a) { return GoodIter(); } + +int test_with_random_access_iterator() { + GoodIter begin, end; + Iter0 begin0, end0; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (GoodIter I = begin; I < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (GoodIter &I = begin; I < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (GoodIter I = begin; I >= end; --I) + ++I; + #pragma omp target + #pragma omp teams + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (GoodIter I(begin); I < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (GoodIter I(nullptr); I < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (GoodIter I(0); I < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (GoodIter I(1,2); I < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (begin = GoodIter(0); begin < end; ++begin) + ++begin; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (begin = GoodIter(1,2); begin < end; ++begin) + ++begin; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (++begin; begin < end; ++begin) + ++begin; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (begin = end; begin < end; ++begin) + ++begin; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} + #pragma omp distribute simd + for (GoodIter I = begin; I - I; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} + #pragma omp distribute simd + for (GoodIter I = begin; begin < end; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} + #pragma omp distribute simd + for (GoodIter I = begin; !I; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (GoodIter I = begin; I >= end; I = I - 1) + ++I; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} + #pragma omp distribute simd + for (GoodIter I = begin; I >= end; I = -I) + ++I; + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (GoodIter I = begin; I >= end; I = 2 + I) + ++I; + #pragma omp target + #pragma omp teams + // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} + #pragma omp distribute simd + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (Iter0 I = begin0; I < end0; ++I) + ++I; + + #pragma omp target + #pragma omp teams + // Initializer is constructor without params. + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (Iter0 I; I < end0; ++I) + ++I; + + Iter1 begin1, end1; + #pragma omp target + #pragma omp teams + // expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} + // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} + #pragma omp distribute simd + for (Iter1 I = begin1; I < end1; ++I) + ++I; + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (Iter1 I = begin1; I >= end1; ++I) + ++I; + + // Initializer is constructor with all default params. + #pragma omp target + #pragma omp teams + // expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}} + // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} + // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} + #pragma omp distribute simd + for (Iter1 I; I < end1; ++I) { + } + + return 0; +} + +template <typename IT, int ST> class TC { + public: + int dotest_lt(IT begin, IT end) { + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (IT I = begin; I < end; I = I + ST) { + ++I; + } + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be positive due to this condition}} + // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (IT I = begin; I <= end; I += ST) { + ++I; + } + #pragma omp distribute simd + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template <typename IT, int ST=0> int dotest_gt(IT begin, IT end) { + #pragma omp target + #pragma omp teams + // expected-note@+3 2 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } + #pragma omp target + #pragma omp teams + // expected-note@+3 2 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (IT I = begin; I >= end; I += ST) { + ++I; + } + + #pragma omp target + #pragma omp teams + // expected-note@+3 {{loop step is expected to be negative due to this condition}} + // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} + #pragma omp distribute simd + for (IT I = begin; I >= end; ++I) { + ++I; + } + + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (IT I = begin; I < end; I+=TC<int,ST>::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC<GoodIter, 100> t1; + TC<GoodIter, -100> t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} + dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + break; // OK in nested loop + } + switch(i) { + case 1: + b[i]++; + break; + default: + break; + } + if (c[i] > 10) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + + if (c[i] > 11) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + } + + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + c[i] = a[i] + b[i]; + if (c[i] > 10) { + if (c[i] < 20) { + break; // OK + } + } + } + } +} + +void test_loop_eh() { + const int N = 100; + float a[N], b[N], c[N]; + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + try { // expected-error {{'try' statement cannot be used in OpenMP simd region}} + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + catch (float f) { + if (f > 0.1) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + return; // expected-error {{cannot return from OpenMP region}} + } + switch(i) { + case 1: + b[i]++; + break; + default: + break; + } + for (int j = 0; j < 10; j++) { + if (c[i] > 10) + throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + } + if (c[9] > 10) + throw c[9]; // OK + + #pragma omp target + #pragma omp teams + #pragma omp distribute simd + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + diff --git a/test/OpenMP/distribute_simd_misc_messages.c b/test/OpenMP/distribute_simd_misc_messages.c new file mode 100644 index 0000000000000..5fc2cb64cc62b --- /dev/null +++ b/test/OpenMP/distribute_simd_misc_messages.c @@ -0,0 +1,1108 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}} +#pragma omp distribute simd + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}} +#pragma omp distribute simd foo + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}} +#pragma omp distribute simd safelen(4) + +void test_no_clause() { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{statement after '#pragma omp distribute simd' must be a for loop}} +#pragma omp distribute simd + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (i = 0; i < 16; ++i) { + if (i == 5) + goto L1; // expected-error {{use of undeclared label 'L1'}} + else if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + else if (i == 7) + goto L2; + else if (i == 8) { + L2: + x[i]++; + } + } + + if (x[0] == 0) + goto L2; // expected-error {{use of undeclared label 'L2'}} + else if (x[1] == 1) + goto L1; +} + +void test_invalid_clause() { + int i; +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +#pragma omp distribute simd foo bar + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +#pragma omp distribute simd; + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +#pragma omp distribute simd private(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +#pragma omp distribute simd, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); +void test_safelen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected '('}} +#pragma omp distribute simd safelen + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd safelen() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp distribute simd safelen 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(4 + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(4, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// xxpected-error@+1 {{expected expression}} +#pragma omp distribute simd safelen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp distribute simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp distribute simd safelen(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp distribute simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_simdlen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected '('}} +#pragma omp distribute simd simdlen + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd simdlen() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp distribute simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp distribute simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp distribute simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp distribute simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp distribute simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + +void test_collapse() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected '('}} +#pragma omp distribute simd collapse + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd collapse( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd collapse() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd collapse(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp distribute simd collapse 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +// xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse(4) + for (int i1 = 0; i1 < 16; ++i1) + for (int i2 = 0; i2 < 16; ++i2) + for (int i3 = 0; i3 < 16; ++i3) + for (int i4 = 0; i4 < 16; ++i4) + foo(); +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp distribute simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp distribute simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute simd collapse(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp distribute simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +// expected-note@+3 {{defined as reduction}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd collapse(2) reduction(+ : i) + for (i = 0; i < 16; ++i) + // expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+2 2 {{reduction variable must be shared}} +// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp for reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; + +#pragma omp target +#pragma omp teams + for (i = 0; i < 16; ++i) + for (int j = 0; j < 16; ++j) +#pragma omp distribute simd reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; +} + +void test_linear() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd linear( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd linear(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd linear(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd linear() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd linear(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute simd linear(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp distribute simd linear(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp distribute simd linear(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp distribute simd linear(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int x, y; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd linear(x :) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd linear(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd linear(x : 1, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd linear(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be linear}} +#pragma omp distribute simd linear(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as private}} +// expected-error@+1 {{private variable cannot be linear}} +#pragma omp distribute simd private(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be private}} +#pragma omp distribute simd linear(x) private(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}} +#pragma omp distribute simd linear(x, y : 0) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be lastprivate}} +#pragma omp distribute simd linear(x) lastprivate(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+1 {{lastprivate variable cannot be linear}} +#pragma omp distribute simd lastprivate(x) linear(x) + for (i = 0; i < 16; ++i) + ; +} + +void test_aligned() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd aligned( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd aligned(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd aligned(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd aligned() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd aligned(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute simd aligned(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp distribute simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp distribute simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp distribute simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int *x, y, z[25]; // expected-note 4 {{'y' defined here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(z) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd aligned(x :) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd aligned(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd aligned(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd aligned(x : 1, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd aligned(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp distribute simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp distribute simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+2 {{defined as aligned}} +// expected-error@+1 {{a variable cannot appear in more than one aligned clause}} +#pragma omp distribute simd aligned(x) aligned(z, x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-note@+3 {{defined as aligned}} +// expected-error@+2 {{a variable cannot appear in more than one aligned clause}} +// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp distribute simd aligned(x, y, z) aligned(y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_private() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp distribute simd private( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute simd private(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute simd private(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd private() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd private(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute simd private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_firstprivate() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd firstprivate( + for (i = 0; i < 16; ++i) + ; +} + +void test_lastprivate() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 2 {{expected expression}} +#pragma omp distribute simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd lastprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_reduction() { + int i, x, y; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected identifier}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp distribute simd reduction( + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected identifier}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp distribute simd reduction() + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{expected expression}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp distribute simd reduction(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected identifier}} +#pragma omp distribute simd reduction( : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected identifier}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp distribute simd reduction(, + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected expression}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp distribute simd reduction(+ + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd reduction(+: + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd reduction(+ :) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd reduction(+ :, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected expression}} +#pragma omp distribute simd reduction(+ : x, + : y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected identifier}} +#pragma omp distribute simd reduction(% : x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(* : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(- : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(& : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(| : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(^ : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(|| : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(max : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(min : x) + for (i = 0; i < 16; ++i) + ; + struct X { + int x; + }; + struct X X; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute simd reduction(+ : X.x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{expected variable name}} +#pragma omp distribute simd reduction(+ : x + x) + for (i = 0; i < 16; ++i) + ; +} + +void test_loop_messages() { + float a[100], b[100], c[100]; +#pragma omp target +#pragma omp teams +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp distribute simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp target +#pragma omp teams +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp distribute simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +} + +void linear_modifiers(int argc) { + int f; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(f) + for (int k = 0; k < argc; ++k) ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(val(f)) + for (int k = 0; k < argc; ++k) ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(uval(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(ref(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd linear(foo(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; +} + diff --git a/test/OpenMP/distribute_simd_private_messages.cpp b/test/OpenMP/distribute_simd_private_messages.cpp new file mode 100644 index 0000000000000..c777c9971d4b5 --- /dev/null +++ b/test/OpenMP/distribute_simd_private_messages.cpp @@ -0,0 +1,315 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int m; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; + + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/distribute_simd_reduction_messages.cpp b/test/OpenMP/distribute_simd_reduction_messages.cpp new file mode 100644 index 0000000000000..e03b852928082 --- /dev/null +++ b/test/OpenMP/distribute_simd_reduction_messages.cpp @@ -0,0 +1,441 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + int b; + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+(const S3 &arg1) { return arg1; } +}; +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 3 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + S4(const S4 &s4); + S4 &operator+(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} +#endif + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : o) // expected-error {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + static int m; +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/distribute_simd_safelen_messages.cpp b/test/OpenMP/distribute_simd_safelen_messages.cpp new file mode 100644 index 0000000000000..4ae35fb2334da --- /dev/null +++ b/test/OpenMP/distribute_simd_safelen_messages.cpp @@ -0,0 +1,177 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (4) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); // expected-error {{statement after '#pragma omp distribute simd' must be a for loop}} + + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/distribute_simd_simdlen_messages.cpp b/test/OpenMP/distribute_simd_simdlen_messages.cpp new file mode 100644 index 0000000000000..4ae35fb2334da --- /dev/null +++ b/test/OpenMP/distribute_simd_simdlen_messages.cpp @@ -0,0 +1,177 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus >= 201103L + // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus <= 199711L + // expected-error@+6 2 {{expression is not an integral constant expression}} +#else + // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (4) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i-ST]; + + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus <= 199711L + // expected-error@+6 {{expression is not an integral constant expression}} +#else + // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i-4]; + + // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target +#pragma omp teams +#pragma omp distribute simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); // expected-error {{statement after '#pragma omp distribute simd' must be a for loop}} + + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/driver.c b/test/OpenMP/driver.c index f84541bef8ba0..74aaea5071966 100644 --- a/test/OpenMP/driver.c +++ b/test/OpenMP/driver.c @@ -8,3 +8,22 @@ // CHECK-NO-TLS: -cc1 // CHECK-NO-TLS-SAME: -fnoopenmp-use-tls // +// RUN: %clang %s -c -E -dM -fopenmp=libomp | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=1 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=0 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=100 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=31 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// CHECK-DEFAULT-VERSION: #define _OPENMP 201107 + +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=40 | FileCheck --check-prefix=CHECK-40-VERSION %s +// CHECK-40-VERSION: #define _OPENMP 201307 + +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=45 | FileCheck --check-prefix=CHECK-45-VERSION %s +// CHECK-45-VERSION: #define _OPENMP 201511 + +// RUN: %clang %s -c -E -dM -fopenmp-version=1 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-version=31 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-version=40 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-version=45 | FileCheck --check-prefix=CHECK-VERSION %s +// CHECK-VERSION-NOT: #define _OPENMP + diff --git a/test/OpenMP/dump.cpp b/test/OpenMP/dump.cpp new file mode 100644 index 0000000000000..378b53ce5bf19 --- /dev/null +++ b/test/OpenMP/dump.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +int ga, gb; +#pragma omp threadprivate(ga, gb) + +// CHECK: |-OMPThreadPrivateDecl {{.+}} <col:9> col:9 +// CHECK-NEXT: | |-DeclRefExpr {{.+}} <col:27> 'int' lvalue Var {{.+}} 'ga' 'int' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:31> 'int' lvalue Var {{.+}} 'gb' 'int' + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) + +#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + +// CHECK: |-OMPDeclareReductionDecl {{.+}} <line:11:35> col:35 operator+ 'int' combiner +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'int' lvalue Var {{.+}} 'omp_out' 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'int' lvalue Var {{.+}} 'omp_in' 'int' +// CHECK-NEXT: | |-VarDecl {{.+}} <col:35> col:35 implicit used omp_in 'int' +// CHECK-NEXT: | `-VarDecl {{.+}} <col:35> col:35 implicit used omp_out 'int' +// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <col:40> col:40 operator+ 'char' combiner +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'char' lvalue Var {{.+}} 'omp_out' 'char' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <IntegralCast> +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'char' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'char' lvalue Var {{.+}} 'omp_in' 'char' +// CHECK-NEXT: | |-VarDecl {{.+}} <col:40> col:40 implicit used omp_in 'char' +// CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char' +// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:13:37> col:37 fun 'float' combiner initializer +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float' + +struct S { + int a, b; + S() { +#pragma omp parallel for default(none) private(a) shared(b) schedule(static, a) + for (int i = 0; i < 0; ++i) + ++a; + } +}; + +// CHECK: | `-OMPParallelForDirective {{.+}} <line:39:9, col:80> +// CHECK-NEXT: | |-OMPDefaultClause {{.+}} <col:26, col:40> +// CHECK-NEXT: | |-OMPPrivateClause {{.+}} <col:40, col:51> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:48> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &' +// CHECK-NEXT: | |-OMPSharedClause {{.+}} <col:51, col:61> +// CHECK-NEXT: | | `-MemberExpr {{.+}} <col:58> 'int' lvalue ->b +// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'struct S *' this +// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79> +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int' +// CHECK-NEXT: | |-CapturedStmt {{.+}} <line:40:5, <invalid sloc>> +// CHECK-NEXT: | | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc> +// CHECK-NEXT: | | | |-ForStmt {{.+}} <col:5, <invalid sloc>> +// CHECK: | | | | `-UnaryOperator {{.+}} <line:41:7, <invalid sloc>> 'int' lvalue prefix '++' +// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <<invalid sloc>> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &' + +#pragma omp declare simd +#pragma omp declare simd inbranch +void foo(); + +// CHECK: `-FunctionDecl {{.+}} <line:63:1, col:10> col:6 foo 'void (void)' +// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:62:9, col:34> Implicit BS_Inbranch +// CHECK: `-OMPDeclareSimdDeclAttr {{.+}} <line:61:9, col:25> Implicit BS_Undefined + diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp index 3510b904b1c76..182b395c13ca1 100644 --- a/test/OpenMP/for_ast_print.cpp +++ b/test/OpenMP/for_ast_print.cpp @@ -8,6 +8,94 @@ void foo() {} +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + T &b; + typename T::type c:12; + typename T::type &d; + S7() : a(0), b(a), c(0), d(a.a) {} + +public: + S7(typename T::type v) : a(v), b(a), c(v), d(a.a) { +#pragma omp for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp for linear(val(c)) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp for lastprivate(a) lastprivate(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp for linear(uval(this->b)) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S::a) +// CHECK: #pragma omp for linear(val(this->c)) +// CHECK: #pragma omp for private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(T::a) +// CHECK: #pragma omp for linear(val(this->c)) +// CHECK: #pragma omp for private(this->a) private(this->a) +// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) +// CHECK: #pragma omp for linear(uval(this->b)) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp for private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp for linear(ref(S7<S>::d)) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp for lastprivate(a) lastprivate(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp for linear(this->c) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S7<S>::a) +// CHECK: #pragma omp for linear(ref(this->S7<S>::d)) +// CHECK: #pragma omp for private(this->a) private(this->a) +// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) +// CHECK: #pragma omp for linear(this->c) + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, g; diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp index 98761f56c7620..1d24403a09fbf 100644 --- a/test/OpenMP/for_codegen.cpp +++ b/test/OpenMP/for_codegen.cpp @@ -98,8 +98,8 @@ void static_not_chunked(float *a, float *b, float *c, float *d) { // CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void static_chunked(float *a, float *b, float *c, float *d) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) - #pragma omp for schedule(static, 5) -// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 33, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5) + #pragma omp for schedule(monotonic: static, 5) +// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 536870945, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5) // UB = min(UB, GlobalUB) // CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]] // CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288 @@ -158,8 +158,8 @@ void static_chunked(float *a, float *b, float *c, float *d) { // CHECK-LABEL: define {{.*void}} @{{.*}}dynamic1{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void dynamic1(float *a, float *b, float *c, float *d) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) - #pragma omp for schedule(dynamic) -// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 35, i64 0, i64 16908287, i64 1, i64 1) + #pragma omp for schedule(nonmonotonic: dynamic) +// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741859, i64 0, i64 16908287, i64 1, i64 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 @@ -327,12 +327,13 @@ void runtime(float *a, float *b, float *c, float *d) { // CHECK-LABEL: test_precond void test_precond() { // CHECK: [[A_ADDR:%.+]] = alloca i8, + // CHECK: [[CAP:%.+]] = alloca i8, // CHECK: [[I_ADDR:%.+]] = alloca i8, char a = 0; // CHECK: store i8 0, // CHECK: store i32 // CHECK: store i8 - // CHECK: [[A:%.+]] = load i8, i8* [[A_ADDR]], + // CHECK: [[A:%.+]] = load i8, i8* [[CAP]], // CHECK: [[CONV:%.+]] = sext i8 [[A]] to i32 // CHECK: [[CMP:%.+]] = icmp slt i32 [[CONV]], 10 // CHECK: br i1 [[CMP]], label %[[PRECOND_THEN:[^,]+]], label %[[PRECOND_END:[^,]+]] @@ -491,4 +492,25 @@ void loop_with_stmt_expr() { // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( + +// CHECK-LABEL: fint +// CHECK: call {{.*}}i32 {{.*}}ftemplate +// CHECK: ret i32 + +// CHECK: load i16, i16* +// CHECK: store i16 % +// CHECK: call void {{.+}}@__kmpc_fork_call( +// CHECK: call void @__kmpc_for_static_init_4( +template <typename T> +T ftemplate() { + short aa = 0; + +#pragma omp parallel for schedule(static, aa) + for (int i = 0; i < 100; i++) { + } + return T(); +} + +int fint(void) { return ftemplate<int>(); } + #endif // HEADER diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp index d40c305c6271b..a6fdf0066592c 100644 --- a/test/OpenMP/for_collapse_messages.cpp +++ b/test/OpenMP/for_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} #pragma omp for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} - #pragma omp for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp for collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp for' must be a for loop}} diff --git a/test/OpenMP/for_firstprivate_codegen.cpp b/test/OpenMP/for_firstprivate_codegen.cpp index 01a93559451a0..3c6f37229f22e 100644 --- a/test/OpenMP/for_firstprivate_codegen.cpp +++ b/test/OpenMP/for_firstprivate_codegen.cpp @@ -95,7 +95,7 @@ int main() { // LAMBDA: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR_REF]] // LAMBDA: store i{{[0-9]+}} [[SIVAR2_VAL]], i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]] - // LAMBDA: call void @__kmpc_barrier( + // LAMBDA-NOT: call void @__kmpc_barrier( g = 1; g1 = 1; sivar = 2; @@ -158,7 +158,7 @@ int main() { // BLOCKS: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF_ADDRR]] // BLOCKS: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]] - // BLOCKS: call void @__kmpc_barrier( + // BLOCKS-NOT: call void @__kmpc_barrier( g = 1; g1 =1; sivar = 2; @@ -246,7 +246,7 @@ int main() { // CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]] // Synchronization for initialization. -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( @@ -262,31 +262,38 @@ int main() { // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[TVAR:%.+]] = alloca i32, +// CHECK: [[TVAR_CAST:%.+]] = alloca i64, // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: [[TVAR_VAL:%.+]] = load i32, i32* [[TVAR]], +// CHECK: [[TVAR_CONV:%.+]] = bitcast i64* [[TVAR_CAST]] to i32* +// CHECK: store i32 [[TVAR_VAL]], i32* [[TVAR_CONV]], +// CHECK: [[PVT_CASTVAL:%[^,]+]] = load i64, i64* [[TVAR_CAST]], +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i64 [[PVT_CASTVAL]], // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 {{.*}}%{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) // Skip temp vars for loop +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, -// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: %{{.+}} = bitcast i64* [[T_VAR_PRIV]] to i32* -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % // CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % +// CHECK: [[VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % // firstprivate t_var(t_var) -// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], -// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK-NOT: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], // firstprivate vec(vec) // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* @@ -310,10 +317,8 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// Synchronization for initialization. -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// No synchronization for initialization. +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp index 1933de25850e6..60be4f5f2a2b1 100644 --- a/test/OpenMP/for_firstprivate_messages.cpp +++ b/test/OpenMP/for_firstprivate_messages.cpp @@ -143,7 +143,7 @@ int foomain(int argc, char **argv) { foo(); #pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}} #pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}} - for (i = 0; i < argc; ++i) + for (int k = 0; k < argc; ++k) foo(); return 0; } diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp index ea559b08eae0c..2b1d6c3cf97f4 100644 --- a/test/OpenMP/for_lastprivate_codegen.cpp +++ b/test/OpenMP/for_lastprivate_codegen.cpp @@ -8,6 +8,115 @@ #ifndef HEADER #define HEADER +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel +#pragma omp for lastprivate(a, b, c) + for (int i = 0; i < 2; ++i) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel +#pragma omp for lastprivate(a, b, c) + for (int i = 0; i < 2; ++i) + ++(this)->a, --b, this->c /= 1; + }(); +#elif defined(BLOCKS) + ^{ + ++a; + --this->b; + (this)->c /= 1; +#pragma omp parallel +#pragma omp for lastprivate(a, b, c) + for (int i = 0; i < 2; ++i) + ++(this)->a, --b, this->c /= 1; + }(); +#else + ++this->a, --b, c /= 1; +#endif +#pragma omp for + for (a = 0; a < 2; ++a) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel +#pragma omp for lastprivate(b) + for (b = 0; b < 2; ++b) + ++(this)->a, --b, this->c /= 1; + }(); +#elif defined(BLOCKS) + ^{ + ++a; + --this->b; + (this)->c /= 1; +#pragma omp parallel +#pragma omp for + for (c = 0; c < 2; ++c) + ++(this)->a, --b, this->c /= 1; + }(); +#else + ++this->a, --b, c /= 1; +#endif + } +}; + +template <typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp parallel +#pragma omp for lastprivate(a) + for (int i = 0; i < 2; ++i) +#ifdef LAMBDA + [&]() { + [&]() { + ++this->a; +#pragma omp parallel +#pragma omp for lastprivate(a) + for (int i = 0; i < 2; ++i) + ++(this)->a; + }(); + }(); +#elif defined(BLOCKS) + ^{ + ^{ + ++a; +#pragma omp parallel +#pragma omp for lastprivate(a) + for (int i = 0; i < 2; ++i) + ++(this)->a; + }(); + }(); +#else + ++(this)->a; +#endif +#pragma omp for + for (a = 0; a < 2; ++a) +#ifdef LAMBDA + [&]() { + ++this->a; +#pragma omp parallel +#pragma omp for + for (a = 0; a < 2; ++(this)->a) + ++(this)->a; + }(); +#elif defined(BLOCKS) + ^{ + ++a; +#pragma omp parallel +#pragma omp for + for (this->a = 0; a < 2; ++a) + ++(this)->a; + }(); +#else + ++(this)->a; +#endif + } +}; + template <class T> struct S { T f; @@ -23,6 +132,9 @@ volatile int &g1 = g; float f; char cnt; +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 // CHECK: [[S_FLOAT_TY:%.+]] = type { float } // CHECK: [[S_INT_TY:%.+]] = type { i32 } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* @@ -32,6 +144,7 @@ char cnt; template <typename T> T tmain() { S<T> test; + SST<T> sst; T t_var __attribute__((aligned(128))) = T(); T vec[] __attribute__((aligned(128))) = {1, 2}; S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; @@ -54,17 +167,75 @@ using A::x; int main() { static int sivar; + SS ss(sivar); #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, // LAMBDA-LABEL: @main - // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: alloca [[SS_TY]], + // LAMBDA: alloca [[CAP_TY:%.+]], + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]([[CAP_TY]]* [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* %{{.+}}) #pragma omp parallel #pragma omp for lastprivate(g, g1, sivar) for (int i = 0; i < 2; ++i) { + // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 + // LAMBDA: store i8 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void + // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA: call void {{.+}} [[SS_LAMBDA:@[^ ]+]] + // LAMBDA: call void @__kmpc_for_static_fini(% + // LAMBDA: ret + + // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) + // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0 + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 + // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2 + // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* + // LAMBDA: call{{.*}} void + // LAMBDA: call void @__kmpc_for_static_fini( + // LAMBDA: br i1 + // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 + // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]], + // LAMBDA: br label + // LAMBDA: ret void + + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], + // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], + // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], + // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], + // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA: call void @__kmpc_for_static_fini( + // LAMBDA: br i1 + // LAMBDA: br label + // LAMBDA: ret void + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, @@ -128,6 +299,7 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main + // BLOCKS: call // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* @@ -191,6 +363,60 @@ int main() { } }(); return 0; +// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// BLOCKS: store i8 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void +// BLOCKS: call void @__kmpc_for_static_init_4( +// BLOCKS-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS: call void +// BLOCKS: call void @__kmpc_for_static_fini(% +// BLOCKS: ret + +// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0 +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2 +// BLOCKS: call void @__kmpc_for_static_init_4( +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* +// BLOCKS: call{{.*}} void +// BLOCKS: call void @__kmpc_for_static_fini( +// BLOCKS: br i1 +// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]], +// BLOCKS: br label +// BLOCKS: ret void + +// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// BLOCKS: call void @__kmpc_for_static_init_4( +// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS: call void @__kmpc_for_static_fini( +// BLOCKS: br i1 +// BLOCKS: br label +// BLOCKS: ret void #else S<float> test; int t_var = 0; @@ -414,7 +640,52 @@ int main() { // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret -// + +// CHECK: define {{.+}} @{{.+}}([[SS_TY]]* +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: store i8 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: call void @__kmpc_for_static_fini(% +// CHECK: ret + +// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: br i1 +// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// CHECK: store i8 %{{.+}}, i8* [[B_REF]], +// CHECK: br label +// CHECK: ret void + // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, diff --git a/test/OpenMP/for_linear_codegen.cpp b/test/OpenMP/for_linear_codegen.cpp index db9788361dd0f..0ad45f5b7054f 100644 --- a/test/OpenMP/for_linear_codegen.cpp +++ b/test/OpenMP/for_linear_codegen.cpp @@ -23,6 +23,74 @@ volatile int &g1 = g; float f; char cnt; +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel +#pragma omp for linear(a, b, c) + for (int i = 0; i < 2; ++i) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel +#pragma omp for linear(a, b) linear(ref(c)) + for (int i = 0; i < 2; ++i) + ++(this)->a, --b, this->c /= 1; + }(); +#elif defined(BLOCKS) + ^{ + ++a; + --this->b; + (this)->c /= 1; +#pragma omp parallel +#pragma omp for linear(a, b) linear(uval(c)) + for (int i = 0; i < 2; ++i) + ++(this)->a, --b, this->c /= 1; + }(); +#else + ++this->a, --b, c /= 1; +#endif + } +}; + +template <typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp parallel +#pragma omp for linear(a) + for (int i = 0; i < 2; ++i) +#ifdef LAMBDA + [&]() { + [&]() { + ++this->a; +#pragma omp parallel +#pragma omp for linear(a) + for (int i = 0; i < 2; ++i) + ++(this)->a; + }(); + }(); +#elif defined(BLOCKS) + ^{ + ^{ + ++a; +#pragma omp parallel +#pragma omp for linear(a) + for (int i = 0; i < 2; ++i) + ++(this)->a; + }(); + }(); +#else + ++(this)->a; +#endif + } +}; + +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 // CHECK: [[S_FLOAT_TY:%.+]] = type { float } // CHECK: [[S_INT_TY:%.+]] = type { i32 } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* @@ -31,6 +99,7 @@ char cnt; template <typename T> T tmain() { S<T> test; + SST<T> sst; T *pvar = &test.f; T &lvar = test.f; #pragma omp parallel @@ -42,16 +111,75 @@ T tmain() { } int main() { + static int sivar; + SS ss(sivar); #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main - // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: alloca [[SS_TY]], + // LAMBDA: alloca [[CAP_TY:%.+]], + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]([[CAP_TY]]* [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel #pragma omp for linear(g, g1:5) for (int i = 0; i < 2; ++i) { + // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 + // LAMBDA: store i8 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void + // LAMBDA: ret + + // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) + // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0 + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 + // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2 + // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* + // LAMBDA: call{{.*}} void + // LAMBDA: call void @__kmpc_for_static_fini( + // LAMBDA: br i1 + // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 + // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]], + // LAMBDA: br label + // LAMBDA: ret void + + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], + // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], + // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], + // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], + // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA: call void @__kmpc_for_static_fini( + // LAMBDA: br i1 + // LAMBDA: br label + // LAMBDA: ret void + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}}, @@ -96,6 +224,7 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main + // BLOCKS: call // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* @@ -146,6 +275,60 @@ int main() { } }(); return 0; +// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// BLOCKS: store i8 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void +// BLOCKS: ret + +// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0 +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2 +// BLOCKS: call void @__kmpc_for_static_init_4( +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* +// BLOCKS: call{{.*}} void +// BLOCKS: call void @__kmpc_for_static_fini( +// BLOCKS: br i1 +// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]], +// BLOCKS: br label +// BLOCKS: ret void + +// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: alloca i{{[0-9]+}}, +// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// BLOCKS: call void @__kmpc_for_static_init_4( +// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS: call void @__kmpc_for_static_fini( +// BLOCKS: br i1 +// BLOCKS: br label +// BLOCKS: ret void #else S<float> test; float *pvar = &test.f; @@ -216,7 +399,51 @@ int main() { // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 2, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32**, i32*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret -// + +// CHECK: define {{.+}} @{{.+}}([[SS_TY]]* +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: store i8 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void +// CHECK: ret + +// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: br i1 +// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// CHECK: store i8 %{{.+}}, i8* [[B_REF]], +// CHECK: br label +// CHECK: ret void + // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32** dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}) // CHECK: alloca i{{[0-9]+}}, // CHECK: [[PVAR_START:%.+]] = alloca i32*, diff --git a/test/OpenMP/for_linear_messages.cpp b/test/OpenMP/for_linear_messages.cpp index 39fb21ef7be0a..ab8934979ac30 100644 --- a/test/OpenMP/for_linear_messages.cpp +++ b/test/OpenMP/for_linear_messages.cpp @@ -212,7 +212,7 @@ int main(int argc, char **argv) { #pragma omp for linear(i) ordered(1) // expected-error {{'linear' clause cannot be specified along with 'ordered' clause with a parameter}} for (int k = 0; k < argc; ++k) ++k; - foomain<int,char>(argc,argv); + foomain<int,char>(argc,argv); // expected-note {{n instantiation of function template specialization 'foomain<int, char>' requested here}} return 0; } diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp index 895baf57e9ccc..bb58a77e5adeb 100644 --- a/test/OpenMP/for_loop_messages.cpp +++ b/test/OpenMP/for_loop_messages.cpp @@ -426,12 +426,25 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +class GoodIter1 { +public: + GoodIter1() {} + GoodIter1(const GoodIter1 &) {} + GoodIter1 &operator++(int) { return *this; } + GoodIter1 &operator=(const GoodIter1 &that) { return *this; } + GoodIter1 &operator+=(int x) { return *this; } + friend long operator-(const GoodIter1 &, const GoodIter1 &); + GoodIter1 &operator-(int) { return *this; } + bool operator<(GoodIter1 a) { return true; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -482,7 +495,7 @@ int test_with_random_access_iterator() { #pragma omp for for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp for @@ -572,6 +585,10 @@ int test_with_random_access_iterator() { #pragma omp for for (Iter1 I; I < end1; ++I) { } + GoodIter1 I1, E1; +#pragma omp for + for (GoodIter1 I = I1; I < E1; I++) + ; return 0; } diff --git a/test/OpenMP/for_ordered_clause.cpp b/test/OpenMP/for_ordered_clause.cpp index 8af509ab9aa87..3335f4046f571 100644 --- a/test/OpenMP/for_ordered_clause.cpp +++ b/test/OpenMP/for_ordered_clause.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -36,16 +41,23 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here} #pragma omp for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}} -// expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}} -// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}} -// expected-error@+1 2 {{expression is not an integral constant expression}} +// expected-error@+6 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}} +// expected-error@+5 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +// expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L +// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp for ordered(foobool(argc)), ordered(true), ordered(-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; #pragma omp for ordered(S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; -// expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L +// expected-error@+4 2 {{expression is not an integral constant expression}} +#else +// expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; @@ -84,10 +96,17 @@ int main(int argc, char **argv) { #pragma omp for ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} expected-note {{as specified in 'ordered' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}} -#pragma omp for ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} +// expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L +// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp for ordered(foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; -// expected-error@+3 {{expression is not an integral constant expression}} +// expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L +// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}} // expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}} #pragma omp for ordered(foobool(argc)), ordered(true), ordered(-5) @@ -96,7 +115,11 @@ int main(int argc, char **argv) { #pragma omp for ordered(S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; -// expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L +// expected-error@+4 {{expression is not an integral constant expression}} +#else +// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp index 3015f819b5447..4045c5b56ff5c 100644 --- a/test/OpenMP/for_private_messages.cpp +++ b/test/OpenMP/for_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -126,6 +174,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp for private // expected-error {{expected '(' after 'private'}} @@ -190,6 +240,8 @@ int main(int argc, char **argv) { for(int k = 0; k < argc; ++k) si = k + 1; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp index 423ab3ce76d0a..6997d8138842c 100644 --- a/test/OpenMP/for_reduction_codegen.cpp +++ b/test/OpenMP/for_reduction_codegen.cpp @@ -52,6 +52,8 @@ T tmain() { return T(); } +extern S<float> **foo(); + int main() { #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double @@ -182,6 +184,9 @@ int main() { S<float> s_arr[] = {1, 2}; S<float> &var = test; S<float> var1, arrs[10][4]; + S<float> **var2 = foo(); + S<float> vvar2[2]; + S<float> (&var3)[2] = s_arr; #pragma omp parallel #pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) for (int i = 0; i < 2; ++i) { @@ -192,6 +197,26 @@ int main() { #pragma omp parallel for reduction(+:arr[1][:vec[1]]) reduction(&:arrs[1:vec[1]][1:2]) for (int i = 0; i < 10; ++i) ++arr[1][i]; +#pragma omp parallel +#pragma omp for reduction(+:arr) reduction(&:arrs) + for (int i = 0; i < 10; ++i) + ++arr[1][i]; +#pragma omp parallel +#pragma omp for reduction(& : var2[0 : 5][1 : 6]) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp for reduction(& : vvar2[0 : 5]) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp for reduction(& : var3[1 : 2]) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp for reduction(& : var3) + for (int i = 0; i < 10; ++i) + ; return tmain<int>(); #endif } @@ -201,6 +226,11 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret @@ -666,6 +696,316 @@ int main() { // CHECK: ret void +// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}}) + +// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]], + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [3 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]], + +// Check initialization of private copy. +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: store i32 0, i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// Check initialization of private copy. +// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]* +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* % +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], +// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]* + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call void @__kmpc_for_static_init_4( +// Skip checks for internal operations. +// CHECK: call void @__kmpc_for_static_fini( + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 0 +// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]], +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 1 +// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]], +// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV_BEGIN]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]], + +// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: [[BITCAST:%.+]] = bitcast [3 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 24, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// CHECK: [[CASE1]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0:%.+]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = add nsw i32 % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false) +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// __kmpc_end_reduce(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// CHECK: [[CASE2]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: atomicrmw add i32* %{{.+}}, i32 %{{.+}} monotonic +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @__kmpc_critical( +// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false) +// CHECK: call void @__kmpc_end_critical( +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] + +// Check destruction of private copy. +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: br +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* % +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[BEGIN]] +// CHECK: br i1 [[DONE]], +// CHECK: call void @llvm.stackrestore(i8* +// CHECK: call void @__kmpc_barrier( + +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// arr_rhs = (int*)rhs[0]; +// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]], +// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32* +// arr_lhs = (int*)lhs[0]; +// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]], +// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32* + +// arr_size = (size_t)lhs[1]; +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 +// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]], +// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64 + +// arrs_rhs = (S<float>*)rhs[2]; +// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 +// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]], +// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]* +// arrs_lhs = (S<float>*)lhs[2]; +// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 +// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]], +// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]* + +// arr_lhs[:] += arr_rhs[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = add nsw i32 % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs_lhs = arrs_lhs.operator &(arrs_rhs); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false) +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) + +// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]], + +// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], +// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 0 +// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 1 +// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], +// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4 +// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6 +// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], +// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]], +// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 +// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64) +// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], +// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64) +// CHECK: [[PSEUDO_VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV]], i64 [[OFFSET]] +// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** % +// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}) + +// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]], + +// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0 +// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4 +// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]* +// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 +// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64) +// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], +// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64) +// CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]] +// CHECK: [[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]] to [2 x [[S_FLOAT_TY]]]* +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}) + +// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]], +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1 +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2 +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]* +// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 +// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64) +// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], +// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64) +// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]] +// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2 x [[S_FLOAT_TY]]]* + +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** % + +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}) + +// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, +// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]], +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]* +// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0 +// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2 + +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** % + +// CHECK: ret void + // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) diff --git a/test/OpenMP/for_reduction_codegen_UDR.cpp b/test/OpenMP/for_reduction_codegen_UDR.cpp new file mode 100644 index 0000000000000..a30df368663db --- /dev/null +++ b/test/OpenMP/for_reduction_codegen_UDR.cpp @@ -0,0 +1,984 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +#ifndef HEADER +#define HEADER + +volatile double g, g_orig; +volatile double &g1 = g_orig; + +struct BaseS { + int x; +}; +struct BaseS1 { + float y; +}; + +template <class T> +struct S : public BaseS, public BaseS1 { + T f; + S(T a) : f(a + g) {} + S() : f(g) {} + ~S() {} +}; +void red(BaseS1&, const BaseS1&); +void red_plus(BaseS1&, const BaseS1&); +void init(BaseS1&, const BaseS1&); +void init1(BaseS1&, const BaseS1&); +void init2(BaseS1&, const BaseS1&); +void init_plus(BaseS1&, const BaseS1&); +#pragma omp declare reduction(operator& : BaseS1 : red(omp_out, omp_in)) initializer(init(omp_priv, omp_orig)) +#pragma omp declare reduction(+ : BaseS1 : red_plus(omp_out, omp_in)) initializer(init_plus(omp_priv, omp_orig)) +#pragma omp declare reduction(&& : S<float>, S<int> : omp_out.f *= omp_in.f) initializer(init1(omp_priv, omp_orig)) + +// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { %{{[^,]+}}, %{{[^,]+}}, float } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { %{{[^,]+}}, %{{[^,]+}}, i{{[0-9]+}} } +// CHECK-DAG: [[ATOMIC_REDUCE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8* +// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* +// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8* +// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer + +#pragma omp declare reduction(operator&& : int : omp_out = 111 & omp_in) +template <typename T> +T tmain() { + T t; + S<T> test; + T t_var = T(), t_var1; + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> &var = test; + S<T> var1; +#pragma omp declare reduction(operator& : T : omp_out = 15 + omp_in) +#pragma omp declare reduction(operator+ : T : omp_out = 1513 + omp_in) initializer(omp_priv = 321) +#pragma omp declare reduction(min : T : omp_out = 47 - omp_in) initializer(omp_priv = 432 / omp_orig) +#pragma omp declare reduction(operator&& : S<T> : omp_out.f = 17 * omp_in.f) initializer(init2(omp_priv, omp_orig)) +#pragma omp declare reduction(operator&& : T : omp_out = 17 * omp_in) +#pragma omp parallel +#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1) nowait + for (int i = 0; i < 2; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } +#pragma omp parallel +#pragma omp for reduction(&& : t_var) + for (int i = 0; i < 2; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } + return T(); +} + +extern S<float> **foo(); + +#pragma omp declare reduction(operator- : float, double : omp_out = 333 + omp_in) +#pragma omp declare reduction(min : float, double : omp_out = 555 + omp_in) +int main() { +#pragma omp declare reduction(operator+ : float, double : omp_out = 222 - omp_in) initializer(omp_priv = -1) + S<float> test; + float t_var = 0, t_var1; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> &var = test; + S<float> var1, arrs[10][4]; + S<float> **var2 = foo(); + S<float> vvar2[2]; + S<float>(&var3)[2] = s_arr; +#pragma omp declare reduction(operator+ : int : omp_out = 555 * omp_in) initializer(omp_priv = 888) +#pragma omp parallel +#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1) + for (int i = 0; i < 2; ++i) { + vec[i] = t_var; + s_arr[i] = var; + } + int arr[10][vec[1]]; +#pragma omp parallel for reduction(+ : arr[1][ : vec[1]]) reduction(& : arrs[1 : vec[1]][1 : 2]) + for (int i = 0; i < 10; ++i) + ++arr[1][i]; +#pragma omp parallel +#pragma omp for reduction(+ : arr) reduction(& : arrs) + for (int i = 0; i < 10; ++i) + ++arr[1][i]; +#pragma omp parallel +#pragma omp for reduction(& : var2[0 : 5][1 : 6]) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp for reduction(& : vvar2[0 : 5]) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp for reduction(& : var3[1 : 2]) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp for reduction(& : var3) + for (int i = 0; i < 10; ++i) + ; + return tmain<int>(); +} + +// CHECK: define {{.*}}i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void +// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca float, +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[T_VAR1_PRIV:%.+]] = alloca float, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[T_VAR_REF:%.+]] = load float*, float** % +// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** % + +// For + reduction operation initial value of private variable is -1. +// CHECK: store float -1.0{{.+}}, float* + +// For & reduction operation initial value of private variable is defined by call of 'init()' function. +// CHECK: call {{.*}}void @_Z4initR6BaseS1RKS_( + +// For && reduction operation initial value of private variable is 1.0. +// CHECK: call {{.*}}void @_Z5init1R6BaseS1RKS_( + +// For min reduction operation initial value of private variable is largest repesentable value. +// CHECK: [[INIT:%.+]] = load float, float* @ +// CHECK: store float [[INIT]], float* [[T_VAR1_PRIV]], + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call void @__kmpc_for_static_init_4( +// Skip checks for internal operations. +// CHECK: call void @__kmpc_for_static_fini( + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0 +// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]], +// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]], +// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]], +// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3 +// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]], + +// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// t_var += t_var_reduction; +// CHECK: fsub float 2.220000e+02, % + +// var = var.operator &(var_reduction); +// CHECK: call {{.*}}void @_Z3redR6BaseS1RKS_( + +// var1 = var1.operator &&(var1_reduction); +// CHECK: fmul float + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: fadd float 5.550000e+02, % + +// __kmpc_end_reduce(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// t_var += t_var_reduction; +// CHECK: call void @__kmpc_critical( +// CHECK: fsub float 2.220000e+02, % +// CHECK: call void @__kmpc_end_critical( + +// var = var.operator &(var_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: call {{.*}}void @_Z3redR6BaseS1RKS_( +// CHECK: call void @__kmpc_end_critical( + +// var1 = var1.operator &&(var1_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: fmul float +// CHECK: call void @__kmpc_end_critical( + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: fadd float 5.550000e+02, % +// CHECK: call void @__kmpc_end_critical( + +// __kmpc_end_reduce(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// t_var_lhs = (float*)lhs[0]; +// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 +// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]], +// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float* +// t_var_rhs = (float*)rhs[0]; +// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 +// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]], +// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float* + +// var_lhs = (S<float>*)lhs[1]; +// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1 +// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]], +// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]* +// var_rhs = (S<float>*)rhs[1]; +// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 +// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]], +// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]* + +// var1_lhs = (S<float>*)lhs[2]; +// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 +// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]], +// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]* +// var1_rhs = (S<float>*)rhs[2]; +// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 +// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]], +// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]* + +// t_var1_lhs = (float*)lhs[3]; +// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3 +// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]], +// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float* +// t_var1_rhs = (float*)rhs[3]; +// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3 +// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]], +// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float* + +// t_var_lhs += t_var_rhs; +// CHECK: fsub float 2.220000e+02, % + +// var_lhs = var_lhs.operator &(var_rhs); +// CHECK: call {{.*}}void @_Z3redR6BaseS1RKS_( + +// var1_lhs = var1_lhs.operator &&(var1_rhs); +// CHECK: fmul float + +// t_var1_lhs = min(t_var1_lhs, t_var1_rhs); +// CHECK: fadd float 5.550000e+02, % +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}}) + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}} +// CHECK: [[LB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// CHECK: [[LB1_0:%.+]] = getelementptr inbounds i32, i32* [[LB1]], i64 0 +// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}} +// CHECK: [[UB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// CHECK: [[UB1_UP:%.+]] = getelementptr inbounds i32, i32* [[UB1]], i64 % +// CHECK: [[UB_CAST:%.+]] = ptrtoint i32* [[UB1_UP]] to i64 +// CHECK: [[LB_CAST:%.+]] = ptrtoint i32* [[LB1_0]] to i64 +// CHECK: [[DIFF:%.+]] = sub i64 [[UB_CAST]], [[LB_CAST]] +// CHECK: [[SIZE_1:%.+]] = sdiv exact i64 [[DIFF]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64) +// CHECK: [[ARR_SIZE:%.+]] = add nuw i64 [[SIZE_1]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]], + +// Check initialization of private copy. +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: store i32 888, i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// CHECK: [[ARRS_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[ARRS_SIZE:%.+]], + +// Check initialization of private copy. +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_PRIV]], i64 [[ARRS_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_PRIV]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_Z4initR6BaseS1RKS_(% +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call void @__kmpc_for_static_init_4( +// Skip checks for internal operations. +// CHECK: call void @__kmpc_for_static_fini( + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0 +// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]], +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1 +// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]], +// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]], +// CHECK: [[ARRS_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3 +// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARRS_SIZE]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARRS_SIZE_REF]], + +// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// CHECK: [[CASE1]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = mul nsw i32 555, % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 [[ARRS_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// __kmpc_end_reduce(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// CHECK: [[CASE2]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: call void @__kmpc_critical( +// CHECK: [[ADD:%.+]] = mul nsw i32 555, % +// CHECK: call void @__kmpc_end_critical( +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 [[ARRS_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @__kmpc_critical( +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: call void @__kmpc_end_critical( +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] + +// Check destruction of private copy. +// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_PRIV]], i64 [[ARRS_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_PRIV]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* % +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[ARRS_PRIV]] +// CHECK: br i1 [[DONE]], +// CHECK: call void @llvm.stackrestore(i8* + +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// arr_rhs = (int*)rhs[0]; +// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]], +// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32* +// arr_lhs = (int*)lhs[0]; +// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]], +// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32* + +// arr_size = (size_t)lhs[1]; +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 +// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]], +// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64 + +// arrs_rhs = (S<float>*)rhs[2]; +// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 +// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]], +// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]* +// arrs_lhs = (S<float>*)lhs[2]; +// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 +// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]], +// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]* + +// arrs_size = (size_t)lhs[3]; +// CHECK: [[ARRS_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3 +// CHECK: [[ARRS_SIZE_VOID:%.+]] = load i8*, i8** [[ARRS_SIZE_REF]], +// CHECK: [[ARRS_SIZE:%.+]] = ptrtoint i8* [[ARRS_SIZE_VOID]] to i64 + +// arr_lhs[:] += arr_rhs[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = mul nsw i32 555, % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs_lhs = arrs_lhs.operator &(arrs_rhs); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 [[ARRS_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}}) + +// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]], + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [3 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]], + +// Check initialization of private copy. +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: store i32 888, i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// Check initialization of private copy. +// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]* +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_Z4initR6BaseS1RKS_(% +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], +// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]* + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call void @__kmpc_for_static_init_4( +// Skip checks for internal operations. +// CHECK: call void @__kmpc_for_static_fini( + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 0 +// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]], +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 1 +// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]], +// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV_BEGIN]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]], + +// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: [[BITCAST:%.+]] = bitcast [3 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 24, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// CHECK: [[CASE1]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0:%.+]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%[^ ]+]] = mul nsw i32 555, % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// __kmpc_end_reduce(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// CHECK: [[CASE2]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: call void @__kmpc_critical( +// CHECK: [[ADD:%.+]] = mul nsw i32 555, % +// CHECK: call void @__kmpc_end_critical( +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @__kmpc_critical( +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: call void @__kmpc_end_critical( +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] + +// Check destruction of private copy. +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: br +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* % +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[BEGIN]] +// CHECK: br i1 [[DONE]], +// CHECK: call void @llvm.stackrestore(i8* +// CHECK: call void @__kmpc_barrier( + +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// arr_rhs = (int*)rhs[0]; +// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]], +// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32* +// arr_lhs = (int*)lhs[0]; +// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]], +// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32* + +// arr_size = (size_t)lhs[1]; +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 +// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]], +// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64 + +// arrs_rhs = (S<float>*)rhs[2]; +// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 +// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]], +// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]* +// arrs_lhs = (S<float>*)lhs[2]; +// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 +// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]], +// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]* + +// arr_lhs[:] += arr_rhs[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = mul nsw i32 555, % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs_lhs = arrs_lhs.operator &(arrs_rhs); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) + +// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]], + +// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], +// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 0 +// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 1 +// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], +// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4 +// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6 +// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], +// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]], +// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 +// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64) +// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], +// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64) +// CHECK: [[PSEUDO_VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV]], i64 [[OFFSET]] +// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** % +// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}}) + +// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]], + +// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0 +// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4 +// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]* +// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 +// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64) +// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], +// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64) +// CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]] +// CHECK: [[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]] to [2 x [[S_FLOAT_TY]]]* +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}}) + +// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]], +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1 +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2 +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]* +// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 +// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64) +// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], +// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64) +// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]] +// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2 x [[S_FLOAT_TY]]]* + +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** % + +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}}) + +// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, +// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]], +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], +// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]* +// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0 +// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2 + +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** % + +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(12) %{{.+}}, [[S_INT_TY]]* dereferenceable(12) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(24) %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}}, + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % +// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % + +// For + reduction operation initial value of private variable is 0. +// CHECK: store i32 321, i32* % + +// For & reduction operation initial value of private variable is ones in all bits. +// CHECK: call void @_Z4initR6BaseS1RKS_( + +// For && reduction operation initial value of private variable is 1.0. +// CHECK: call void @_Z5init2R6BaseS1RKS_( + +// For min reduction operation initial value of private variable is largest repesentable value. +// CHECK: sdiv i32 432, % + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call void @__kmpc_for_static_init_4( +// Skip checks for internal operations. +// CHECK: call void @__kmpc_for_static_fini( + +// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; + +// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0 +// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]], +// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]], +// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]], +// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3 +// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]], + +// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); + +// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// t_var += t_var_reduction; +// CHECK: add nsw i32 1513, % + +// var = var.operator &(var_reduction); +// CHECK: call void @_Z3redR6BaseS1RKS_(% + +// var1 = var1.operator &&(var1_reduction); +// CHECK: mul nsw i32 17, % + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: sub nsw i32 47, % + +// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>); +// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// t_var += t_var_reduction; +// CHECK: call void @__kmpc_critical( +// CHECK: add nsw i32 1513, % +// CHECK: call void @__kmpc_end_critical( + +// var = var.operator &(var_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: call void @_Z3redR6BaseS1RKS_(% +// CHECK: call void @__kmpc_end_critical( + +// var1 = var1.operator &&(var1_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: mul nsw i32 17, % +// CHECK: call void @__kmpc_end_critical( + +// t_var1 = min(t_var1, t_var1_reduction); +// CHECK: call void @__kmpc_critical( +// CHECK: sub nsw i32 47, % +// CHECK: call void @__kmpc_end_critical( + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: ret void + +// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], +// *(Type<n>-1*)rhs[<n>-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// t_var_lhs = (i{{[0-9]+}}*)lhs[0]; +// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 +// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]], +// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}* +// t_var_rhs = (i{{[0-9]+}}*)rhs[0]; +// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 +// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]], +// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}* + +// var_lhs = (S<i{{[0-9]+}}>*)lhs[1]; +// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1 +// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]], +// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]* +// var_rhs = (S<i{{[0-9]+}}>*)rhs[1]; +// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 +// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]], +// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]* + +// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2]; +// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 +// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]], +// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]* +// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2]; +// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 +// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]], +// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]* + +// t_var1_lhs = (i{{[0-9]+}}*)lhs[3]; +// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3 +// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]], +// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}* +// t_var1_rhs = (i{{[0-9]+}}*)rhs[3]; +// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3 +// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]], +// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}* + +// t_var_lhs += t_var_rhs; +// CHECK: add nsw i32 1513, % + +// var_lhs = var_lhs.operator &(var_rhs); +// CHECK: call void @_Z3redR6BaseS1RKS_(% + +// var1_lhs = var1_lhs.operator &&(var1_rhs); +// CHECK: mul nsw i32 17, % + +// t_var1_lhs = min(t_var1_lhs, t_var1_rhs); +// CHECK: sub nsw i32 47, % +// CHECK: ret void + +#endif + diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp index 317f88ce11ba9..45a4681440fc2 100644 --- a/test/OpenMP/for_reduction_messages.cpp +++ b/test/OpenMP/for_reduction_messages.cpp @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -33,7 +33,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -55,9 +55,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable: no known conversion from 'int' to 'S6' for 1st argument}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable: no known conversion from 'int' to 'S6' for 1st argument}} #endif int a; @@ -123,7 +123,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp for reduction(foo : argc) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -135,11 +135,11 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -147,15 +147,15 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -175,7 +175,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -187,7 +187,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -304,15 +304,15 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel diff --git a/test/OpenMP/for_simd_aligned_messages.cpp b/test/OpenMP/for_simd_aligned_messages.cpp index 1007b3c545cc0..cef83c30e239c 100644 --- a/test/OpenMP/for_simd_aligned_messages.cpp +++ b/test/OpenMP/for_simd_aligned_messages.cpp @@ -196,6 +196,7 @@ int main(int argc, char **argv) { #pragma omp for simd aligned(h) for (int k = 0; k < argc; ++k) ++k; int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} foomain<int*,char>(pargc,argv); return 0; } diff --git a/test/OpenMP/for_simd_ast_print.cpp b/test/OpenMP/for_simd_ast_print.cpp index d4b13ba1998c8..54f0d4676134d 100644 --- a/test/OpenMP/for_simd_ast_print.cpp +++ b/test/OpenMP/for_simd_ast_print.cpp @@ -6,6 +6,57 @@ #ifndef HEADER #define HEADER +struct S1 { + S1(): a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for simd private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp for simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp for simd private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp for simd private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for simd private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp for simd private(this->a) private(this->a) + void foo() {} int g_ind = 1; template<class T, class N> T reduct(T* arr, N num) { diff --git a/test/OpenMP/for_simd_codegen.cpp b/test/OpenMP/for_simd_codegen.cpp index e1aa8926418f8..fb282d0511bb5 100644 --- a/test/OpenMP/for_simd_codegen.cpp +++ b/test/OpenMP/for_simd_codegen.cpp @@ -54,13 +54,13 @@ void simple(float *a, float *b, float *c, float *d) { long long k = get_val(); - #pragma omp for simd linear(k : 3) schedule(dynamic) + #pragma omp for simd linear(k : 3) schedule(simd, nonmonotonic: dynamic) // CHECK: [[K0:%.+]] = call {{.*}}i64 @{{.*}}get_val // CHECK-NEXT: store i64 [[K0]], i64* [[K_VAR:%[^,]+]] // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_VAR]] // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] -// CHECK: call void @__kmpc_dispatch_init_4(%ident_t* {{.+}}, i32 %{{.+}}, i32 35, i32 0, i32 8, i32 1, i32 1) +// CHECK: call void @__kmpc_dispatch_init_4(%ident_t* {{.+}}, i32 %{{.+}}, i32 1073741859, i32 0, i32 8, i32 1, i32 1) // CHECK: [[NEXT:%.+]] = call i32 @__kmpc_dispatch_next_4(%ident_t* {{.+}}, i32 %{{.+}}, i32* %{{.+}}, i32* [[LB:%.+]], i32* [[UB:%.+]], i32* %{{.+}}) // CHECK: [[COND:%.+]] = icmp ne i32 [[NEXT]], 0 // CHECK: br i1 [[COND]], label %[[CONT:.+]], label %[[END:.+]] @@ -362,7 +362,7 @@ template <class T, unsigned K> T tfoo(T a) { return a + K; } template <typename T, unsigned N> int templ1(T a, T *z) { - #pragma omp for simd collapse(N) + #pragma omp for simd collapse(N) schedule(simd: static, N) for (int i = 0; i < N * 2; i++) { for (long long j = 0; j < (N + N + N + N); j += 2) { z[i + j] = a + tfoo<T, N>(i + j); @@ -373,7 +373,7 @@ int templ1(T a, T *z) { // Instatiation templ1<float,2> // CHECK-LABEL: define {{.*i32}} @{{.*}}templ1{{.*}}(float {{.+}}, float* {{.+}}) -// CHECK: call void @__kmpc_for_static_init_8(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 34, i32* %{{[^,]+}}, i64* [[LB:%[^,]+]], i64* [[UB:%[^,]+]], i64* [[STRIDE:%[^,]+]], i64 1, i64 1) +// CHECK: call void @__kmpc_for_static_init_8(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 45, i32* %{{[^,]+}}, i64* [[LB:%[^,]+]], i64* [[UB:%[^,]+]], i64* [[STRIDE:%[^,]+]], i64 1, i64 2) // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], // CHECK: [[CMP:%.+]] = icmp sgt i64 [[UB_VAL]], 15 // CHECK: br i1 [[CMP]], label %[[TRUE:.+]], label %[[FALSE:[^,]+]] @@ -389,6 +389,7 @@ int templ1(T a, T *z) { // CHECK: store i64 [[LB_VAL]], i64* [[T1_OMP_IV:%[^,]+]], // ... +// CHECK: icmp sle i64 // CHECK: [[IV:%.+]] = load i64, i64* [[T1_OMP_IV]] // CHECK-NEXT: [[UB_VAL:%.+]] = load i64, i64* [[UB]] // CHECK-NEXT: [[CMP1:%.+]] = icmp sle i64 [[IV]], [[UB_VAL]] @@ -581,9 +582,11 @@ void collapsed(float *a, float *b, float *c, float *d) { } // i,j,l are updated; k is not updated. // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) -// CHECK-NEXT: store i32 3, i32* [[I:%[^,]+]] -// CHECK-NEXT: store i32 5, i32* [[I:%[^,]+]] -// CHECK-NEXT: store i16 9, i16* [[I:%[^,]+]] +// CHECK: br i1 +// CHECK: store i32 3, i32* +// CHECK-NEXT: store i32 5, +// CHECK-NEXT: store i32 7, +// CHECK-NEXT: store i16 9, i16* // CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK: ret void } diff --git a/test/OpenMP/for_simd_collapse_messages.cpp b/test/OpenMP/for_simd_collapse_messages.cpp index 5c9d058b975c6..2efd49479ea9f 100644 --- a/test/OpenMP/for_simd_collapse_messages.cpp +++ b/test/OpenMP/for_simd_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for simd', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} #pragma omp for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} - #pragma omp for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp for simd collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} diff --git a/test/OpenMP/for_simd_firstprivate_messages.cpp b/test/OpenMP/for_simd_firstprivate_messages.cpp index cb74ee081710c..4e96866c1a2c2 100644 --- a/test/OpenMP/for_simd_firstprivate_messages.cpp +++ b/test/OpenMP/for_simd_firstprivate_messages.cpp @@ -147,7 +147,7 @@ int foomain(int argc, char **argv) { foo(); #pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}} #pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} - for (i = 0; i < argc; ++i) + for (int k = 0; k < argc; ++k) foo(); return 0; } diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp index 44370a15664fb..3f93125a38a29 100644 --- a/test/OpenMP/for_simd_linear_messages.cpp +++ b/test/OpenMP/for_simd_linear_messages.cpp @@ -208,7 +208,7 @@ int main(int argc, char **argv) { #pragma omp for simd linear(i) for (int k = 0; k < argc; ++k) ++k; - foomain<int,char>(argc,argv); + foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} return 0; } diff --git a/test/OpenMP/for_simd_loop_messages.cpp b/test/OpenMP/for_simd_loop_messages.cpp index afd7b0bb545e5..e9729a8fc26d8 100644 --- a/test/OpenMP/for_simd_loop_messages.cpp +++ b/test/OpenMP/for_simd_loop_messages.cpp @@ -408,12 +408,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -465,7 +465,7 @@ int test_with_random_access_iterator() { for (begin = GoodIter(0); begin < end; ++begin) ++begin; #pragma omp parallel -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp for simd for (begin = begin0; begin < end; ++begin) diff --git a/test/OpenMP/for_simd_private_messages.cpp b/test/OpenMP/for_simd_private_messages.cpp index 15e235c2f8f41..ca4c3a33fcaff 100644 --- a/test/OpenMP/for_simd_private_messages.cpp +++ b/test/OpenMP/for_simd_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -119,6 +167,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp for simd private // expected-error {{expected '(' after 'private'}} @@ -180,6 +230,8 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) m = k + 2; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp index 000960fb55b53..2935cec602dd2 100644 --- a/test/OpenMP/for_simd_reduction_messages.cpp +++ b/test/OpenMP/for_simd_reduction_messages.cpp @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -122,7 +122,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -134,11 +134,11 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -146,15 +146,15 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -174,7 +174,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -186,7 +186,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -295,15 +295,15 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel diff --git a/test/OpenMP/for_simd_safelen_messages.cpp b/test/OpenMP/for_simd_safelen_messages.cpp index d70e90198ad6e..fa1b4442cee49 100644 --- a/test/OpenMP/for_simd_safelen_messages.cpp +++ b/test/OpenMP/for_simd_safelen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd safelen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}} - // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd safelen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd safelen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp for simd safelen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}} // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} diff --git a/test/OpenMP/for_simd_simdlen_messages.cpp b/test/OpenMP/for_simd_simdlen_messages.cpp index c72e546811924..8fe197979cc27 100644 --- a/test/OpenMP/for_simd_simdlen_messages.cpp +++ b/test/OpenMP/for_simd_simdlen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd simdlen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}} - // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd simdlen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp for simd simdlen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp for simd simdlen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}} // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} #pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} diff --git a/test/OpenMP/loops_explicit_clauses_codegen.cpp b/test/OpenMP/loops_explicit_clauses_codegen.cpp new file mode 100644 index 0000000000000..dc21fd11af6f9 --- /dev/null +++ b/test/OpenMP/loops_explicit_clauses_codegen.cpp @@ -0,0 +1,162 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + + +#ifndef HEADER +#define HEADER + +#define N 10 +int foo(); +int bar(); +int k; +// CHECK-LABEL: @main +int main(int argc, char **argv) { + foo(); +// CHECK: @{{.+}}foo +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK-NOT: @k +// CHECK: call void @__kmpc_for_static_fini( +// CHECK-NOT: @k +#pragma omp for private(k) + for (k = 0; k < argc; k++) + ; + foo(); +// CHECK: @{{.+}}foo +// CHECK: call void @__kmpc_for_static_init_8( +// CHECK-NOT: @k +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: store i32 %{{.+}}, i32* @k +#pragma omp for lastprivate(k) collapse(2) + for (int i = 0; i < 2; ++i) + for (k = 0; k < argc; k++) + ; + foo(); +// CHECK: @{{.+}}foo +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: sdiv i32 +// CHECK: store i32 %{{.+}}, i32* @k, +#pragma omp simd linear(k : 2) + for (k = 0; k < argc; k++) + bar(); +// CHECK: @{{.+}}foo +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: sdiv i32 +// CHECK: store i32 %{{.+}}, i32* @k, + foo(); +#pragma omp simd lastprivate(k) collapse(2) + for (int i = 0; i < 2; ++i) + for (k = 0; k < argc; k++) + bar() ; + foo(); +// CHECK: @{{.+}}foo +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: sdiv i32 +// CHECK: store i32 %{{.+}}, i32* @k, +#pragma omp simd + for (k = 0; k < argc; k++) + bar(); + foo(); +// CHECK: @{{.+}}foo +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access +// CHECK: sdiv i32 +// CHECK: store i32 %{{.+}}, i32* @k, +#pragma omp simd collapse(2) + for (int i = 0; i < 2; ++i) + for (k = 0; k < argc; k++) + bar(); +// CHECK: @{{.+}}foo + foo(); + return 0; +} + +struct S { + int k; + S(int argc) { + foo(); +// CHECK: @{{.+}}foo +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: call void @__kmpc_for_static_fini( +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +#pragma omp for private(k) + for (k = 0; k < argc; k++) + ; + foo(); +// CHECK: @{{.+}}foo +// CHECK: call void @__kmpc_for_static_init_8( +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: call void @__kmpc_for_static_fini( +#pragma omp for lastprivate(k) collapse(2) + for (int i = 0; i < 2; ++i) + for (k = 0; k < argc; k++) + ; + foo(); +// CHECK: @{{.+}}foo +// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: br i1 +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: br label {{.+}}, !llvm.loop +// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +#pragma omp simd linear(k : 2) + for (k = 0; k < argc; k++) + bar(); + foo(); +// CHECK: @{{.+}}foo +// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: br i1 +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: add nsw i64 %{{.+}}, 1 +// CHECK: br label {{.+}}, !llvm.loop +// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +#pragma omp simd lastprivate(k) collapse(2) + for (int i = 0; i < 2; ++i) + for (k = 0; k < argc; k++) + bar(); + foo(); +// CHECK: @{{.+}}foo +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: br i1 +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: br label {{.+}}, !llvm.loop +// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +#pragma omp simd + for (k = 0; k < argc; k++) + bar(); + foo(); +// CHECK: @{{.+}}foo +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: br i1 +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access +// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +// CHECK: add nsw i64 %{{.+}}, 1 +// CHECK: br label {{.+}}, !llvm.loop +// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0 +#pragma omp simd collapse(2) + for (int i = 0; i < 2; ++i) + for (k = 0; k < argc; k++) + bar(); +// CHECK: @{{.+}}foo + foo(); + } +} s(N); + +#endif // HEADER diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp index b2b87db6a158a..b6082e7447ddc 100644 --- a/test/OpenMP/nesting_of_regions.cpp +++ b/test/OpenMP/nesting_of_regions.cpp @@ -97,6 +97,27 @@ void foo() { } #pragma omp parallel { +#pragma omp target parallel + ++a; + } +#pragma omp parallel + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp parallel + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp parallel + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -112,7 +133,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } - +#pragma omp parallel + { +#pragma omp target update to(a) + } +#pragma omp parallel + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + // SIMD DIRECTIVE #pragma omp simd for (int i = 0; i < 10; ++i) { @@ -122,7 +165,7 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} for (int i = 0; i < 10; ++i) ; } @@ -226,6 +269,16 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp ordered simd // OK + bar(); + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -236,6 +289,27 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -251,6 +325,28 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for// expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } // FOR DIRECTIVE #pragma omp for @@ -398,6 +494,27 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { +#pragma omp target parallel + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -413,6 +530,28 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // FOR SIMD DIRECTIVE #pragma omp for simd @@ -423,7 +562,7 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} for (int i = 0; i < 10; ++i) ; } @@ -527,6 +666,16 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { +#pragma omp ordered simd // OK + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { #pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -537,6 +686,27 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -552,6 +722,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } // SECTIONS DIRECTIVE #pragma omp sections @@ -706,6 +899,25 @@ void foo() { } #pragma omp sections { +#pragma omp target parallel + ++a; + } +#pragma omp sections + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp target enter data map(to: a) + } +#pragma omp sections + { +#pragma omp target exit data map(from: a) + } +#pragma omp sections + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -721,6 +933,28 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp target update to(a) + } +#pragma omp sections + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SECTION DIRECTIVE #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} @@ -911,6 +1145,37 @@ void foo() { #pragma omp sections { #pragma omp section +#pragma omp target parallel + ++a; + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target enter data map(to: a) + ++a; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target exit data map(from: a) + ++a; + } + } +#pragma omp sections + { +#pragma omp section #pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -928,6 +1193,35 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp section + { + bar(); +#pragma omp target update to(a) + } + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SINGLE DIRECTIVE #pragma omp single @@ -1065,6 +1359,27 @@ void foo() { } #pragma omp single { +#pragma omp target parallel + ++a; + } +#pragma omp single + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp single + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp single + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -1080,6 +1395,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp single + { +#pragma omp target update to(a) + bar(); + } +#pragma omp single + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // MASTER DIRECTIVE #pragma omp master @@ -1217,6 +1555,27 @@ void foo() { } #pragma omp master { +#pragma omp target parallel + ++a; + } +#pragma omp master + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp master + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp master + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -1232,6 +1591,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp master + { +#pragma omp target update to(a) + bar(); + } +#pragma omp master + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -1383,6 +1765,27 @@ void foo() { } #pragma omp critical { +#pragma omp target parallel + ++a; + } +#pragma omp critical + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp critical + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp critical + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -1398,6 +1801,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp critical + { +#pragma omp target update to(a) + bar(); + } +#pragma omp critical + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -1550,6 +1976,27 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp target parallel + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -1565,6 +2012,28 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // PARALLEL FOR SIMD DIRECTIVE #pragma omp parallel for simd @@ -1575,7 +2044,7 @@ void foo() { } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd// expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} for (int i = 0; i < 10; ++i) ; } @@ -1717,6 +2186,27 @@ void foo() { } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -1732,6 +2222,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -1875,6 +2388,25 @@ void foo() { } #pragma omp parallel sections { +#pragma omp target parallel + ++a; + } +#pragma omp parallel sections + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { +#pragma omp target enter data map(to: a) + } +#pragma omp parallel sections + { +#pragma omp target exit data map(from: a) + } +#pragma omp parallel sections + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -1890,6 +2422,28 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel sections + { +#pragma omp target update to(a) + } +#pragma omp parallel sections + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // TASK DIRECTIVE #pragma omp task @@ -1979,6 +2533,25 @@ void foo() { } #pragma omp task { +#pragma omp target parallel + ++a; + } +#pragma omp task +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp task + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp task + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp task + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -1994,6 +2567,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp task + { +#pragma omp target update to(a) + bar(); + } +#pragma omp task + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp task + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp task + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // ORDERED DIRECTIVE #pragma omp ordered @@ -2141,6 +2737,37 @@ void foo() { } #pragma omp ordered { +#pragma omp target parallel + ++a; + } +#pragma omp ordered + { +#pragma omp target parallel for ordered + for (int j = 0; j < 10; ++j) { +#pragma omp ordered // OK + { + bar(); + } + } + } +#pragma omp ordered + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp ordered + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp ordered + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -2156,6 +2783,30 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp ordered + { + bar(); +#pragma omp target update to(a) + bar(); + } +#pragma omp ordered + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // ATOMIC DIRECTIVE #pragma omp atomic @@ -2322,6 +2973,35 @@ void foo() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}} ++a; } @@ -2341,6 +3021,37 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } // TARGET DIRECTIVE #pragma omp target @@ -2432,10 +3143,19 @@ void foo() { } #pragma omp target { +#pragma omp target // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } #pragma omp target + { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} ++a; } #pragma omp target +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target { #pragma omp teams ++a; @@ -2446,6 +3166,12 @@ void foo() { #pragma omp teams // expected-note {{nested teams construct here}} ++a; } +#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}} + { + while (0) // expected-note {{statement outside teams construct here}} +#pragma omp teams // expected-note {{nested teams construct here}} + ++a; + } #pragma omp target { #pragma omp taskloop @@ -2458,6 +3184,402 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp target + { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}} + } +#pragma omp target + { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} + } +#pragma omp target + { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}} + } +#pragma omp target + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// TARGET PARALLEL DIRECTIVE +#pragma omp target parallel +#pragma omp parallel + bar(); +#pragma omp target parallel +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp sections + { + bar(); + } +#pragma omp target parallel +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel region}} + { + bar(); + } +#pragma omp target parallel +#pragma omp single + bar(); + +#pragma omp target parallel +#pragma omp master + { + bar(); + } +#pragma omp target parallel +#pragma omp critical + { + bar(); + } +#pragma omp target parallel +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp parallel sections + { + bar(); + } +#pragma omp target parallel +#pragma omp task + { + bar(); + } +#pragma omp target parallel + { +#pragma omp taskyield + bar(); + } +#pragma omp target parallel + { +#pragma omp barrier + bar(); + } +#pragma omp target parallel + { +#pragma omp taskwait + bar(); + } +#pragma omp target parallel + { +#pragma omp flush + bar(); + } +#pragma omp target parallel + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target parallel + { +#pragma omp atomic + ++a; + } +#pragma omp target parallel + { +#pragma omp target // expected-error {{region cannot be nested inside 'target parallel' region}} + ++a; + } +#pragma omp target parallel + { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel' region}} + ++a; + } +#pragma omp target parallel +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel' region}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target parallel + { + ++a; +#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target parallel + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target parallel + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel + { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel' region}} + } +#pragma omp target parallel + { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}} + } +#pragma omp target parallel + { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel' region}} + } +#pragma omp target parallel + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// TARGET PARALLEL FOR DIRECTIVE +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel for region}} + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + { + bar(); + } + } + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{region cannot be closely nested inside 'target parallel for' region}} + { + bar(); + } + } + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp critical + { + bar(); + } + } + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + { +#pragma omp single // OK + { + bar(); + } +#pragma omp for // OK + for (int i = 0; i < 10; ++i) + ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; +#pragma omp sections // OK + { + bar(); + } + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp task + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target parallel for' region}} + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp flush + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target parallel for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel for' region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel for' region}} + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // TEAMS DIRECTIVE #pragma omp target @@ -2575,6 +3697,29 @@ void foo() { #pragma omp target #pragma omp teams { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams + { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target enter data' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -2598,6 +3743,41 @@ void foo() { #pragma omp distribute for (int j = 0; j < 10; ++j) ; +#pragma omp target +#pragma omp teams + { +#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}} + } +#pragma omp target +#pragma omp teams + { +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute parallel for + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target +#pragma omp teams + { +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute parallel for simd + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target +#pragma omp teams + { +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute simd + for (int j = 0; j < 10; ++j) + ; + } // TASKLOOP DIRECTIVE #pragma omp taskloop @@ -2740,6 +3920,27 @@ void foo() { } #pragma omp taskloop for (int i = 0; i < 10; ++i) { +#pragma omp target parallel + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -2749,6 +3950,36 @@ void foo() { for (int i = 0; i < 10; ++i) ++a; } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) + bar(); + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ++a; + } + // DISTRIBUTE DIRECTIVE #pragma omp target #pragma omp teams @@ -2927,7 +4158,36 @@ void foo() { #pragma omp teams #pragma omp distribute for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } #pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} ++a; } #pragma omp target @@ -2937,6 +4197,495 @@ void foo() { #pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } + +// DISTRIBUTE PARALLEL FOR DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a distribute parallel for region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp critical + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + { +#pragma omp single + { + bar(); + } + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp task + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp flush + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { +#pragma omp single + { + bar(); + } + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } } void foo() { @@ -3033,6 +4782,25 @@ void foo() { } #pragma omp parallel { +#pragma omp target parallel + ++a; + } +#pragma omp parallel +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp parallel + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp parallel + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -3048,6 +4816,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel + { +#pragma omp target update to(a) + a++; + } +#pragma omp parallel + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SIMD DIRECTIVE #pragma omp simd @@ -3058,7 +4849,7 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { -#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} for (int i = 0; i < 10; ++i) ; } @@ -3165,6 +4956,27 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -3180,6 +4992,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + a++; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } // FOR DIRECTIVE #pragma omp for @@ -3317,6 +5152,27 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { +#pragma omp target parallel + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -3332,6 +5188,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // FOR SIMD DIRECTIVE #pragma omp for simd @@ -3342,7 +5221,7 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} for (int i = 0; i < 10; ++i) ; } @@ -3449,6 +5328,27 @@ void foo() { } #pragma omp for simd for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -3464,6 +5364,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } // SECTIONS DIRECTIVE #pragma omp sections @@ -3593,6 +5516,25 @@ void foo() { } #pragma omp sections { +#pragma omp target parallel + ++a; + } +#pragma omp sections + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp target enter data map(to: a) + } +#pragma omp sections + { +#pragma omp target exit data map(from: a) + } +#pragma omp sections + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -3608,6 +5550,28 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp target update to(a) + } +#pragma omp sections + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SECTION DIRECTIVE #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} @@ -3803,6 +5767,39 @@ void foo() { { #pragma omp section { +#pragma omp target parallel + ++a; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target enter data map(to: a) + ++a; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target exit data map(from: a) + ++a; + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -3823,6 +5820,35 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target update to(a) + a++; + } + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SINGLE DIRECTIVE #pragma omp single @@ -3950,6 +5976,27 @@ void foo() { } #pragma omp single { +#pragma omp target parallel + ++a; + } +#pragma omp single + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp single + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp single + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -3965,6 +6012,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp single + { +#pragma omp target update to(a) + a++; + } +#pragma omp single + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // MASTER DIRECTIVE #pragma omp master @@ -4102,6 +6172,27 @@ void foo() { } #pragma omp master { +#pragma omp target parallel + ++a; + } +#pragma omp master + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp master + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp master + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -4117,6 +6208,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp master + { +#pragma omp target update to(a) + ++a; + } +#pragma omp master + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -4273,6 +6387,27 @@ void foo() { } #pragma omp critical { +#pragma omp target parallel + ++a; + } +#pragma omp critical + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp critical + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp critical + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -4288,6 +6423,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp critical + { +#pragma omp target update to(a) + a++; + } +#pragma omp critical + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -4440,6 +6598,27 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp target parallel + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -4455,6 +6634,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) + a++; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // PARALLEL FOR SIMD DIRECTIVE #pragma omp parallel for simd @@ -4465,7 +6667,7 @@ void foo() { } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { -#pragma omp simd// expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} for (int i = 0; i < 10; ++i) ; } @@ -4607,6 +6809,27 @@ void foo() { } #pragma omp parallel for simd for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} ++a; } @@ -4622,6 +6845,29 @@ void foo() { for (int j = 0; j < 10; ++j) ; } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + a++; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int j = 0; j < 10; ++j) + ; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -4761,6 +7007,25 @@ void foo() { } #pragma omp parallel sections { +#pragma omp target parallel + ++a; + } +#pragma omp parallel sections + { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { +#pragma omp target enter data map(to: a) + } +#pragma omp parallel sections + { +#pragma omp target exit data map(from: a) + } +#pragma omp parallel sections + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -4776,6 +7041,28 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp parallel sections + { +#pragma omp target update to(a) + } +#pragma omp parallel sections + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // TASK DIRECTIVE #pragma omp task @@ -4864,6 +7151,25 @@ void foo() { } #pragma omp task { +#pragma omp target parallel + ++a; + } +#pragma omp task +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp task + { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp task + { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp task + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -4879,6 +7185,29 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp task + { +#pragma omp target update to(a) + a++; + } +#pragma omp task + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp task + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp task + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // ATOMIC DIRECTIVE #pragma omp atomic @@ -5045,6 +7374,35 @@ void foo() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { #pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}} ++a; } @@ -5064,6 +7422,36 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp distribute parallel for// expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } // TARGET DIRECTIVE #pragma omp target @@ -5155,10 +7543,27 @@ void foo() { } #pragma omp target { +#pragma omp target // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } #pragma omp target + { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} ++a; } #pragma omp target +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target + { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}} + } +#pragma omp target + { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} + } +#pragma omp target { #pragma omp teams ++a; @@ -5181,6 +7586,398 @@ void foo() { for (int i = 0; i < 10; ++i) ; } +#pragma omp atomic + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + a++; + } +#pragma omp target + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// TARGET PARALLEL DIRECTIVE +#pragma omp target parallel +#pragma omp parallel + bar(); +#pragma omp target parallel +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp sections + { + bar(); + } +#pragma omp target parallel +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel region}} + { + bar(); + } +#pragma omp target parallel +#pragma omp single + bar(); + +#pragma omp target parallel +#pragma omp master + { + bar(); + } +#pragma omp target parallel +#pragma omp critical + { + bar(); + } +#pragma omp target parallel +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel +#pragma omp parallel sections + { + bar(); + } +#pragma omp target parallel +#pragma omp task + { + bar(); + } +#pragma omp target parallel + { +#pragma omp taskyield + bar(); + } +#pragma omp target parallel + { +#pragma omp barrier + bar(); + } +#pragma omp target parallel + { +#pragma omp taskwait + bar(); + } +#pragma omp target parallel + { +#pragma omp flush + bar(); + } +#pragma omp target parallel + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target parallel + { +#pragma omp atomic + ++a; + } +#pragma omp target parallel + { +#pragma omp target // expected-error {{region cannot be nested inside 'target parallel' region}} + ++a; + } +#pragma omp target parallel + { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel' region}} + ++a; + } +#pragma omp target parallel +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel' region}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target parallel + { + ++a; +#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target parallel + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target parallel + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel + { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel' region}} + } +#pragma omp target parallel + { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}} + } +#pragma omp target parallel + { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel' region}} + } +#pragma omp target parallel + { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel + { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel + { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// TARGET PARALLEL FOR DIRECTIVE +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel for region}} + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + { + bar(); + } + } + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{region cannot be closely nested inside 'target parallel for' region}} + { + bar(); + } + } + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp critical + { + bar(); + } + } + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + { +#pragma omp single // OK + { + bar(); + } +#pragma omp for // OK + for (int i = 0; i < 10; ++i) + ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; +#pragma omp sections // OK + { + bar(); + } + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp task + { + bar(); + } + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target parallel for' region}} + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp flush + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target parallel for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel for' region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel for' region}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel for' region}} + a++; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // TEAMS DIRECTIVE #pragma omp target @@ -5298,6 +8095,27 @@ void foo() { #pragma omp target #pragma omp teams { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams + { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target enter data' directive into a parallel region?}} + } +#pragma omp target +#pragma omp teams + { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}} + } +#pragma omp target +#pragma omp teams + { #pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -5321,6 +8139,47 @@ void foo() { #pragma omp distribute for (int j = 0; j < 10; ++j) ; +#pragma omp target +#pragma omp teams + { +#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams + { +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute parallel for + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target +#pragma omp teams + { +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute parallel for simd + for (int j = 0; j < 10; ++j) + ; + } +#pragma omp target +#pragma omp teams + { +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute simd + for (int j = 0; j < 10; ++j) + ; + } // TASKLOOP DIRECTIVE #pragma omp taskloop @@ -5463,6 +8322,27 @@ void foo() { } #pragma omp taskloop for (int i = 0; i < 10; ++i) { +#pragma omp target parallel + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } @@ -5472,6 +8352,35 @@ void foo() { for (int i = 0; i < 10; ++i) ++a; } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) + ++a; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // DISTRIBUTE DIRECTIVE #pragma omp target @@ -5651,16 +8560,786 @@ void foo() { #pragma omp teams #pragma omp distribute for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } #pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} ++a; } #pragma omp target #pragma omp teams #pragma omp distribute for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { #pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} ++a; } return foo<int>(); -} +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ++a; + } + + // DISTRIBUTE PARALLEL FOR DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a distribute parallel for region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp critical + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + { +#pragma omp single + { + bar(); + } + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp task + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp flush + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + return foo<int>(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ++a; + } +// DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { +#pragma omp single + { + bar(); + } + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } + return foo<int>(); +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } + +// DISTRIBUTE SIMD DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { +#pragma omp single + { + bar(); + } + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } + return foo<int>(); +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp target +#pragma omp teams +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) { +#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +} diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp new file mode 100644 index 0000000000000..c4df636367d3b --- /dev/null +++ b/test/OpenMP/nvptx_target_codegen.cpp @@ -0,0 +1,581 @@ +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +// CHECK-DAG: [[OMP_NT:@.+]] = common addrspace(3) global i32 0 +// CHECK-DAG: [[OMP_WID:@.+]] = common addrspace(3) global i64 0 + +template<typename tx, typename ty> +struct TT{ + tx X; + ty Y; +}; + +int foo(int n) { + int a = 0; + short aa = 0; + float b[10]; + float bn[n]; + double c[5][10]; + double cn[5][n]; + TT<long long, char> d; + + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l86}}_worker() + // CHECK: br label {{%?}}[[AWAIT_WORK:.+]] + // + // CHECK: [[AWAIT_WORK]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]], + // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0 + // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]] + // + // CHECK: [[SEL_WORKERS]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]] + // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]] + // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]] + // + // CHECK: [[EXEC_PARALLEL]] + // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] + // + // CHECK: [[TERM_PARALLEL]] + // CHECK: br label {{%?}}[[BAR_PARALLEL]] + // + // CHECK: [[BAR_PARALLEL]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[AWAIT_WORK]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l86]]() + // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() + // CHECK: [[A:%.+]] = sub i32 [[WS]], 1 + // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1 + // CHECK: [[MID:%.+]] = and i32 [[B]], + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]] + // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]] + // + // CHECK: [[CHECK_WORKER]] + // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]] + // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]] + // + // CHECK: [[WORKER]] + // CHECK: call void [[T1]]_worker() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[MASTER]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]]) + // CHECK: br label {{%?}}[[TERM:.+]] + // + // CHECK: [[TERM]] + // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]], + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + #pragma omp target + { + } + + // CHECK-NOT: define {{.*}}void [[T2:@__omp_offloading_.+foo.+]]_worker() + #pragma omp target if(0) + { + } + + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l157}}_worker() + // CHECK: br label {{%?}}[[AWAIT_WORK:.+]] + // + // CHECK: [[AWAIT_WORK]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]], + // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0 + // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]] + // + // CHECK: [[SEL_WORKERS]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]] + // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]] + // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]] + // + // CHECK: [[EXEC_PARALLEL]] + // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] + // + // CHECK: [[TERM_PARALLEL]] + // CHECK: br label {{%?}}[[BAR_PARALLEL]] + // + // CHECK: [[BAR_PARALLEL]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[AWAIT_WORK]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l157]](i[[SZ:32|64]] [[ARG1:%.+]]) + // CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], + // CHECK: store i[[SZ]] [[ARG1]], i[[SZ]]* [[AA_ADDR]], + // CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16* + // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() + // CHECK: [[A:%.+]] = sub i32 [[WS]], 1 + // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1 + // CHECK: [[MID:%.+]] = and i32 [[B]], + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]] + // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]] + // + // CHECK: [[CHECK_WORKER]] + // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]] + // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]] + // + // CHECK: [[WORKER]] + // CHECK: call void [[T3]]_worker() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[MASTER]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]]) + // CHECK: load i16, i16* [[AA_CADDR]], + // CHECK: br label {{%?}}[[TERM:.+]] + // + // CHECK: [[TERM]] + // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]], + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + #pragma omp target if(1) + { + aa += 1; + } + + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l260}}_worker() + // CHECK: br label {{%?}}[[AWAIT_WORK:.+]] + // + // CHECK: [[AWAIT_WORK]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]], + // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0 + // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]] + // + // CHECK: [[SEL_WORKERS]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]] + // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]] + // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]] + // + // CHECK: [[EXEC_PARALLEL]] + // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] + // + // CHECK: [[TERM_PARALLEL]] + // CHECK: br label {{%?}}[[BAR_PARALLEL]] + // + // CHECK: [[BAR_PARALLEL]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[AWAIT_WORK]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+foo.+l260]](i[[SZ]] + // Create local storage for each capture. + // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]* + // CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_BN:%.+]] = alloca float* + // CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]* + // CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_CN:%.+]] = alloca double* + // CHECK: [[LOCAL_D:%.+]] = alloca [[TT:%.+]]* + // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]] + // CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]] + // CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]] + // CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]] + // CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]] + // CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]] + // CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]] + // CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]] + // CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]] + // + // CHECK-64-DAG: [[REF_A:%.+]] = bitcast i64* [[LOCAL_A]] to i32* + // CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]], + // CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]], + // CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]], + // CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]], + // CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]], + // CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]], + // CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]], + // CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]], + // + // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() + // CHECK: [[A:%.+]] = sub i32 [[WS]], 1 + // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1 + // CHECK: [[MID:%.+]] = and i32 [[B]], + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]] + // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]] + // + // CHECK: [[CHECK_WORKER]] + // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]] + // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]] + // + // CHECK: [[WORKER]] + // CHECK: call void [[T4]]_worker() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[MASTER]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]]) + // + // Use captures. + // CHECK-64-DAG: load i32, i32* [[REF_A]] + // CHECK-32-DAG: load i32, i32* [[LOCAL_A]] + // CHECK-DAG: getelementptr inbounds [10 x float], [10 x float]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2 + // CHECK-DAG: getelementptr inbounds float, float* [[REF_BN]], i[[SZ]] 3 + // CHECK-DAG: getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] 0, i[[SZ]] 1 + // CHECK-DAG: getelementptr inbounds double, double* [[REF_CN]], i[[SZ]] %{{.+}} + // CHECK-DAG: getelementptr inbounds [[TT]], [[TT]]* [[REF_D]], i32 0, i32 0 + // + // CHECK: br label {{%?}}[[TERM:.+]] + // + // CHECK: [[TERM]] + // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]], + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + #pragma omp target if(n>20) + { + a += 1; + b[2] += 1.0; + bn[3] += 1.0; + c[1][2] += 1.0; + cn[1][3] += 1.0; + d.X += 1; + d.Y += 1; + } + + return a; +} + +template<typename tx> +tx ftemplate(int n) { + tx a = 0; + short aa = 0; + tx b[10]; + + #pragma omp target if(n>40) + { + a += 1; + aa += 1; + b[2] += 1; + } + + return a; +} + +static +int fstatic(int n) { + int a = 0; + short aa = 0; + char aaa = 0; + int b[10]; + + #pragma omp target if(n>50) + { + a += 1; + aa += 1; + aaa += 1; + b[2] += 1; + } + + return a; +} + +struct S1 { + double a; + + int r1(int n){ + int b = n+1; + short int c[2][n]; + + #pragma omp target if(n>60) + { + this->a = (double)b + 1.5; + c[1][1] = ++a; + } + + return c[1][1] + (int)b; + } +}; + +int bar(int n){ + int a = 0; + + a += foo(n); + + S1 S; + a += S.r1(n); + + a += fstatic(n); + + a += ftemplate<int>(n); + + return a; +} + + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+l297}}_worker() + // CHECK: br label {{%?}}[[AWAIT_WORK:.+]] + // + // CHECK: [[AWAIT_WORK]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]], + // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0 + // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]] + // + // CHECK: [[SEL_WORKERS]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]] + // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]] + // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]] + // + // CHECK: [[EXEC_PARALLEL]] + // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] + // + // CHECK: [[TERM_PARALLEL]] + // CHECK: br label {{%?}}[[BAR_PARALLEL]] + // + // CHECK: [[BAR_PARALLEL]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[AWAIT_WORK]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+static.+l297]](i[[SZ]] + // Create local storage for each capture. + // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]* + // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]] + // CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]] + // CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]] + // CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]] + // Store captures in the context. + // CHECK-64-DAG: [[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32* + // CHECK-DAG: [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16* + // CHECK-DAG: [[REF_AAA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8* + // CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]], + // + // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() + // CHECK: [[A:%.+]] = sub i32 [[WS]], 1 + // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1 + // CHECK: [[MID:%.+]] = and i32 [[B]], + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]] + // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]] + // + // CHECK: [[CHECK_WORKER]] + // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]] + // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]] + // + // CHECK: [[WORKER]] + // CHECK: call void [[T5]]_worker() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[MASTER]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]]) + // + // CHECK-64-DAG: load i32, i32* [[REF_A]] + // CHECK-32-DAG: load i32, i32* [[LOCAL_A]] + // CHECK-DAG: load i16, i16* [[REF_AA]] + // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2 + // + // CHECK: br label {{%?}}[[TERM:.+]] + // + // CHECK: [[TERM]] + // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]], + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + + + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l315}}_worker() + // CHECK: br label {{%?}}[[AWAIT_WORK:.+]] + // + // CHECK: [[AWAIT_WORK]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]], + // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0 + // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]] + // + // CHECK: [[SEL_WORKERS]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]] + // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]] + // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]] + // + // CHECK: [[EXEC_PARALLEL]] + // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] + // + // CHECK: [[TERM_PARALLEL]] + // CHECK: br label {{%?}}[[BAR_PARALLEL]] + // + // CHECK: [[BAR_PARALLEL]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[AWAIT_WORK]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+S1.+l315]]( + // Create local storage for each capture. + // CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1:%struct.*]]* + // CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_C:%.+]] = alloca i16* + // CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]] + // CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]] + // CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]] + // CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]] + // CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]] + // Store captures in the context. + // CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]], + // CHECK-64-DAG:[[REF_B:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32* + // CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]], + // CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]], + // CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]], + // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() + // CHECK: [[A:%.+]] = sub i32 [[WS]], 1 + // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1 + // CHECK: [[MID:%.+]] = and i32 [[B]], + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]] + // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]] + // + // CHECK: [[CHECK_WORKER]] + // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]] + // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]] + // + // CHECK: [[WORKER]] + // CHECK: call void [[T6]]_worker() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[MASTER]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]]) + // Use captures. + // CHECK-DAG: getelementptr inbounds [[S1]], [[S1]]* [[REF_THIS]], i32 0, i32 0 + // CHECK-64-DAG:load i32, i32* [[REF_B]] + // CHECK-32-DAG:load i32, i32* [[LOCAL_B]] + // CHECK-DAG: getelementptr inbounds i16, i16* [[REF_C]], i[[SZ]] %{{.+}} + // CHECK: br label {{%?}}[[TERM:.+]] + // + // CHECK: [[TERM]] + // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]], + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + + + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l280}}_worker() + // CHECK: br label {{%?}}[[AWAIT_WORK:.+]] + // + // CHECK: [[AWAIT_WORK]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]], + // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0 + // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]] + // + // CHECK: [[SEL_WORKERS]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]] + // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]] + // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]] + // + // CHECK: [[EXEC_PARALLEL]] + // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]] + // + // CHECK: [[TERM_PARALLEL]] + // CHECK: br label {{%?}}[[BAR_PARALLEL]] + // + // CHECK: [[BAR_PARALLEL]] + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[AWAIT_WORK]] + // + // CHECK: [[EXIT]] + // CHECK: ret void + + // CHECK: define {{.*}}void [[T7:@__omp_offloading_.+template.+l280]](i[[SZ]] + // Create local storage for each capture. + // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]] + // CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]* + // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]] + // CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]] + // CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]] + // Store captures in the context. + // CHECK-64-DAG:[[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32* + // CHECK-DAG: [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16* + // CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]], + // + // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() + // CHECK: [[A:%.+]] = sub i32 [[WS]], 1 + // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1 + // CHECK: [[MID:%.+]] = and i32 [[B]], + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]] + // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]] + // + // CHECK: [[CHECK_WORKER]] + // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]] + // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]] + // + // CHECK: [[WORKER]] + // CHECK: call void [[T7]]_worker() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[MASTER]] + // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() + // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]]) + // + // CHECK-64-DAG: load i32, i32* [[REF_A]] + // CHECK-32-DAG: load i32, i32* [[LOCAL_A]] + // CHECK-DAG: load i16, i16* [[REF_AA]] + // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2 + // + // CHECK: br label {{%?}}[[TERM:.+]] + // + // CHECK: [[TERM]] + // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]], + // CHECK: call void @llvm.nvvm.barrier0() + // CHECK: br label {{%?}}[[EXIT]] + // + // CHECK: [[EXIT]] + // CHECK: ret void +#endif diff --git a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp new file mode 100644 index 0000000000000..5dcff8e548426 --- /dev/null +++ b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp @@ -0,0 +1,223 @@ + +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +template<typename tx, typename ty> +struct TT{ + tx X; + ty Y; +}; + +// TCHECK: [[TT:%.+]] = type { i64, i8 } +// TCHECK: [[S1:%.+]] = type { double } + +int foo(int n, double *ptr) { + int a = 0; + short aa = 0; + float b[10]; + double c[5][10]; + TT<long long, char> d; + + #pragma omp target firstprivate(a) + { + } + + // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]]) + // TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK-NOT: alloca i{{[0-9]+}}, + // TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]], + // TCHECK: ret void + +#pragma omp target firstprivate(aa,b,c,d) + { + aa += 1; + b[2] = 1.0; + c[1][2] = 1.0; + d.X = 1; + d.Y = 1; + } + + // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the + // target region + // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]]) + // TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*, + // TCHECK: [[C_ADDR:%.+]] = alloca [5 x [10 x double]]*, + // TCHECK: [[D_ADDR:%.+]] = alloca [[TT]]*, + // TCHECK-NOT: alloca i{{[0-9]+}}, + // TCHECK: [[B_PRIV:%.+]] = alloca [10 x float], + // TCHECK: [[C_PRIV:%.+]] = alloca [5 x [10 x double]], + // TCHECK: [[D_PRIV:%.+]] = alloca [[TT]], + // TCHECK: store i{{[0-9]+}} [[A2_IN]], i{{[0-9]+}}* [[A2_ADDR]], + // TCHECK: store [10 x float]* [[B_IN]], [10 x float]** [[B_ADDR]], + // TCHECK: store [5 x [10 x double]]* [[C_IN]], [5 x [10 x double]]** [[C_ADDR]], + // TCHECK: store [[TT]]* [[D_IN]], [[TT]]** [[D_ADDR]], + // TCHECK: [[CONV_A2ADDR:%.+]] = bitcast i{{[0-9]+}}* [[A2_ADDR]] to i{{[0-9]+}}* + // TCHECK: [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** [[B_ADDR]], + // TCHECK: [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[C_ADDR]], + // TCHECK: [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** [[D_ADDR]], + + // firstprivate(aa): a_priv = a_in + + // firstprivate(b): memcpy(b_priv,b_in) + // TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x float]* [[B_PRIV]] to i8* + // TCHECK: [[B_ADDR_REF_BCAST:%.+]] = bitcast [10 x float]* [[B_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_ADDR_REF_BCAST]], {{.+}}) + + // firstprivate(c) + // TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8* + // TCHECK: [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}}) + + // firstprivate(d) + // TCHECK: [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8* + // TCHECK: [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[D_PRIV_BCAST]], i8* [[D_IN_BCAST]],{{.+}}) + + // TCHECK: load i16, i16* [[CONV_A2ADDR]], + + + #pragma omp target firstprivate(ptr) + { + ptr[0]++; + } + + // TCHECK: define void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]]) + // TCHECK: [[PTR_ADDR:%.+]] = alloca double*, + // TCHECK-NOT: alloca double*, + // TCHECK: store double* [[PTR_IN]], double** [[PTR_ADDR]], + // TCHECK: [[PTR_IN_REF:%.+]] = load double*, double** [[PTR_ADDR]], + // TCHECK-NOT: store double* [[PTR_IN_REF]], double** [[PTR_PRIV]], + + return a; +} + + +template<typename tx> +tx ftemplate(int n) { + tx a = 0; + tx b[10]; + +#pragma omp target firstprivate(a,b) + { + a += 1; + b[2] += 1; + } + + return a; +} + +static +int fstatic(int n) { + int a = 0; + char aaa = 0; + int b[10]; + +#pragma omp target firstprivate(a,aaa,b) + { + a += 1; + aaa += 1; + b[2] += 1; + } + + return a; +} + +// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]]) +// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[A3_ADDR:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*, +// TCHECK-NOT: alloca i{{[0-9]+}}, +// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}], +// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]], +// TCHECK: store i{{[0-9]+}} [[A3_IN]], i{{[0-9]+}}* [[A3_ADDR]], +// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]], +// TCHECK-64: [[A_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}* +// TCHECK: [[A3_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A3_ADDR]] to i8* +// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]], + +// firstprivate(a): a_priv = a_in + +// firstprivate(aaa) + +// TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* + +// firstprivate(b) +// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8* +// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8* +// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}}) + +// TCHECK: ret void + +struct S1 { + double a; + + int r1(int n){ + int b = n+1; + +#pragma omp target firstprivate(b) + { + this->a = (double)b + 1.5; + } + + return (int)b; + } + + // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]]) + // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*, + // TCHECK: [[B_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK-NOT: alloca i{{[0-9]+}}, + + // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]], + // TCHECK: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[B_ADDR]], + // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]], + // TCHECK-64: [[B_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[B_ADDR]] to i{{[0-9]+}}* + + // firstprivate(b) + // TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* + + // TCHECK: ret void +}; + + + +int bar(int n, double *ptr){ + int a = 0; + a += foo(n, ptr); + S1 S; + a += S.r1(n); + a += fstatic(n); + a += ftemplate<int>(n); + + return a; +} + +// template + +// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]]) +// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*, +// TCHECK-NOT: alloca i{{[0-9]+}}, +// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}], +// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]], +// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]], +// TCHECK-64: [[A_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}* +// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]], + +// firstprivate(a) +// TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* + +// firstprivate(b) +// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8* +// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8* +// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}}) + +// TCHECK: ret void + +#endif diff --git a/test/OpenMP/nvptx_teams_codegen.cpp b/test/OpenMP/nvptx_teams_codegen.cpp new file mode 100644 index 0000000000000..b26d47c706aca --- /dev/null +++ b/test/OpenMP/nvptx_teams_codegen.cpp @@ -0,0 +1,132 @@ +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +#ifdef CK1 + +template <typename T> +int tmain(T argc) { +#pragma omp target +#pragma omp teams + argc = 0; + return 0; +} + + +int main (int argc, char **argv) { +#pragma omp target +#pragma omp teams + { + argc = 0; + } + return tmain(argv); +} + +// only nvptx side: do not outline teams region and do not call fork_teams +// CK1: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[ARGC:%.+]]) +// CK1: {{.+}} = alloca i{{[0-9]+}}*, +// CK1: {{.+}} = alloca i{{[0-9]+}}*, +// CK1: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}*, +// CK1: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}}, +// CK1: store {{.+}} 0, {{.+}}, +// CK1: store i{{[0-9]+}} [[ARGC]], i{{[0-9]+}}* [[ARGCADDR]], +// CK1-64: [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ARGCADDR]] to i{{[0-9]+}}* +// CK1-64: store i{{[0-9]+}}* [[CONV]], i{{[0-9]+}}** [[ARGCADDR_PTR]], +// CK1-32: store i{{[0-9]+}}* [[ARGCADDR]], i{{[0-9]+}}** [[ARGCADDR_PTR]], +// CK1: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARGCADDR_PTR]], +// CK1: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[ARGCADDR_PTR_REF]], +// CK1-NOT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams( +// CK1: ret void +// CK1-NEXT: } + +// target region in template +// CK1: define {{.*}}void @{{[^,]+}}(i{{.+}}** [[ARGC:%.+]]) +// CK1: [[ARGCADDR_PTR:%.+]] = alloca i{{.+}}***, +// CK1: [[ARGCADDR:%.+]] = alloca i{{.+}}**, +// CK1: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]] +// CK1: store i8*** [[ARGCADDR]], i8**** [[ARGCADDR_PTR]], +// CK1: [[ARGCADDR_PTR_REF:%.+]] = load i{{.+}}**, i{{.+}}*** [[ARGCADDR_PTR]], +// CK1: store i{{[0-9]+}}** null, i{{[0-9]+}}*** [[ARGCADDR_PTR_REF]], +// CK1-NOT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams( +// CK1: ret void +// CK1-NEXT: } + + +#endif // CK1 + +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// expected-no-diagnostics +#ifdef CK2 + +template <typename T> +int tmain(T argc) { + int a = 10; + int b = 5; +#pragma omp target +#pragma omp teams num_teams(a) thread_limit(b) + { + argc = 0; + } + return 0; +} + +int main (int argc, char **argv) { + int a = 20; + int b = 5; +#pragma omp target +#pragma omp teams num_teams(a) thread_limit(b) + { + argc = 0; + } + return tmain(argv); +} + +// CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[ARGC_IN:.+]]) +// CK2: {{.}} = alloca i{{[0-9]+}}*, +// CK2: {{.}} = alloca i{{[0-9]+}}*, +// CK2: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}*, +// CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}}, +// CK2: [[BADDR:%.+]] = alloca i{{[0-9]+}}, +// CK2: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}}, +// CK2-NOT: {{%.+}} = call i32 @__kmpc_global_thread_num( +// CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]], +// CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]], +// CK2: store i{{[0-9]+}} [[ARGC_IN]], i{{[0-9]+}}* [[ARGCADDR]], +// CK2-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32* +// CK2-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32* +// CK2-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32* +// CK2-64: store i{{[0-9]+}}* [[CONV]], i{{[0-9]+}}** [[ARGCADDR_PTR]], +// CK2-32: store i{{[0-9]+}}* [[ARGCADDR]], i{{[0-9]+}}** [[ARGCADDR_PTR]], +// CK2: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARGCADDR_PTR]], +// CK2: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[ARGCADDR_PTR_REF]], +// CK2-NOT: {{.+}} = call i32 @__kmpc_push_num_teams( +// CK2-NOT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams( +// CK2: ret + +// CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[BP:%.+]], i{{[0-9]+}}** [[ARGC:%.+]]) +// CK2: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}***, +// CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}}, +// CK2: [[BADDR:%.+]] = alloca i{{[0-9]+}}, +// CK2: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}}**, +// CK2-NOT: {{%.+}} = call i32 @__kmpc_global_thread_num( +// CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]], +// CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]], +// CK2: store i{{[0-9]+}}** [[ARGC]], i{{[0-9]+}}*** [[ARGCADDR]], +// CK2: store i{{[0-9]+}}*** [[ARGCADDR]], i{{[0-9]+}}**** [[ARGCADDR_PTR]], +// CK2: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}***, i{{[0-9]+}}**** [[ARGCADDR_PTR]], +// CK2: store i{{[0-9]+}}** null, i{{[0-9]+}}*** [[ARGCADDR_PTR_REF]], +// CK2-NOT: {{.+}} = call i32 @__kmpc_push_num_teams( +// CK2-NOT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams( +// CK2: ret void + +#endif // CK2 +#endif diff --git a/test/OpenMP/ordered_doacross_codegen.cpp b/test/OpenMP/ordered_doacross_codegen.cpp new file mode 100644 index 0000000000000..d1fe99d4b826b --- /dev/null +++ b/test/OpenMP/ordered_doacross_codegen.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// 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 +// REQUIRES: x86-registered-target +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK: [[KMP_DIM:%.+]] = type { i64, i64, i64 } +extern int n; +int a[10], b[10], c[10], d[10]; +void foo(); + +// CHECK-LABEL: @main() +int main() { + int i; +// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]]) +// CHECK: icmp +// CHECK-NEXT: br i1 % +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* [[CAST]], i8 0, i64 24, i32 8, i1 false) +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1 +// CHECK: store i64 %{{.+}}, i64* % +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2 +// CHECK: store i64 1, i64* % +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* +// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]]) +// CHECK: call void @__kmpc_for_static_init_4( +#pragma omp for ordered(1) + for (i = 0; i < n; ++i) { + a[i] = b[i] + 1; + foo(); +// CHECK: invoke void [[FOO:.+]]( +// CHECK: load i32, i32* [[CNT:%.+]], +// CHECK-NEXT: sext i32 %{{.+}} to i64 +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], +// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]]) +#pragma omp ordered depend(source) + c[i] = c[i] + 1; + foo(); +// CHECK: invoke void [[FOO]] +// CHECK: load i32, i32* [[CNT]], +// CHECK-NEXT: sub nsw i32 %{{.+}}, 2 +// CHECK-NEXT: sext i32 %{{.+}} to i64 +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], +// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]]) +#pragma omp ordered depend(sink : i - 2) + d[i] = a[i - 2]; + } + // CHECK: landingpad + // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: br label % + + // CHECK: call void @__kmpc_for_static_fini( + // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: ret i32 0 + return 0; +} + +// CHECK: define {{.+}}TestStruct +template <typename T> +struct TestStruct { + static const int M = 10; + static const int N = 20; + T i; + T a[N][M]; + T b[N][M]; + T foo(T, T); + T bar(T, T, T); + void baz(T, T); + TestStruct() { +// CHECK: [[CNT:%.+]] = alloca i64, +// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]]) +// CHECK: icmp +// CHECK-NEXT: br i1 % +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* [[CAST]], i8 0, i64 24, i32 8, i1 false) +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1 +// CHECK: store i64 %{{.+}}, i64* % +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2 +// CHECK: store i64 1, i64* % +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* +// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]]) +// CHECK: call void @__kmpc_for_static_init_8( +#pragma omp for ordered(2) + for (T j = 0; j < M; j++) + for (i = 0; i < n; i += 2) { + a[i][j] = foo(i, j); +// CHECK: invoke {{.+TestStruct.+foo}} +// CHECK: load i64, i64* [[CNT]], +// CHECK-NEXT: sub nsw i64 %{{.+}}, 1 +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], +// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]]) +// CHECK-NEXT: load i64, i64* [[CNT]], +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: mul nsw i32 1, % +// CHECK-NEXT: sext i32 %{{.+}} to i64 +// CHECK-NEXT: sub nsw i64 % +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], +// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]]) +#pragma omp ordered depend(sink : j, i - 2) depend(sink : j - 1, i) + b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]); +// CHECK: invoke {{.+TestStruct.+bar}} +// CHECK: load i64, i64* [[CNT]], +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], +// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]]) +#pragma omp ordered depend(source) + baz(a[i][j], b[i][j]); + } + } + // CHECK: landingpad + // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: br label % + + // CHECK: call void @__kmpc_for_static_fini( + // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: ret +}; + +TestStruct<int> s; +#endif // HEADER diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp index 1e46fba48ca31..8a1533959e364 100644 --- a/test/OpenMP/parallel_ast_print.cpp +++ b/test/OpenMP/parallel_ast_print.cpp @@ -8,6 +8,113 @@ void foo() {} +struct S1 { + S1(): a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; + S1& operator +(const S1&); + S1& operator *(const S1&); + S1& operator &&(const S1&); + S1& operator ^(const S1&); +}; + +template <typename T> +class S7 : public T { +protected: + T a; + T b[100]; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp parallel private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel shared(a) shared(this->a) shared(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel reduction(+ : a) reduction(*: b[:]) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp parallel firstprivate(a) firstprivate(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp parallel shared(a) shared(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp parallel reduction(&& : this->a) reduction(^: b[s.a.a]) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S1::a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S1::a) +// CHECK: #pragma omp parallel reduction(+: this->a) reduction(*: this->b[:]) +// CHECK: #pragma omp parallel private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(T::a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(T::a) +// CHECK: #pragma omp parallel reduction(+: this->a) reduction(*: this->b[:]) +// CHECK: #pragma omp parallel private(this->a) private(this->a) +// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) +// CHECK: #pragma omp parallel reduction(&&: this->a) reduction(^: this->b[s.a.a]) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp parallel private(a) private(this->a) private(S7 < S1 > ::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(S7 < S1 > ::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel shared(a) shared(this->a) shared(S7 < S1 > ::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; +#pragma omp parallel reduction(^ : S7 < S1 > ::a) reduction(+ : S7 < S1 > ::b[ : S7 < S1 > ::a.a]) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp parallel private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp parallel firstprivate(a) firstprivate(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp parallel shared(a) shared(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; +#pragma omp parallel reduction(* : this->a) reduction(&&:this->b[a.a:]) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S7<S1>::a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S7<S1>::a) +// CHECK: #pragma omp parallel reduction(^: this->S7<S1>::a) reduction(+: this->S7<S1>::b[:this->S7<S1>::a.a]) +// CHECK: #pragma omp parallel private(this->a) private(this->a) +// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) +// CHECK: #pragma omp parallel shared(this->a) shared(this->a) +// CHECK: #pragma omp parallel reduction(*: this->a) reduction(&&: this->b[this->a.a:]) + template <class T> struct S { operator T() {return T();} @@ -120,4 +227,7 @@ void foo(const Foo<int> &arg) { } } +template<typename T> +T S<T>::TS = 0; + #endif diff --git a/test/OpenMP/parallel_copyin_codegen.cpp b/test/OpenMP/parallel_copyin_codegen.cpp index ff76cfe4dd6c8..49e7b3fd618ba 100644 --- a/test/OpenMP/parallel_copyin_codegen.cpp +++ b/test/OpenMP/parallel_copyin_codegen.cpp @@ -87,10 +87,6 @@ int main() { // TLS-LAMBDA: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]() // TLS-LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]]) - // TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() - // TLS-LAMBDA: ret i{{[0-9]+}}* [[G]] - // TLS-LAMBDA: } - #pragma omp parallel copyin(g) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) @@ -122,6 +118,11 @@ int main() { g = 1; // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* // TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* + + // TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() + // TLS-LAMBDA: ret i{{[0-9]+}}* [[G]] + // TLS-LAMBDA: } + [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -149,9 +150,6 @@ int main() { // TLS-BLOCKS: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]() // TLS-BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]]) - // TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() - // TLS-BLOCKS: ret i{{[0-9]+}}* [[G]] - // TLS-BLOCKS: } #pragma omp parallel copyin(g) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) @@ -189,6 +187,10 @@ int main() { // TLS-BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_CAPTURE_DST]] // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} // TLS-BLOCKS: call {{.*}}void {{%.+}}(i8 + + // TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS: ret i{{[0-9]+}}* [[G]] + // TLS-BLOCKS: } ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* // TLS-BLOCKS: define {{.+}} void {{@.+}}(i8* diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp index d0da8cea87ac0..d20f3f5135691 100644 --- a/test/OpenMP/parallel_firstprivate_codegen.cpp +++ b/test/OpenMP/parallel_firstprivate_codegen.cpp @@ -1,8 +1,15 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s -// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-32 %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-32 %s + +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-64 %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-64 %s + // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s // expected-no-diagnostics #ifndef ARRAY @@ -18,6 +25,60 @@ struct St { volatile int g __attribute__((aligned(128))) = 1212; +struct SS { + int a; + int b : 4; + int &c; + int e[4]; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel firstprivate(a, b, c, e) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel firstprivate(a, b, c) + ++(this)->a, --b, this->c /= 1; + }(); +#elif defined(BLOCKS) + ^{ + ++a; + --this->b; + (this)->c /= 1; +#pragma omp parallel firstprivate(a, b, c) + ++(this)->a, --b, this->c /= 1; + }(); +#else + ++this->a, --b, c /= 1, e[2] = 1111; +#endif + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp parallel firstprivate(a) +#ifdef LAMBDA + [&]() { + [&]() { + ++this->a; +#pragma omp parallel firstprivate(a) + ++(this)->a; + }(); + }(); +#elif defined(BLOCKS) + ^{ + ^{ + ++a; +#pragma omp parallel firstprivate(a) + ++(this)->a; + }(); + }(); +#else + ++(this)->a; +#endif + } +}; + template <class T> struct S { T f; @@ -28,14 +89,17 @@ struct S { ~S() {} }; +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } // CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } -// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* template <typename T> T tmain() { S<T> test; + SST<T> sst; T t_var __attribute__((aligned(128))) = T(); T vec[] __attribute__((aligned(128))) = {1, 2}; S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; @@ -52,33 +116,79 @@ T tmain() { int main() { static int sivar; + SS ss(sivar); #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main - // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: alloca [[SS_TY]], + // LAMBDA: alloca [[CAP_TY:%.+]], + // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]* [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}}) #pragma omp parallel firstprivate(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) - // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 + // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 + // LAMBDA: store i8 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz:i64|i32]], {{i64|i32}}, {{i64|i32}}, [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void + // LAMBDA: ret + + // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}}) + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % + // LAMBDA: call{{.*}} void + // LAMBDA: ret void + + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}) + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32* + // LAMBDA-64: store i32* [[A_CONV]], i32** [[REFA:%.+]], + // LAMBDA-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]], + // LAMBDA-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32* + // LAMBDA-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32* + // LAMBDA-64: store i32* [[C_CONV]], i32** [[REFC:%.+]], + // LAMBDA-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]], + // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], + // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]], + // LAMBDA-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 + // LAMBDA-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]], + // LAMBDA-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], + // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: ret void + + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}%{{.+}}) // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] - // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR:%.+]] + // LAMBDA-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32* // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128 // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 - // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] - // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] - // LAMBDA: call {{.*}}void @__kmpc_barrier( + // LAMBDA-NOT: call {{.*}}void @__kmpc_barrier( g = 1; sivar = 2; // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], - // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // LAMBDA-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], + // LAMBDA-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 - // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] + // LAMBDA-64: store i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] + // LAMBDA-32: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) @@ -98,33 +208,32 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main + // BLOCKS: call // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}}) #pragma omp parallel firstprivate(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) - // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz:i64|i32]] {{.*}}%{{.+}}) // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] - // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR:%.+]] + // BLOCKS-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32* // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128 // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 - // BLOCK: [[SIVAR_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 - // BLOCK: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]] - // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]], - // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], - // BLOCKS: call {{.*}}void @__kmpc_barrier( + // BLOCKS-NOT: call {{.*}}void @__kmpc_barrier( g = 1; sivar = 2; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], - // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // BLOCKS-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], + // BLOCKS-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} - // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-64: i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]] + // BLOCKS-32: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ @@ -142,6 +251,48 @@ int main() { } }(); return 0; +// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// BLOCKS: store i8 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void +// BLOCKS: ret + +// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}}) +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % +// BLOCKS: call{{.*}} void +// BLOCKS: ret void + +// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}) +// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32* +// BLOCKS-64: store i32* [[A_CONV]], i32** [[REFA:%.+]], +// BLOCKS-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]], +// BLOCKS-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32* +// BLOCKS-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32* +// BLOCKS-64: store i32* [[C_CONV]], i32** [[REFC:%.+]], +// BLOCKS-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]], +// BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]], +// BLOCKS-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// BLOCKS-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]], +// BLOCKS-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: ret void #else S<float> test; int t_var = 0; @@ -162,27 +313,40 @@ int main() { // CHECK: define {{.*}}i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[T_VAR:%.+]] = alloca i32, +// CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]], +// CHECK: [[SIVARCAST:%.+]] = alloca [[iz]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]], +// CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST]] to i32* +// CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]], +// CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST]], +// CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST]], +// CHECK: [[SIVARVAL:%.+]] = load i32, i32* @{{.+}}, +// CHECK-64: [[SIVARCONV:%.+]] = bitcast i64* [[SIVARCAST]] to i32* +// CHECK-64: store i32 [[SIVARVAL]], i32* [[SIVARCONV]], +// CHECK-32: store i32 [[SIVARVAL]], i32* [[SIVARCAST]], +// CHECK: [[SIVARPVT:%.+]] = load [[iz]], [[iz]]* [[SIVARCAST]], +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, [[iz]], [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[MAIN_MICROTASK:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]],{{.*}}[[iz]] [[SIVARPVT]] // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) +// CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [[iz]] {{.*}}%{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}[[SIVAR:%.+]]) // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], -// CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK-64: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_PRIV]] to i32* // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** % // CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % -// CHECK: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, -// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], -// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK-64: [[SIVAR7_CONV:%.+]] = bitcast i64* [[SIVAR7_PRIV]] to i32* // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* // CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], @@ -200,9 +364,8 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// CHECK: [[SIVAR_REF_ADDR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]], -// CHECK: store i{{[0-9]+}} [[SIVAR_REF_ADDR]], i{{[0-9]+}}* [[SIVAR7_PRIV]], -// CHECK: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]], +// CHECK-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_CONV]], +// CHECK-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]], // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* @@ -214,6 +377,55 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // +// CHECK: define {{.+}} @{{.+}}([[SS_TY]]* +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: store i8 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i32]*)* [[SS_MICROTASK:@.+]] to void +// CHECK: ret + +// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}}) +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[E_PRIV:%.+]] = alloca [4 x i{{[0-9]+}}], +// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[A_PRIV]] +// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[B_PRIV]] +// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[C_PRIV]] +// CHECK-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV:%.+]] to i32* +// CHECK-64: store i32* [[A_CONV]], i32** [[REFA:%.+]], +// CHECK-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]], +// CHECK-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV:%.+]] to i32* +// CHECK-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV:%.+]] to i32* +// CHECK-64: store i32* [[C_CONV]], i32** [[REFC:%.+]], +// CHECK-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]], +// CHECK: bitcast [4 x i{{[0-9]+}}]* [[E_PRIV]] to i8* +// CHECK: bitcast [4 x i{{[0-9]+}}]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy +// CHECK: store [4 x i{{[0-9]+}}]* [[E_PRIV]], [4 x i{{[0-9]+}}]** [[REFE:%.+]], +// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// CHECK-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]], +// CHECK-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// CHECK-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]], +// CHECK-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: [[E_PRIV:%.+]] = load [4 x i{{[0-9]+}}]*, [4 x i{{[0-9]+}}]** [[REFE]], +// CHECK-NEXT: [[E_PRIV_2:%.+]] = getelementptr inbounds [4 x i{{[0-9]+}}], [4 x i{{[0-9]+}}]* [[E_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK-NEXT: store i32 1111, i32* [[E_PRIV_2]], +// CHECK-NEXT: ret void + // CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128 @@ -244,9 +456,7 @@ int main() { // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call {{.*}}void @__kmpc_barrier( // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK: ret void @@ -270,13 +480,13 @@ struct St { void array_func(float a[3], St s[2], int n, long double vla1[n]) { double vla2[n][n] __attribute__((aligned(128))); // ARRAY: @__kmpc_fork_call( -// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float**, -// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St**, -// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80**, +// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*, +// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*, +// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float*, // ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*, -// ARRAY-DAG: store float** %{{.+}}, float*** [[PRIV_A]], -// ARRAY-DAG: store %struct.St** %{{.+}}, %struct.St*** [[PRIV_S]], -// ARRAY-DAG: store x86_fp80** %{{.+}}, x86_fp80*** [[PRIV_VLA1]], +// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], +// ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], +// ARRAY-DAG: store float* %{{.+}}, float** [[PRIV_A]], // ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]], // ARRAY: call i8* @llvm.stacksave() // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8 @@ -288,11 +498,11 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // ARRAY-LABEL: St_func // ARRAY: @__kmpc_fork_call( -// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St**, -// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80**, +// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*, +// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*, // ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*, -// ARRAY-DAG: store %struct.St** %{{.+}}, %struct.St*** [[PRIV_S]], -// ARRAY-DAG: store x86_fp80** %{{.+}}, x86_fp80*** [[PRIV_VLA1]], +// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], +// ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], // ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]], // ARRAY: call i8* @llvm.stacksave() // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8 diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp index c4be521455df2..2476ee87605aa 100644 --- a/test/OpenMP/parallel_for_ast_print.cpp +++ b/test/OpenMP/parallel_for_ast_print.cpp @@ -8,6 +8,57 @@ void foo() {} +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp parallel for private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp parallel for private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp parallel for private(this->a) private(this->a) + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, h; diff --git a/test/OpenMP/parallel_for_collapse_messages.cpp b/test/OpenMP/parallel_for_collapse_messages.cpp index 6e5f71ff16727..4461df8cccdba 100644 --- a/test/OpenMP/parallel_for_collapse_messages.cpp +++ b/test/OpenMP/parallel_for_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}} #pragma omp parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}} - #pragma omp parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp parallel for collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4{{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}} diff --git a/test/OpenMP/parallel_for_linear_messages.cpp b/test/OpenMP/parallel_for_linear_messages.cpp index 7272aada92a08..e5f5b61873c89 100644 --- a/test/OpenMP/parallel_for_linear_messages.cpp +++ b/test/OpenMP/parallel_for_linear_messages.cpp @@ -263,7 +263,7 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; - foomain<int, char>(argc, argv); + foomain<int, char>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} return 0; } diff --git a/test/OpenMP/parallel_for_loop_messages.cpp b/test/OpenMP/parallel_for_loop_messages.cpp index 2bb32bdfc1768..7e136e75869cd 100644 --- a/test/OpenMP/parallel_for_loop_messages.cpp +++ b/test/OpenMP/parallel_for_loop_messages.cpp @@ -354,12 +354,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -402,7 +402,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel for for (begin = begin0; begin < end; ++begin) diff --git a/test/OpenMP/parallel_for_ordered_messages.cpp b/test/OpenMP/parallel_for_ordered_messages.cpp index 3729eb9a68a35..055fe1bba4237 100644 --- a/test/OpenMP/parallel_for_ordered_messages.cpp +++ b/test/OpenMP/parallel_for_ordered_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -36,16 +41,23 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here} #pragma omp parallel for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}} -// expected-error@+3 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}} -// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}} -// expected-error@+1 2 {{expression is not an integral constant expression}} +// expected-error@+6 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}} +// expected-error@+5 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +// expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L +// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp parallel for ordered(foobool(argc)), ordered(true), ordered(-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; #pragma omp parallel for ordered(S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; -// expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L +// expected-error@+4 2 {{expression is not an integral constant expression}} +#else +// expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i - ST]; @@ -76,10 +88,17 @@ int main(int argc, char **argv) { #pragma omp parallel for ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} expected-note {{as specified in 'ordered' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}} -#pragma omp parallel for ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} +// expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L +// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp parallel for ordered(foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; -// expected-error@+3 {{expression is not an integral constant expression}} +// expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L +// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}} // expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}} #pragma omp parallel for ordered(foobool(argc)), ordered(true), ordered(-5) @@ -88,7 +107,11 @@ int main(int argc, char **argv) { #pragma omp parallel for ordered(S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; -// expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L +// expected-error@+4 {{expression is not an integral constant expression}} +#else +// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i - 4]; diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp index efc827b0d5e56..cc1b79f4111b0 100644 --- a/test/OpenMP/parallel_for_private_messages.cpp +++ b/test/OpenMP/parallel_for_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -119,6 +167,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp parallel for private // expected-error {{expected '(' after 'private'}} @@ -180,6 +230,8 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) m = k + 2; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp index 22251b446300b..4d5a143bae3a3 100644 --- a/test/OpenMP/parallel_for_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s void foo() { } @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -111,7 +111,7 @@ T tmain(T argc) { #pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(&& : argc) @@ -120,22 +120,22 @@ T tmain(T argc) { #pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -150,7 +150,7 @@ T tmain(T argc) { #pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -160,7 +160,7 @@ T tmain(T argc) { #pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} @@ -251,13 +251,13 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} diff --git a/test/OpenMP/parallel_for_simd_aligned_messages.cpp b/test/OpenMP/parallel_for_simd_aligned_messages.cpp index 8bffd21f4655f..2ccdf0697624e 100644 --- a/test/OpenMP/parallel_for_simd_aligned_messages.cpp +++ b/test/OpenMP/parallel_for_simd_aligned_messages.cpp @@ -196,6 +196,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd aligned(h) for (int k = 0; k < argc; ++k) ++k; int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} foomain<int*,char>(pargc,argv); return 0; } diff --git a/test/OpenMP/parallel_for_simd_ast_print.cpp b/test/OpenMP/parallel_for_simd_ast_print.cpp index 1b9415d8dbf30..cdd1b73b59032 100644 --- a/test/OpenMP/parallel_for_simd_ast_print.cpp +++ b/test/OpenMP/parallel_for_simd_ast_print.cpp @@ -7,6 +7,58 @@ #define HEADER void foo() {} + +struct S1 { + S1() : a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp parallel for simd private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) + int g_ind = 1; template<class T, class N> T reduct(T* arr, N num) { N i; diff --git a/test/OpenMP/parallel_for_simd_collapse_messages.cpp b/test/OpenMP/parallel_for_simd_collapse_messages.cpp index 4f04cca5635eb..c7effbddeb28c 100644 --- a/test/OpenMP/parallel_for_simd_collapse_messages.cpp +++ b/test/OpenMP/parallel_for_simd_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for simd', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} #pragma omp parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} - #pragma omp parallel for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp parallel for simd collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp index 858f53f4674da..fc1895a36854a 100644 --- a/test/OpenMP/parallel_for_simd_linear_messages.cpp +++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp @@ -208,7 +208,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd linear(i) for (int k = 0; k < argc; ++k) ++k; - foomain<int,char>(argc,argv); + foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} return 0; } diff --git a/test/OpenMP/parallel_for_simd_loop_messages.cpp b/test/OpenMP/parallel_for_simd_loop_messages.cpp index e5fd8c04c0cfc..403e951d53c43 100644 --- a/test/OpenMP/parallel_for_simd_loop_messages.cpp +++ b/test/OpenMP/parallel_for_simd_loop_messages.cpp @@ -355,12 +355,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -403,7 +403,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for simd for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel for simd for (begin = begin0; begin < end; ++begin) diff --git a/test/OpenMP/parallel_for_simd_private_messages.cpp b/test/OpenMP/parallel_for_simd_private_messages.cpp index a031d407ec1bf..a33b35d57d1ef 100644 --- a/test/OpenMP/parallel_for_simd_private_messages.cpp +++ b/test/OpenMP/parallel_for_simd_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -119,6 +167,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}} @@ -180,6 +230,8 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) m = k + 3; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp index e2e9e1bca38b0..afb0b367c4193 100644 --- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -111,7 +111,7 @@ T tmain(T argc) { #pragma omp parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(&& : argc) @@ -120,22 +120,22 @@ T tmain(T argc) { #pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -150,7 +150,7 @@ T tmain(T argc) { #pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -160,7 +160,7 @@ T tmain(T argc) { #pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} @@ -251,13 +251,13 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} diff --git a/test/OpenMP/parallel_for_simd_safelen_messages.cpp b/test/OpenMP/parallel_for_simd_safelen_messages.cpp index 45f2fa2b6277c..3e643c619c6fc 100644 --- a/test/OpenMP/parallel_for_simd_safelen_messages.cpp +++ b/test/OpenMP/parallel_for_simd_safelen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd safelen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} - // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd safelen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} diff --git a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp index dd1cf0feaa497..fa9e0d6802a9c 100644 --- a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp +++ b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd simdlen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}} - // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for simd simdlen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}} // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} #pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} diff --git a/test/OpenMP/parallel_num_threads_codegen.cpp b/test/OpenMP/parallel_num_threads_codegen.cpp index d744e5e87b748..c5f11bde19aed 100644 --- a/test/OpenMP/parallel_num_threads_codegen.cpp +++ b/test/OpenMP/parallel_num_threads_codegen.cpp @@ -72,11 +72,11 @@ int main() { // CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 1) // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call( -// CHECK: call {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23) +// CHECK: {{(invoke|call)}} {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23) // CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP]]([[S_TY]]* [[S_TEMP]]) // CHECK: [[RES:%.+]] = sext {{.*}}i8 [[S_CHAR_OP]] to i32 // CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]]) -// CHECK: call {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]]) +// CHECK: {{(invoke|call)}} {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]]) // CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call( // CHECK: ret [[INT_TY]] 0 // CHECK: } diff --git a/test/OpenMP/parallel_private_codegen.cpp b/test/OpenMP/parallel_private_codegen.cpp index 1d195be97d6e8..1498d456dfa55 100644 --- a/test/OpenMP/parallel_private_codegen.cpp +++ b/test/OpenMP/parallel_private_codegen.cpp @@ -18,11 +18,69 @@ struct S { volatile int g __attribute__((aligned(128))) = 1212; +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel private(a, b, c) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel private(a, b, c) + ++(this)->a, --b, this->c /= 1; + }(); +#elif defined(BLOCKS) + ^{ + ++a; + --this->b; + (this)->c /= 1; +#pragma omp parallel private(a, b, c) + ++(this)->a, --b, this->c /= 1; + }(); +#else + ++this->a, --b, c /= 1; +#endif + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp parallel private(a) +#ifdef LAMBDA + [&]() { + [&]() { + ++this->a; +#pragma omp parallel private(a) + ++(this)->a; + }(); + }(); +#elif defined(BLOCKS) + ^{ + ^{ + ++a; +#pragma omp parallel private(a) + ++(this)->a; + }(); + }(); +#else + ++(this)->a; +#endif + } +}; + +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 // CHECK: [[S_FLOAT_TY:%.+]] = type { float } // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK: [[SST_TY:%.+]] = type { i{{[0-9]+}} } template <typename T> T tmain() { S<T> test; + SST<T> sst; T t_var __attribute__((aligned(128))) = T(); T vec[] __attribute__((aligned(128))) = {1, 2}; S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; @@ -37,16 +95,49 @@ T tmain() { int main() { static int sivar; + SS ss(sivar); #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main - // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: alloca [[SS_TY]], + // LAMBDA: alloca [[CAP_TY:%.+]], + // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]* [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA-NOT: = getelementptr inbounds %{{.+}}, // LAMBDA: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel private(g, sivar) { + // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % + // LAMBDA: store i8 + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void + // LAMBDA: ret + + // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % + // LAMBDA: call{{.*}} void + // LAMBDA: ret void + + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], + // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], + // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], + // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], + // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: ret void + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, @@ -80,6 +171,7 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main + // BLOCKS: call // BLOCKS: call{{.*}} void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* @@ -116,6 +208,35 @@ int main() { } }(); return 0; +// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// BLOCKS: store i8 +// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void +// BLOCKS: ret + +// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % +// BLOCKS: call{{.*}} void +// BLOCKS: ret void + +// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: ret void #else S<float> test; int t_var = 0; @@ -166,6 +287,31 @@ int main() { // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // +// CHECK: define {{.+}} @{{.+}}([[SS_TY]]* +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// CHECK: store i8 +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void +// CHECK: ret + +// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: ret void + // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128 @@ -184,5 +330,20 @@ int main() { // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK: ret void + +// CHECK: define {{.+}} @{{.+}}([[SST_TY]]* % +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SST_TY]]*)* [[SST_MICROTASK:@.+]] to void +// CHECK: ret + +// CHECK: define internal void [[SST_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SST_TY]]* %{{.+}}) +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REF:%.+]], +// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REF]], +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: ret void + #endif diff --git a/test/OpenMP/parallel_reduction_codegen.cpp b/test/OpenMP/parallel_reduction_codegen.cpp index 05224d0a1391c..703750c2337f7 100644 --- a/test/OpenMP/parallel_reduction_codegen.cpp +++ b/test/OpenMP/parallel_reduction_codegen.cpp @@ -20,6 +20,62 @@ struct S { ~S() {} }; +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel reduction(+: a, b, c) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel reduction(&: a, b, c) + ++(this)->a, --b, this->c /= 1; + }(); +#elif defined(BLOCKS) + ^{ + ++a; + --this->b; + (this)->c /= 1; +#pragma omp parallel reduction(-: a, b, c) + ++(this)->a, --b, this->c /= 1; + }(); +#else + ++this->a, --b, c /= 1; +#endif + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp parallel reduction(*: a) +#ifdef LAMBDA + [&]() { + [&]() { + ++this->a; +#pragma omp parallel reduction(&& :a) + ++(this)->a; + }(); + }(); +#elif defined(BLOCKS) + ^{ + ^{ + ++a; +#pragma omp parallel reduction(|: a) + ++(this)->a; + }(); + }(); +#else + ++(this)->a; +#endif + } +}; + +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } // CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8* @@ -29,6 +85,7 @@ template <typename T> T tmain() { T t; S<T> test; + SST<T> sst; T t_var __attribute__((aligned(128))) = T(), t_var1 __attribute__((aligned(128))); T vec[] = {1, 2}; S<T> s_arr[] = {1, 2}; @@ -41,16 +98,62 @@ T tmain() { return T(); } +int sivar; int main() { + SS ss(sivar); #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main - // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + // LAMBDA: alloca [[SS_TY]], + // LAMBDA: alloca [[CAP_TY:%.+]], + // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]* [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) #pragma omp parallel reduction(+:g) { + // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 + // LAMBDA: store i8 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 + // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 + // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i32*, i32*, i32*)* [[SS_MICROTASK:@.+]] to void + // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 + // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]], + // LAMBDA: ret + + // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) + // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % + // LAMBDA: call{{.*}} void + // LAMBDA: ret void + + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], + // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], + // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], + // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], + // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], + // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], + // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 + // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], + // LAMBDA: call i32 @__kmpc_reduce_nowait( + // LAMBDA: ret void + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, @@ -100,6 +203,7 @@ int main() { #elif defined(BLOCKS) // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, // BLOCKS-LABEL: @main + // BLOCKS: call // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* @@ -152,6 +256,47 @@ int main() { } }(); return 0; +// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// BLOCKS: store i8 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// BLOCKS-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i32*, i32*, i32*)* [[SS_MICROTASK:@.+]] to void +// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]], +// BLOCKS: ret + +// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) +// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % +// BLOCKS: call{{.*}} void +// BLOCKS: ret void + +// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) +// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// BLOCKS: call i32 @__kmpc_reduce_nowait( +// BLOCKS: ret void #else S<float> test; float t_var = 0, t_var1; @@ -472,6 +617,43 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // +// CHECK: define {{.+}} @{{.+}}([[SS_TY]]* +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: store i8 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*)* [[SS_MICROTASK:@.+]] to void +// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 +// CHECK: store i8 %{{.+}}, i8* [[B_REF]], +// CHECK: ret + +// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[A_PRIV]], +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[B_PRIV]], +// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[C_PRIV]], +// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], +// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], +// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], +// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 +// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], +// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], +// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], +// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], +// CHECK: call i32 @__kmpc_reduce_nowait( +// CHECK: ret void + // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp index b29f7c98a5744..af1f5ed7bc0d9 100644 --- a/test/OpenMP/parallel_reduction_messages.cpp +++ b/test/OpenMP/parallel_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s void foo() { } @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -101,23 +101,23 @@ T tmain(T argc) { foo(); #pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} foo(); #pragma omp parallel reduction(&& : argc) foo(); #pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); -#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} foo(); -#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); @@ -127,14 +127,14 @@ T tmain(T argc) { foo(); #pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} foo(); -#pragma omp parallel reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp parallel reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} foo(); #pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} foo(); #pragma omp parallel private(k) #pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} foo(); -#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} foo(); #pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} foo(); @@ -208,11 +208,11 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp index 9f5c1fadbeb82..a66b75ea6d796 100644 --- a/test/OpenMP/parallel_sections_ast_print.cpp +++ b/test/OpenMP/parallel_sections_ast_print.cpp @@ -141,4 +141,7 @@ int main(int argc, char **argv) { return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); } +template<typename T> +T S<T>::TS = 0; + #endif diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp index ac9280e74ce10..40b0138b53967 100644 --- a/test/OpenMP/parallel_sections_private_messages.cpp +++ b/test/OpenMP/parallel_sections_private_messages.cpp @@ -29,7 +29,13 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp parallel sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } }; class S5 { int a; @@ -37,6 +43,60 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp parallel sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp parallel sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } + S6 &operator=(S6 &s) { +#pragma omp parallel sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp parallel sections private(a) private(this->a) private(T::a) + { + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + } + S7 &operator=(S7 &s) { +#pragma omp parallel sections private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + } + return *this; + } }; S3 h; @@ -134,6 +194,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp parallel sections private // expected-error {{expected '(' after 'private'}} @@ -212,6 +274,8 @@ int main(int argc, char **argv) { foo(); } - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp index eff1849d71323..52d4cb9cdcb65 100644 --- a/test/OpenMP/parallel_sections_reduction_messages.cpp +++ b/test/OpenMP/parallel_sections_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s void foo() { } @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -121,7 +121,7 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp parallel sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} { foo(); } @@ -133,11 +133,11 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} { foo(); } -#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} { foo(); } @@ -145,15 +145,15 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -173,7 +173,7 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp parallel sections reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} { foo(); } @@ -186,7 +186,7 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} { foo(); } @@ -298,15 +298,15 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } diff --git a/test/OpenMP/predefined_macro.c b/test/OpenMP/predefined_macro.c index 9a961bce552f2..e18c3d26d4c22 100644 --- a/test/OpenMP/predefined_macro.c +++ b/test/OpenMP/predefined_macro.c @@ -5,7 +5,7 @@ // -fopenmp option is specified #ifndef _OPENMP #error "No _OPENMP macro is defined with -fopenmp option" -#elsif _OPENMP != 201307 +#elsif _OPENMP != 201107 #error "_OPENMP has incorrect value" #endif //_OPENMP #else diff --git a/test/OpenMP/sections_firstprivate_codegen.cpp b/test/OpenMP/sections_firstprivate_codegen.cpp index 0e9273f52ca77..51d0c7b61834c 100644 --- a/test/OpenMP/sections_firstprivate_codegen.cpp +++ b/test/OpenMP/sections_firstprivate_codegen.cpp @@ -59,7 +59,6 @@ S<float> s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S<float> var(3); // CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, -// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[SECTIONS_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) @@ -94,7 +93,7 @@ int main() { // LAMBDA: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_REF]] // LAMBDA: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]] - // LAMBDA: call void @__kmpc_barrier( + // LAMBDA-NOT: call void @__kmpc_barrier( { g = 1; sivar = 10; @@ -154,7 +153,7 @@ int main() { // BLOCKS: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_REF]], // BLOCKS: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]], - // BLOCKS: call void @__kmpc_barrier( + // BLOCKS-NOT: call void @__kmpc_barrier( { g = 1; sivar = 10; @@ -217,6 +216,7 @@ int main() { // firstprivate t_var(t_var) // CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], + // firstprivate vec(vec) // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* // CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), @@ -242,7 +242,7 @@ int main() { // CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], // CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]], -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( @@ -257,7 +257,11 @@ int main() { // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: [[T_VARVAL:%.+]] = load i32, i32* %{{.+}}, +// CHECK: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST:%.+]] to i32* +// CHECK: store i32 [[T_VARVAL]], i32* [[T_VARCONV]], +// CHECK: [[T_VARPVT:%.+]] = load i64, i64* [[T_VARCAST]], +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void {{.*}}i64 [[T_VARPVT]], // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // @@ -268,19 +272,20 @@ int main() { // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, +// CHECK: alloca i{{[0-9]+}}, // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % // CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % // CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % // firstprivate t_var(t_var) -// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], // firstprivate vec(vec) @@ -304,10 +309,8 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// Synchronization for initialization. -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// No synchronization for initialization. +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp index f13bbdb012e22..27bb3136e7201 100644 --- a/test/OpenMP/sections_private_messages.cpp +++ b/test/OpenMP/sections_private_messages.cpp @@ -29,7 +29,13 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } }; class S5 { int a; @@ -37,6 +43,60 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } + S6 &operator=(S6 &s) { +#pragma omp sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp sections private(a) private(this->a) private(T::a) + { + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + } + S7 &operator=(S7 &s) { +#pragma omp sections private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + } + return *this; + } }; S3 h; @@ -134,6 +194,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp sections private // expected-error {{expected '(' after 'private'}} @@ -212,6 +274,8 @@ int main(int argc, char **argv) { foo(); } - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp index 79473d4e5d289..134bf619c9113 100644 --- a/test/OpenMP/sections_reduction_messages.cpp +++ b/test/OpenMP/sections_reduction_messages.cpp @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -132,7 +132,7 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} { foo(); } @@ -147,12 +147,12 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} { foo(); } @@ -162,17 +162,17 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -197,7 +197,7 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp sections reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} { foo(); } @@ -212,7 +212,7 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} { foo(); } @@ -342,17 +342,17 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } diff --git a/test/OpenMP/simd_aligned_messages.cpp b/test/OpenMP/simd_aligned_messages.cpp index 6be7529ad5119..9515a0bca68f1 100644 --- a/test/OpenMP/simd_aligned_messages.cpp +++ b/test/OpenMP/simd_aligned_messages.cpp @@ -196,6 +196,7 @@ int main(int argc, char **argv) { #pragma omp simd aligned(h) for (int k = 0; k < argc; ++k) ++k; int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} foomain<int*,char>(pargc,argv); return 0; } diff --git a/test/OpenMP/simd_ast_print.cpp b/test/OpenMP/simd_ast_print.cpp index cabbe338db2a4..99c00c6dca814 100644 --- a/test/OpenMP/simd_ast_print.cpp +++ b/test/OpenMP/simd_ast_print.cpp @@ -6,6 +6,58 @@ #ifndef HEADER #define HEADER +struct SS { + SS(): a(0) {} + SS(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T *a; + T b[2]; + S7() : a(0) {} + +public: + S7(typename T::type &v) : a((T*)&v) { +#pragma omp simd aligned(a) + for (int k = 0; k < a->a; ++k) + ++this->a->a; + } + S7 &operator=(S7 &s) { +#pragma omp simd aligned(this->b : 8) + for (int k = 0; k < s.a->a; ++k) + ++s.a->a; + return *this; + } +}; + +// CHECK: #pragma omp simd aligned(this->a) +// CHECK: #pragma omp simd aligned(this->a) +// CHECK: #pragma omp simd aligned(this->b: 8) + +class S8 : public S7<SS> { + S8() {} + +public: + S8(int v) : S7<SS>(v){ +#pragma omp simd aligned(S7<SS>::a) + for (int k = 0; k < a->a; ++k) + ++this->a->a; + } + S8 &operator=(S8 &s) { +#pragma omp simd aligned(this->b: 4) + for (int k = 0; k < s.a->a; ++k) + ++s.a->a; + return *this; + } +}; + +// CHECK: #pragma omp simd aligned(this->S7<SS>::a) +// CHECK: #pragma omp simd aligned(this->b: 4) + void foo() {} int g_ind = 1; template<class T, class N> T reduct(T* arr, N num) { diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp index 62028339f5142..29828b39173cd 100644 --- a/test/OpenMP/simd_codegen.cpp +++ b/test/OpenMP/simd_codegen.cpp @@ -4,8 +4,10 @@ // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG // REQUIRES: x86-registered-target // expected-no-diagnostics -#ifndef HEADER -#define HEADER + #ifndef HEADER + #define HEADER + +// CHECK: [[SS_TY:%.+]] = type { i32 } long long get_val() { return 0; } double *g_ptr; @@ -207,6 +209,7 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]] } // CHECK: [[SIMPLE_LOOP7_END]] +// CHECK-NEXT: store i64 11, i64* // CHECK-NEXT: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]], // CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* [[A]], int R; @@ -321,7 +324,6 @@ public: // CHECK-LABEL: define {{.*void}} @{{.*}}iter_simple{{.*}} void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) { // -// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]] // Calculate number of iterations before the loop body. // CHECK: [[DIFF1:%.+]] = invoke {{.*}}i32 @{{.*}}IterDouble{{.*}} // CHECK: [[DIFF2:%.+]] = sub nsw i32 [[DIFF1]], 1 @@ -329,6 +331,7 @@ void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) { // CHECK-NEXT: [[DIFF4:%.+]] = sdiv i32 [[DIFF3]], 1 // CHECK-NEXT: [[DIFF5:%.+]] = sub nsw i32 [[DIFF4]], 1 // CHECK-NEXT: store i32 [[DIFF5]], i32* [[OMP_LAST_IT:%[^,]+]]{{.+}} +// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]] #pragma omp simd // CHECK: [[IV:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}} !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID:[0-9]+]] @@ -416,9 +419,10 @@ void collapsed(float *a, float *b, float *c, float *d) { // CHECK: [[COLL1_END]] } // i,j,l are updated; k is not updated. -// CHECK: store i32 3, i32* [[I:%[^,]+]] -// CHECK-NEXT: store i32 5, i32* [[I:%[^,]+]] -// CHECK-NEXT: store i16 9, i16* [[I:%[^,]+]] +// CHECK: store i32 3, i32* +// CHECK-NEXT: store i32 5, i32* +// CHECK-NEXT: store i32 7, i32* +// CHECK-NEXT: store i16 9, i16* // CHECK: ret void } @@ -490,8 +494,10 @@ void linear(float *a) { #pragma omp simd linear(k : 3) // CHECK: store i64* [[VAL_ADDR]], i64** [[K_ADDR]], +// CHECK: [[VAL_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: store i64* [[VAL_REF]], i64** [[K_ADDR_REF:%.+]], // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]] -// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]], // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]] // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] @@ -524,7 +530,7 @@ void linear(float *a) { // CHECK: [[SIMPLE_LOOP_END]] // // Update linear vars after loop, as the loop was operating on a private version. -// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]], // CHECK: store i64* [[K_REF]], i64** [[K_PRIV_REF:%.+]], // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]] // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27 @@ -533,8 +539,10 @@ void linear(float *a) { // #pragma omp simd linear(val(k) : 3) +// CHECK: [[VAL_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: store i64* [[VAL_REF]], i64** [[K_ADDR_REF:%.+]], // CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]] -// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]], // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]] // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] @@ -567,7 +575,7 @@ void linear(float *a) { // CHECK: [[SIMPLE_LOOP_END]] // // Update linear vars after loop, as the loop was operating on a private version. -// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]], // CHECK: store i64* [[K_REF]], i64** [[K_PRIV_REF:%.+]], // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]] // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27 @@ -632,5 +640,68 @@ void parallel_simd(float *a) { a[i] += bar(); } // TERM_DEBUG: !{{[0-9]+}} = !DILocation(line: [[@LINE-11]], + +// CHECK-LABEL: S8 +// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64 +// CHECK-NEXT: and i64 %{{.+}}, 15 +// CHECK-NEXT: icmp eq i64 %{{.+}}, 0 +// CHECK-NEXT: call void @llvm.assume(i1 + +// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64 +// CHECK-NEXT: and i64 %{{.+}}, 7 +// CHECK-NEXT: icmp eq i64 %{{.+}}, 0 +// CHECK-NEXT: call void @llvm.assume(i1 + +// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64 +// CHECK-NEXT: and i64 %{{.+}}, 15 +// CHECK-NEXT: icmp eq i64 %{{.+}}, 0 +// CHECK-NEXT: call void @llvm.assume(i1 + +// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64 +// CHECK-NEXT: and i64 %{{.+}}, 3 +// CHECK-NEXT: icmp eq i64 %{{.+}}, 0 +// CHECK-NEXT: call void @llvm.assume(i1 +struct SS { + SS(): a(0) {} + SS(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T *a; + T b[2]; + S7() : a(0) {} + +public: + S7(typename T::type &v) : a((T*)&v) { +#pragma omp simd aligned(a) + for (int k = 0; k < a->a; ++k) + ++this->a->a; +#pragma omp simd aligned(this->b : 8) + for (int k = 0; k < a->a; ++k) + ++a->a; + } +}; + +class S8 : private IterDouble, public S7<SS> { + S8() {} + +public: + S8(int v) : S7<SS>(v){ +#pragma omp parallel private(a) +#pragma omp simd aligned(S7<SS>::a) + for (int k = 0; k < a->a; ++k) + ++this->a->a; +#pragma omp parallel shared(b) +#pragma omp simd aligned(this->b: 4) + for (int k = 0; k < a->a; ++k) + ++a->a; + } +}; +S8 s8(0); + #endif // HEADER diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp index e34f0a15b20c9..5b8802468849b 100644 --- a/test/OpenMP/simd_collapse_messages.cpp +++ b/test/OpenMP/simd_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp simd', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} #pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}} diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp index 7cc5ba81f78b4..16223db71ad57 100644 --- a/test/OpenMP/simd_lastprivate_messages.cpp +++ b/test/OpenMP/simd_lastprivate_messages.cpp @@ -217,5 +217,5 @@ int main(int argc, char **argv) { #pragma omp simd lastprivate(t) // OK for (i = 0; i < argc; ++i) foo(); - return 0; + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp index 3442d182ed02e..1850101891f7e 100644 --- a/test/OpenMP/simd_private_messages.cpp +++ b/test/OpenMP/simd_private_messages.cpp @@ -26,13 +26,61 @@ class S4 { int a; S4(); // expected-note {{implicitly declared private here}} public: - S4(int v):a(v) { } + S4(int v) : a(v) { +#pragma omp simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; S5():a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v):a(v) { } + S5 &operator=(S5 &s) { +#pragma omp simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -96,6 +144,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp simd private // expected-error {{expected '(' after 'private'}} @@ -137,6 +187,8 @@ int main(int argc, char **argv) { #pragma omp simd private(i) for (int k = 0; k < argc; ++k) ++k; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp index e082921cf3839..c47d53eb9185e 100644 --- a/test/OpenMP/simd_reduction_messages.cpp +++ b/test/OpenMP/simd_reduction_messages.cpp @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -111,7 +111,7 @@ T tmain(T argc) { #pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(&& : argc) @@ -120,22 +120,22 @@ T tmain(T argc) { #pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -150,7 +150,7 @@ T tmain(T argc) { #pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -163,7 +163,7 @@ T tmain(T argc) { #pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} @@ -254,13 +254,13 @@ int main(int argc, char **argv) { #pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} diff --git a/test/OpenMP/simd_safelen_messages.cpp b/test/OpenMP/simd_safelen_messages.cpp index aa31b7da9b7fc..56cb868337e0f 100644 --- a/test/OpenMP/simd_safelen_messages.cpp +++ b/test/OpenMP/simd_safelen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd safelen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}} - // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}} + // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd safelen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd safelen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp simd safelen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}} // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd safelen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}} diff --git a/test/OpenMP/simd_simdlen_messages.cpp b/test/OpenMP/simd_simdlen_messages.cpp index 91656f87b583e..426d1878ba4ca 100644 --- a/test/OpenMP/simd_simdlen_messages.cpp +++ b/test/OpenMP/simd_simdlen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd simdlen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}} - // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd simdlen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp simd simdlen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp simd simdlen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}} // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} #pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}} diff --git a/test/OpenMP/single_ast_print.cpp b/test/OpenMP/single_ast_print.cpp index 8eb35174a77f2..d30b7feb02c57 100644 --- a/test/OpenMP/single_ast_print.cpp +++ b/test/OpenMP/single_ast_print.cpp @@ -8,15 +8,43 @@ void foo() {} +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel firstprivate(a, b, c) +#pragma omp single copyprivate(a, this->b, (this)->c) +// CHECK: #pragma omp parallel firstprivate(this->a,this->b,this->c) +// CHECK-NEXT: #pragma omp single copyprivate(this->a,this->b,this->c) + ++this->a, --b, (this)->c /= 1; + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +// CHECK: #pragma omp parallel firstprivate(this->a) +// CHECK-NEXT: #pragma omp single copyprivate(this->a) +// CHECK: #pragma omp parallel firstprivate(this->a) +// CHECK-NEXT: #pragma omp single copyprivate(this->a) +#pragma omp parallel firstprivate(a) +#pragma omp single copyprivate(this->a) + ++this->a; + } +}; + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, g; static T a; + SST<T> sst; // CHECK: static T a; #pragma omp parallel private(g) #pragma omp single private(argc, b), firstprivate(c, d), nowait foo(); - // CHECK-NEXT: #pragma omp parallel private(g) + // CHECK: #pragma omp parallel private(g) // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait // CHECK-NEXT: foo(); #pragma omp parallel private(g) @@ -31,11 +59,12 @@ T tmain(T argc) { int main(int argc, char **argv) { int b = argc, c, d, e, f, g; static int a; + SS ss(a); // CHECK: static int a; #pragma omp parallel private(g) #pragma omp single private(argc, b), firstprivate(argv, c), nowait foo(); - // CHECK-NEXT: #pragma omp parallel private(g) + // CHECK: #pragma omp parallel private(g) // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait // CHECK-NEXT: foo(); #pragma omp parallel private(g) diff --git a/test/OpenMP/single_codegen.cpp b/test/OpenMP/single_codegen.cpp index 61a93a5a1b735..a2140c2eda78b 100644 --- a/test/OpenMP/single_codegen.cpp +++ b/test/OpenMP/single_codegen.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s // RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -std=c++11 -fopenmp -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG // RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s // expected-no-diagnostics // REQUIRES: x86-registered-target @@ -19,7 +19,9 @@ public: }; // CHECK-DAG: [[TEST_CLASS_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-DAG: [[SST_TY:%.+]] = type { double } +// CHECK-DAG: [[SS_TY:%.+]] = type { i32, i8, i32* } +// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } // CHECK: [[IMPLICIT_BARRIER_SINGLE_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8* // CHECK: define void [[FOO:@.+]]() @@ -30,6 +32,39 @@ TestClass tc2[2]; void foo() {} +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp parallel firstprivate(a, b, c) +#pragma omp single copyprivate(a, this->b, (this)->c) + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel firstprivate(a, b, c) +#pragma omp single copyprivate(a, this->b, (this)->c) + ++(this)->a, --b, this->c /= 1; + }(); + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp parallel firstprivate(a) +#pragma omp single copyprivate(this->a) + [&]() { + [&]() { + ++this->a; +#pragma omp parallel firstprivate(a) +#pragma omp single copyprivate((this)->a) + ++(this)->a; + }(); + }(); + } +}; + // CHECK-LABEL: @main // TERM_DEBUG-LABEL: @main int main() { @@ -39,6 +74,8 @@ int main() { char a; char a2[2]; TestClass &c = tc; + SST<double> sst; + SS ss(c.a); // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]]) // CHECK-DAG: [[DID_IT:%.+]] = alloca i32, @@ -74,8 +111,8 @@ int main() { // CHECK-NEXT: invoke void [[FOO]]() // CHECK: to label {{%?}}[[CONT:.+]] unwind // CHECK: [[CONT]] -// CHECK: store i32 1, i32* [[DID_IT]] // CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK: store i32 1, i32* [[DID_IT]] // CHECK-NEXT: br label {{%?}}[[EXIT]] // CHECK: [[EXIT]] // CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 @@ -186,3 +223,210 @@ void array_func(int n, int a[n], St s[2]) { // ARRAY: store i32* %{{.+}}, i32** %{{.+}}, // ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}}, #endif + +// CHECK-LABEL:@_ZN2SSC2ERi( +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SS_TY]]*, i64, i64, i64)* [[SS_MICROTASK:@.+]] to void +// CHECK-NEXT: ret void + +// CHECK: define internal void [[SS_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SS_TY]]* {{.+}}, i64 {{.+}}, i64 {{.+}}, i64 {{.+}}) +// Private a +// CHECK: alloca i64, +// Private b +// CHECK: alloca i64, +// Private c +// CHECK: alloca i64, +// CHECK: alloca i32*, +// CHECK: alloca i32*, +// CHECK: alloca i32*, +// CHECK: alloca i32*, +// CHECK: [[DID_IT:%.+]] = alloca i32, +// CHECK: bitcast i64* %{{.+}} to i32* +// CHECK: bitcast i64* %{{.+}} to i32* +// CHECK: bitcast i64* %{{.+}} to i32* +// CHECK: store i32 0, i32* [[DID_IT]], +// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK-NEXT: icmp ne i32 [[RES]], 0 +// CHECK-NEXT: br i1 + +// CHECK: getelementptr inbounds [[CAP_TY:%.+]], [[CAP_TY]]* [[CAP:%.+]], i32 0, i32 0 +// CHECK: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 1 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: store i32* % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2 +// CHECK-NEXT: store i32* % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: store i32* % +// CHECK-LABEL: invoke void @_ZZN2SSC1ERiENKUlvE_clEv( +// CHECK-SAME: [[CAP_TY]]* [[CAP]]) + +// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK: store i32 1, i32* [[DID_IT]], +// CHECK: br label + +// CHECK: call void @__kmpc_end_single(%{{.+}}* @{{.+}}, i32 %{{.+}}) +// CHECK: br label + +// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0 +// CHECK: load i32*, i32** % +// CHECK-NEXT: bitcast i32* % +// CHECK-NEXT: store i8* % +// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 1 +// CHECK-NEXT: bitcast i32* % +// CHECK-NEXT: store i8* % +// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 2 +// CHECK: load i32*, i32** % +// CHECK-NEXT: bitcast i32* % +// CHECK-NEXT: store i8* % +// CHECK-NEXT: bitcast [3 x i8*]* [[LIST]] to i8* +// CHECK-NEXT: load i32, i32* [[DID_IT]], +// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 24, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}}) +// CHECK-NEXT: ret void + +// CHECK-LABEL: @_ZZN2SSC1ERiENKUlvE_clEv( +// CHECK: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP:%.+]], i32 0, i32 1 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: add nsw i32 %{{.+}}, 1 +// CHECK-NEXT: store i32 % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: add nsw i32 %{{.+}}, -1 +// CHECK-NEXT: store i32 % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 +// CHECK-NEXT: store i32 % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 1 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: bitcast i64* % +// CHECK-NEXT: store i32 %{{.+}}, i32* % +// CHECK-NEXT: load i64, i64* % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: bitcast i64* % +// CHECK-NEXT: store i32 %{{.+}}, i32* % +// CHECK-NEXT: load i64, i64* % +// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3 +// CHECK-NEXT: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: bitcast i64* % +// CHECK-NEXT: store i32 %{{.+}}, i32* % +// CHECK-NEXT: load i64, i64* % +// CHECK-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SS_TY]]*, i64, i64, i64)* [[SS_MICROTASK1:@.+]] to void +// CHECK-NEXT: ret void + +// CHECK: define internal void [[COPY_FUNC]](i8*, i8*) +// CHECK: ret void + +// CHECK: define internal void [[SS_MICROTASK1]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SS_TY]]* {{.+}}, i64 {{.+}}, i64 {{.+}}, i64 {{.+}}) +// Private a +// CHECK: alloca i64, +// Private b +// CHECK: alloca i64, +// Private c +// CHECK: alloca i64, +// CHECK: alloca i32*, +// CHECK: alloca i32*, +// CHECK: alloca i32*, +// CHECK: alloca i32*, +// CHECK: [[DID_IT:%.+]] = alloca i32, +// CHECK: bitcast i64* %{{.+}} to i32* +// CHECK: bitcast i64* %{{.+}} to i32* +// CHECK: bitcast i64* %{{.+}} to i32* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK-NEXT: icmp ne i32 [[RES]], 0 +// CHECK-NEXT: br i1 + +// CHECK-NOT: getelementptr inbounds +// CHECK: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: add nsw i32 %{{.+}}, 1 +// CHECK-NEXT: store i32 % +// CHECK-NOT: getelementptr inbounds +// CHECK: load i32, i32* % +// CHECK-NEXT: add nsw i32 %{{.+}}, -1 +// CHECK-NEXT: store i32 % +// CHECK-NOT: getelementptr inbounds +// CHECK: load i32*, i32** % +// CHECK-NEXT: load i32, i32* % +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 +// CHECK-NEXT: store i32 % +// CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK-NEXT: store i32 1, i32* [[DID_IT]], +// CHECK-NEXT: br label + +// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0 +// CHECK: load i32*, i32** % +// CHECK-NEXT: bitcast i32* % +// CHECK-NEXT: store i8* % +// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 1 +// CHECK-NEXT: bitcast i32* % +// CHECK-NEXT: store i8* % +// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 2 +// CHECK: load i32*, i32** % +// CHECK-NEXT: bitcast i32* % +// CHECK-NEXT: store i8* % +// CHECK-NEXT: bitcast [3 x i8*]* [[LIST]] to i8* +// CHECK-NEXT: load i32, i32* [[DID_IT]], +// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 24, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}}) +// CHECK-NEXT: ret void + +// CHECK: define internal void [[COPY_FUNC]](i8*, i8*) +// CHECK: ret void + +// CHECK-LABEL: @_ZN3SSTIdEC2Ev +// CHECK: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK-NEXT: store double 0.000000e+00, double* % +// CHECK-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK-NEXT: store double* %{{.+}}, double** % +// CHECK-NEXT: load double*, double** % +// CHECK-NEXT: load double, double* % +// CHECK-NEXT: bitcast i64* %{{.+}} to double* +// CHECK-NEXT: store double %{{.+}}, double* % +// CHECK-NEXT: load i64, i64* % +// CHECK-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void +// CHECK-NEXT: ret void + +// CHECK: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}}) +// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK-NEXT: icmp ne i32 [[RES]], 0 +// CHECK-NEXT: br i1 + +// CHECK: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// CHECK-NEXT: load double*, double** % +// CHECK-NEXT: store double* % +// CHECK-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv( + +// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK-NEXT: store i32 1, i32* [[DID_IT]], +// CHECK-NEXT: br label + +// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// CHECK-NEXT: br label + +// CHECK: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0 +// CHECK: load double*, double** % +// CHECK-NEXT: bitcast double* % +// CHECK-NEXT: store i8* % +// CHECK-NEXT: bitcast [1 x i8*]* [[LIST]] to i8* +// CHECK-NEXT: load i32, i32* [[DID_IT]], +// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}}) +// CHECK-NEXT: ret void + +// CHECK-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv( +// CHECK: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// CHECK-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// CHECK-NEXT: load double*, double** % +// CHECK-NEXT: store double* % +// CHECK-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( +// CHECK-NEXT: ret void + +// CHECK: define internal void [[COPY_FUNC]](i8*, i8*) +// CHECK: ret void + +// CHECK-LABEL: @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( diff --git a/test/OpenMP/single_firstprivate_codegen.cpp b/test/OpenMP/single_firstprivate_codegen.cpp index cc72addb5f453..537ae76f12772 100644 --- a/test/OpenMP/single_firstprivate_codegen.cpp +++ b/test/OpenMP/single_firstprivate_codegen.cpp @@ -57,7 +57,6 @@ int vec[] = {1, 2}; S<float> s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S<float> var(3); -// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[SINGLE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) @@ -215,7 +214,7 @@ int main() { // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK: call void @__kmpc_end_single( -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() @@ -224,18 +223,24 @@ int main() { // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR:%.+]], +// CHECK: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST:%.+]] to i32* +// CHECK: store i32 [[T_VARVAL]], i32* [[T_VARCONV]], +// CHECK: [[T_VARPVT:%.+]] = load i64, i64* [[T_VARCAST]], +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void {{.*}}i64 [[T_VARPVT:%.+]], // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 {{.*}}%{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[T_VAR_ARG:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_ARG]] to i32* // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % // CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % // CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % @@ -245,7 +250,7 @@ int main() { // CHECK: call i32 @__kmpc_single( // firstprivate t_var(t_var) -// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], // firstprivate vec(vec) diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp index a24cf47cd2a26..0ed0e6cfb0999 100644 --- a/test/OpenMP/single_private_messages.cpp +++ b/test/OpenMP/single_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp single private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp single private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp single private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp single private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -102,6 +150,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp single private // expected-error {{expected '(' after 'private'}} @@ -146,6 +196,8 @@ int main(int argc, char **argv) { #pragma omp single private(m) // OK foo(); - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp index acf032a221202..e093e29979ba8 100644 --- a/test/OpenMP/target_ast_print.cpp +++ b/test/OpenMP/target_ast_print.cpp @@ -25,6 +25,12 @@ T tmain(T argc, T *argv) { foo(); #pragma omp target map(always,alloc: i) foo(); +#pragma omp target nowait + foo(); +#pragma omp target depend(in : argc, argv[i:argc], a[:]) + foo(); +#pragma omp target defaultmap(tofrom: scalar) + foo(); return 0; } @@ -44,6 +50,12 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target map(always,alloc: i) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target nowait +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar) +// CHECK-NEXT: foo() // CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) { // CHECK-NEXT: char i, j, a[20] // CHECK-NEXT: #pragma omp target @@ -60,6 +72,12 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target map(always,alloc: i) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target nowait +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar) +// CHECK-NEXT: foo() // CHECK: template <typename T, int C> T tmain(T argc, T *argv) { // CHECK-NEXT: T i, j, a[20] // CHECK-NEXT: #pragma omp target @@ -76,6 +94,12 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target map(always,alloc: i) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target nowait +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar) +// CHECK-NEXT: foo() // CHECK-LABEL: int main(int argc, char **argv) { int main (int argc, char **argv) { @@ -115,6 +139,21 @@ int main (int argc, char **argv) { foo(); // CHECK-NEXT: foo(); +#pragma omp target nowait +// CHECK-NEXT: #pragma omp target nowait + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target depend(in : argc, argv[i:argc], a[:]) +// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target defaultmap(tofrom: scalar) +// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar) + foo(); +// CHECK-NEXT: foo(); + return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]); } diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp index c2e08d67b843f..f263ebdd2fe34 100644 --- a/test/OpenMP/target_codegen.cpp +++ b/test/OpenMP/target_codegen.cpp @@ -1,20 +1,20 @@ // Test host codegen. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 // Test target codegen - host bc file has to be created first. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 // expected-no-diagnostics #ifndef HEADER @@ -33,15 +33,15 @@ // sizes. // CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2] -// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2] -// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 128, i32 128] -// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 128, i32 3, i32 128, i32 3, i32 3, i32 128, i32 128, i32 3, i32 3] +// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288] +// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35] // CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40] -// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 128, i32 128, i32 3] +// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35] // CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40] -// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 128, i32 128, i32 128, i32 3] -// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 3, i32 128, i32 128, i32 128, i32 3] +// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35] +// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35] // CHECK-DAG: @{{.*}} = private constant i8 0 // CHECK-DAG: @{{.*}} = private constant i8 0 // CHECK-DAG: @{{.*}} = private constant i8 0 diff --git a/test/OpenMP/target_codegen_global_capture.cpp b/test/OpenMP/target_codegen_global_capture.cpp index 211a3cc884b67..b08bf10f9f29d 100644 --- a/test/OpenMP/target_codegen_global_capture.cpp +++ b/test/OpenMP/target_codegen_global_capture.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -21,6 +21,11 @@ // CHECK-DAG: [[BB:@.+]] = internal global float 1.000000e+01 // CHECK-DAG: [[BC:@.+]] = internal global float 1.100000e+01 // CHECK-DAG: [[BD:@.+]] = internal global float 1.200000e+01 +// CHECK-DAG: [[TBA:@.+]] = {{.*}}global float 1.700000e+01 +// CHECK-DAG: [[TBB:@.+]] = {{.*}}global float 1.800000e+01 +// CHECK-DAG: [[TBC:@.+]] = {{.*}}global float 1.900000e+01 +// CHECK-DAG: [[TBD:@.+]] = {{.*}}global float 2.000000e+01 + double Ga = 1.0; double Gb = 2.0; double Gc = 3.0; @@ -42,14 +47,14 @@ int foo(short a, short b, short c, short d){ static float Sd = 8.0; // CHECK-DAG: [[VALLB:%.+]] = load i16, i16* [[LB]], - // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* @Gb, - // CHECK-DAG: [[VALFB:%.+]] = load float, float* @_ZZ3foossssE2Sb, - // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* @Gc, + // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]], + // CHECK-DAG: [[VALFB:%.+]] = load float, float* [[FB]], + // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]], // CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LC]], - // CHECK-DAG: [[VALFC:%.+]] = load float, float* @_ZZ3foossssE2Sc, + // CHECK-DAG: [[VALFC:%.+]] = load float, float* [[FC]], // CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LD]], - // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* @Gd, - // CHECK-DAG: [[VALFD:%.+]] = load float, float* @_ZZ3foossssE2Sd, + // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]], + // CHECK-DAG: [[VALFD:%.+]] = load float, float* [[FD]], // 3 local vars being captured. @@ -178,14 +183,156 @@ int bar(short a, short b, short c, short d){ #pragma omp parallel { // CHECK-DAG: [[VALLB:%.+]] = load i16, i16* [[LLB]], - // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* @Gb, - // CHECK-DAG: [[VALFB:%.+]] = load float, float* @_ZZ3barssssE2Sb, - // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* @Gc, + // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]], + // CHECK-DAG: [[VALFB:%.+]] = load float, float* [[BB]], + // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]], + // CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LLC]], + // CHECK-DAG: [[VALFC:%.+]] = load float, float* [[BC]], + // CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LLD]], + // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]], + // CHECK-DAG: [[VALFD:%.+]] = load float, float* [[BD]], + + // 3 local vars being captured. + + // CHECK-DAG: store i16 [[VALLB]], i16* [[CONVLB:%.+]], + // CHECK-DAG: [[CONVLB]] = bitcast i[[sz:64|32]]* [[CADDRLB:%.+]] to i16* + // CHECK-DAG: [[CVALLB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLB]], + // CHECK-DAG: [[CPTRLB:%.+]] = inttoptr i[[sz]] [[CVALLB]] to i8* + // CHECK-DAG: store i8* [[CPTRLB]], i8** [[GEPLB:%.+]], + // CHECK-DAG: [[GEPLB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK-DAG: store i16 [[VALLC]], i16* [[CONVLC:%.+]], + // CHECK-DAG: [[CONVLC]] = bitcast i[[sz]]* [[CADDRLC:%.+]] to i16* + // CHECK-DAG: [[CVALLC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLC]], + // CHECK-DAG: [[CPTRLC:%.+]] = inttoptr i[[sz]] [[CVALLC]] to i8* + // CHECK-DAG: store i8* [[CPTRLC]], i8** [[GEPLC:%.+]], + // CHECK-DAG: [[GEPLC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK-DAG: store i16 [[VALLD]], i16* [[CONVLD:%.+]], + // CHECK-DAG: [[CONVLD]] = bitcast i[[sz]]* [[CADDRLD:%.+]] to i16* + // CHECK-DAG: [[CVALLD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLD]], + // CHECK-DAG: [[CPTRLD:%.+]] = inttoptr i[[sz]] [[CVALLD]] to i8* + // CHECK-DAG: store i8* [[CPTRLD]], i8** [[GEPLD:%.+]], + // CHECK-DAG: [[GEPLD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // 3 static vars being captured. + + // CHECK-DAG: store float [[VALFB]], float* [[CONVFB:%.+]], + // CHECK-DAG: [[CONVFB]] = bitcast i[[sz]]* [[CADDRFB:%.+]] to float* + // CHECK-DAG: [[CVALFB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFB]], + // CHECK-DAG: [[CPTRFB:%.+]] = inttoptr i[[sz]] [[CVALFB]] to i8* + // CHECK-DAG: store i8* [[CPTRFB]], i8** [[GEPFB:%.+]], + // CHECK-DAG: [[GEPFB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK-DAG: store float [[VALFC]], float* [[CONVFC:%.+]], + // CHECK-DAG: [[CONVFC]] = bitcast i[[sz]]* [[CADDRFC:%.+]] to float* + // CHECK-DAG: [[CVALFC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFC]], + // CHECK-DAG: [[CPTRFC:%.+]] = inttoptr i[[sz]] [[CVALFC]] to i8* + // CHECK-DAG: store i8* [[CPTRFC]], i8** [[GEPFC:%.+]], + // CHECK-DAG: [[GEPFC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK-DAG: store float [[VALFD]], float* [[CONVFD:%.+]], + // CHECK-DAG: [[CONVFD]] = bitcast i[[sz]]* [[CADDRFD:%.+]] to float* + // CHECK-DAG: [[CVALFD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFD]], + // CHECK-DAG: [[CPTRFD:%.+]] = inttoptr i[[sz]] [[CVALFD]] to i8* + // CHECK-DAG: store i8* [[CPTRFD]], i8** [[GEPFD:%.+]], + // CHECK-DAG: [[GEPFD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // 3 static global vars being captured. + + // CHECK-64-DAG: store double [[VALGB]], double* [[CONVGB:%.+]], + // CHECK-64-DAG: [[CONVGB]] = bitcast i[[sz]]* [[CADDRGB:%.+]] to double* + // CHECK-64-DAG: [[CVALGB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGB]], + // CHECK-64-DAG: [[CPTRGB:%.+]] = inttoptr i[[sz]] [[CVALGB]] to i8* + // CHECK-64-DAG: store i8* [[CPTRGB]], i8** [[GEPGB:%.+]], + // CHECK-32-DAG: store i8* bitcast (double* @Gb to i8*), i8** [[GEPGB:%.+]], + // CHECK-DAG: [[GEPGB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK-64-DAG: store double [[VALGC]], double* [[CONVGC:%.+]], + // CHECK-64-DAG: [[CONVGC]] = bitcast i[[sz]]* [[CADDRGC:%.+]] to double* + // CHECK-64-DAG: [[CVALGC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGC]], + // CHECK-64-DAG: [[CPTRGC:%.+]] = inttoptr i[[sz]] [[CVALGC]] to i8* + // CHECK-64-DAG: store i8* [[CPTRGC]], i8** [[GEPGC:%.+]], + // CHECK-32-DAG: store i8* bitcast (double* @Gc to i8*), i8** [[GEPGC:%.+]], + // CHECK-DAG: [[GEPGC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK-64-DAG: store double [[VALGD]], double* [[CONVGD:%.+]], + // CHECK-64-DAG: [[CONVGD]] = bitcast i[[sz]]* [[CADDRGD:%.+]] to double* + // CHECK-64-DAG: [[CVALGD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGD]], + // CHECK-64-DAG: [[CPTRGD:%.+]] = inttoptr i[[sz]] [[CVALGD]] to i8* + // CHECK-64-DAG: store i8* [[CPTRGD]], i8** [[GEPGD:%.+]], + // CHECK-32-DAG: store i8* bitcast (double* @Gd to i8*), i8** [[GEPGD:%.+]], + // CHECK-DAG: [[GEPGD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}} + + // CHECK: call i32 @__tgt_target + // CHECK: call void [[OFFLOADF:@.+]]( + // Capture b, Gb, Sb, Gc, c, Sc, d, Gd, Sd + #pragma omp target if(Ga>0.0 && a>0 && Sa>0.0) + { + b += 1; + Gb += 1.0; + Sb += 1.0; + + // CHECK: define internal void [[OFFLOADF]]({{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}) + // CHECK: call void {{.*}}@__kmpc_fork_call(%ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}) + + // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}) + // Capture d, Gd, Sd + #pragma omp parallel if(Gc>0.0 && c>0 && Sc>0.0) + { + d += 1; + Gd += 1.0; + Sd += 1.0; + } + } + } + return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd; +} + +/// +/// Tests with template functions. +/// + +// CHECK: define {{.*}} @{{.*}}tbar2{{.*}}( + +// CHECK: define {{.*}} @{{.*}}tbar{{.*}}( +// CHECK-SAME: i16 {{[^,]*}}[[A:%[^,]+]], +// CHECK-SAME: i16 {{[^,]*}}[[B:%[^,]+]], +// CHECK-SAME: i16 {{[^,]*}}[[C:%[^,]+]], +// CHECK-SAME: i16 {{[^,]*}}[[D:%[^,]+]]) +// CHECK: [[LA:%.+]] = alloca i16 +// CHECK: [[LB:%.+]] = alloca i16 +// CHECK: [[LC:%.+]] = alloca i16 +// CHECK: [[LD:%.+]] = alloca i16 +template<typename T> +int tbar(T a, T b, T c, T d){ + static float Sa = 17.0; + static float Sb = 18.0; + static float Sc = 19.0; + static float Sd = 20.0; + + // CHECK: call void {{.*}}@__kmpc_fork_call(%ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}), i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}}) + // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, i16* dereferenceable(2) [[A:%.+]], i16* dereferenceable(2) [[B:%.+]], i16* dereferenceable(2) [[C:%.+]], i16* dereferenceable(2) [[D:%.+]]) + // Capture a, b, c, d + // CHECK: [[ALLOCLA:%.+]] = alloca i16 + // CHECK: [[ALLOCLB:%.+]] = alloca i16 + // CHECK: [[ALLOCLC:%.+]] = alloca i16 + // CHECK: [[ALLOCLD:%.+]] = alloca i16 + // CHECK: [[LLA:%.+]] = load i16*, i16** [[ALLOCLA]], + // CHECK: [[LLB:%.+]] = load i16*, i16** [[ALLOCLB]], + // CHECK: [[LLC:%.+]] = load i16*, i16** [[ALLOCLC]], + // CHECK: [[LLD:%.+]] = load i16*, i16** [[ALLOCLD]], + #pragma omp parallel + { + // CHECK-DAG: [[VALLB:%.+]] = load i16, i16* [[LLB]], + // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]], + // CHECK-DAG: [[VALFB:%.+]] = load float, float* [[TBB]], + // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]], // CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LLC]], - // CHECK-DAG: [[VALFC:%.+]] = load float, float* @_ZZ3barssssE2Sc, + // CHECK-DAG: [[VALFC:%.+]] = load float, float* [[TBC]], // CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LLD]], - // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* @Gd, - // CHECK-DAG: [[VALFD:%.+]] = load float, float* @_ZZ3barssssE2Sd, + // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]], + // CHECK-DAG: [[VALFD:%.+]] = load float, float* [[TBD]], // 3 local vars being captured. @@ -284,4 +431,8 @@ int bar(short a, short b, short c, short d){ return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd; } +int tbar2(short a, short b, short c, short d){ + return tbar(a, b, c, d); +} + #endif diff --git a/test/OpenMP/target_codegen_registration.cpp b/test/OpenMP/target_codegen_registration.cpp index 7d515bb64d907..a440faff9158c 100644 --- a/test/OpenMP/target_codegen_registration.cpp +++ b/test/OpenMP/target_codegen_registration.cpp @@ -1,20 +1,20 @@ // Test host codegen. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // Test target codegen - host bc file has to be created first. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK // Check that no target code is emmitted if no omptests flag was provided. // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET @@ -61,45 +61,45 @@ // CHECK-DAG: {{@.+}} = private constant i8 0 // TCHECK-NOT: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-DAG: {{@.+}} = private constant i8 0 // CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4] -// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128] +// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288] // CHECK-NTARGET-NOT: private constant i8 0 // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i -// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:\.omp_offloading\.[0-9a-f]+\.[0-9a-f]+\._Z.+\.l[0-9]+\.c[0-9]+]]\00" +// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" // CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" // CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1 @@ -124,7 +124,7 @@ // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" // CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1 -// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:\.omp_offloading\.[0-9a-f]+\.[0-9a-f]+\._Z.+\.l[0-9]+\.c[0-9]+]]\00" +// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" // TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" // TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1 @@ -407,31 +407,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 11, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 13, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 11, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 13, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}} #endif diff --git a/test/OpenMP/target_codegen_registration_naming.cpp b/test/OpenMP/target_codegen_registration_naming.cpp index ab7a469aba4d0..ce133eee03e80 100644 --- a/test/OpenMP/target_codegen_registration_naming.cpp +++ b/test/OpenMP/target_codegen_registration_naming.cpp @@ -1,20 +1,20 @@ // Test host codegen. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // Test target codegen - host bc file has to be created first. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK // expected-no-diagnostics #ifndef HEADER @@ -24,7 +24,7 @@ // CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}}) int nested(int a){ - // CHECK: call void @.omp_offloading.[[FILEID:[0-9a-f]+\.[0-9a-f]+]].[[NNAME]].l[[T1L:[0-9]+]].c[[T1C:[0-9]+]]( + // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]]( #pragma omp target ++a; @@ -42,25 +42,25 @@ int nested(int a){ return a; } -// CHECK: define {{.*}}void @.omp_offloading.[[FILEID]].[[NNAME]].l[[T1L]].c[[T1C]]( -// TCHECK: define {{.*}}void @.omp_offloading.[[FILEID:[0-9a-f]+\.[0-9a-f]+]].[[NNAME:.+]].l[[T1L:[0-9]+]].c[[T1C:[0-9]+]]( +// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]]( +// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]]( // CHECK: define {{.*}}void @"[[LNAME]]"( // CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to // CHECK: define {{.*}}void [[PNAME]]( -// CHECK: call void @.omp_offloading.[[FILEID]].[[NNAME]].l[[T2L:[0-9]+]].c[[T2C:[0-9]+]]( +// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]]( -// CHECK: define {{.*}}void @.omp_offloading.[[FILEID]].[[NNAME]].l[[T2L]].c[[T2C]]( -// TCHECK: define {{.*}}void @.omp_offloading.[[FILEID]].[[NNAME:.+]].l[[T2L:[0-9]+]].c[[T2C:[0-9]+]]( +// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]]( +// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]]( // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 [[T1C]], i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 [[T2C]], i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 [[T1C]], i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 [[T2C]], i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}} #endif diff --git a/test/OpenMP/target_data_ast_print.cpp b/test/OpenMP/target_data_ast_print.cpp index cdff857e569ad..ed7a96541196f 100644 --- a/test/OpenMP/target_data_ast_print.cpp +++ b/test/OpenMP/target_data_ast_print.cpp @@ -12,13 +12,13 @@ template <typename T, int C> T tmain(T argc, T *argv) { T i, j, b, c, d, e, x[20]; -#pragma omp target data +#pragma omp target data map(to: c) i = argc; -#pragma omp target data if (target data: j > 0) +#pragma omp target data map(to: c) if (target data: j > 0) foo(); -#pragma omp target data if (b) +#pragma omp target data map(to: c) if (b) foo(); #pragma omp target data map(c) @@ -48,11 +48,11 @@ T tmain(T argc, T *argv) { // CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) { // CHECK-NEXT: int i, j, b, c, d, e, x[20]; -// CHECK-NEXT: #pragma omp target data +// CHECK-NEXT: #pragma omp target data map(to: c) // CHECK-NEXT: i = argc; -// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0) // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: #pragma omp target data map(to: c) if(b) // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: c) // CHECK-NEXT: foo(); @@ -70,11 +70,11 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) { // CHECK-NEXT: char i, j, b, c, d, e, x[20]; -// CHECK-NEXT: #pragma omp target data +// CHECK-NEXT: #pragma omp target data map(to: c) // CHECK-NEXT: i = argc; -// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0) // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: #pragma omp target data map(to: c) if(b) // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: c) // CHECK-NEXT: foo(); @@ -92,11 +92,11 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: foo(); // CHECK: template <typename T, int C> T tmain(T argc, T *argv) { // CHECK-NEXT: T i, j, b, c, d, e, x[20]; -// CHECK-NEXT: #pragma omp target data +// CHECK-NEXT: #pragma omp target data map(to: c) // CHECK-NEXT: i = argc; -// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0) // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: #pragma omp target data map(to: c) if(b) // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp target data map(tofrom: c) // CHECK-NEXT: foo(); @@ -118,17 +118,17 @@ int main (int argc, char **argv) { static int a; // CHECK: static int a; -#pragma omp target data -// CHECK: #pragma omp target data +#pragma omp target data map(to: c) +// CHECK: #pragma omp target data map(to: c) a=2; // CHECK-NEXT: a = 2; -#pragma omp target data if (target data: b) -// CHECK: #pragma omp target data if(target data: b) +#pragma omp target data map(to: c) if (target data: b) +// CHECK: #pragma omp target data map(to: c) if(target data: b) foo(); // CHECK-NEXT: foo(); -#pragma omp target data if (b > g) -// CHECK: #pragma omp target data if(b > g) +#pragma omp target data map(to: c) if (b > g) +// CHECK: #pragma omp target data map(to: c) if(b > g) foo(); // CHECK-NEXT: foo(); diff --git a/test/OpenMP/target_data_codegen.cpp b/test/OpenMP/target_data_codegen.cpp new file mode 100644 index 0000000000000..a149ba9332b93 --- /dev/null +++ b/test/OpenMP/target_data_codegen.cpp @@ -0,0 +1,248 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +///==========================================================================/// +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +#ifdef CK1 + +// CK1: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; +}; + +ST<int> gb; +double gc[100]; + +// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800] +// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34] + +// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4] +// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33] + +// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 37] + +// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24] +// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17] + +// CK1-LABEL: _Z3fooi +void foo(int arg) { + int la; + float lb[arg]; + + // Region 00 + // CK1-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]] + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + + // CK1-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]] + #pragma omp target data if(1+3-5) device(arg) map(from: gc) + {++arg;} + + // Region 01 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target data map(la) if(1+3-4) + {++arg;} + + // Region 02 + // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + // CK1: [[IFTHEN]] + // CK1-DAG: call void @__tgt_target_data_begin(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + // CK1: br label %[[IFEND:[^,]+]] + + // CK1: [[IFELSE]] + // CK1: br label %[[IFEND]] + // CK1: [[IFEND]] + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + + // CK1: [[IFTHEN]] + // CK1-DAG: call void @__tgt_target_data_end(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]] + // CK1: br label %[[IFEND:[^,]+]] + // CK1: [[IFELSE]] + // CK1: br label %[[IFEND]] + // CK1: [[IFEND]] + #pragma omp target data map(to: arg) if(arg) device(4) + {++arg;} + + // Region 03 + // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]] + // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8* + // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + + // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]] + // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S]] + #pragma omp target data map(always, to: lb) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 04 + // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]] + + + // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]] + // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8* + // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0 + // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + + // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]] + #pragma omp target data map(to: gb.b[:3]) + {++arg;} +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +#ifdef CK2 + +// CK2: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; + + T foo(T arg) { + // Region 00 + #pragma omp target data map(always, to: b[1:3]) if(a>123) device(arg) + {arg++;} + return arg; + } +}; + +// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24] +// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 37, i32 21] + +// CK2-LABEL: _Z3bari +int bar(int arg){ + ST<int> A; + return A.foo(arg); +} + +// Region 00 +// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] +// CK2: [[IFTHEN]] +// CK2-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}) +// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, +// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* +// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8* +// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + + +// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8* +// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8* +// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1 +// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]], +// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + +// CK2: br label %[[IFEND:[^,]+]] + +// CK2: [[IFELSE]] +// CK2: br label %[[IFEND]] +// CK2: [[IFEND]] +// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 +// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + +// CK2: [[IFTHEN]] +// CK2-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}) +// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, +// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]] +// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]] +// CK2: br label %[[IFEND:[^,]+]] +// CK2: [[IFELSE]] +// CK2: br label %[[IFEND]] +// CK2: [[IFEND]] +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +#ifdef CK3 + +// CK3-LABEL: no_target_devices +void no_target_devices(int arg) { + // CK3-NOT: tgt_target_data_begin + // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK3-NOT: tgt_target_data_end + // CK3: ret + #pragma omp target data map(to: arg) if(arg) device(4) + {++arg;} +} +#endif +#endif diff --git a/test/OpenMP/target_data_device_messages.cpp b/test/OpenMP/target_data_device_messages.cpp index 9e8e31a28f5b6..9ed7a54b4399a 100644 --- a/test/OpenMP/target_data_device_messages.cpp +++ b/test/OpenMP/target_data_device_messages.cpp @@ -10,18 +10,19 @@ bool foobool(int argc) { struct S1; // expected-note {{declared here}} int main(int argc, char **argv) { - #pragma omp target data device // expected-error {{expected '(' after 'device'}} - #pragma omp target data device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data device () // expected-error {{expected expression}} - #pragma omp target data device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} -#pragma omp target data device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} - #pragma omp target data device (argc + argc) - #pragma omp target data device (argc), device (argc+1) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'device' clause}} - #pragma omp target data device (S1) // expected-error {{'S1' does not refer to a value}} - #pragma omp target data device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} - #pragma omp target device (-10u) - #pragma omp target device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + int a; + #pragma omp target data map(to: a) device // expected-error {{expected '(' after 'device'}} + #pragma omp target data map(to: a) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) device () // expected-error {{expected expression}} + #pragma omp target data map(to: a) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} +#pragma omp target data map(to: a) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target data map(to: a) device (argc + argc) + #pragma omp target data map(to: a) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'device' clause}} + #pragma omp target data map(to: a) device (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target data map(to: a) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + #pragma omp target data map(to: a) device (-10u) + #pragma omp target data map(to: a) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} foo(); return 0; diff --git a/test/OpenMP/target_data_if_messages.cpp b/test/OpenMP/target_data_if_messages.cpp index 77edefa48b8a4..ec6fe26921538 100644 --- a/test/OpenMP/target_data_if_messages.cpp +++ b/test/OpenMP/target_data_if_messages.cpp @@ -10,22 +10,23 @@ bool foobool(int argc) { struct S1; // expected-note {{declared here}} int main(int argc, char **argv) { - #pragma omp target data if // expected-error {{expected '(' after 'if'}} - #pragma omp target data if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if () // expected-error {{expected expression}} - #pragma omp target data if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} - #pragma omp target data if (argc > 0 ? argv[1] : argv[2]) - #pragma omp target data if (argc + argc) - #pragma omp target data if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}} - #pragma omp target data if (S1) // expected-error {{'S1' does not refer to a value}} - #pragma omp target data if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target data if(target data : argc) - #pragma omp target data if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}} - #pragma omp target data if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}} - #pragma omp target data if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + int a; + #pragma omp target data map(to: a) if // expected-error {{expected '(' after 'if'}} + #pragma omp target data map(to: a) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if () // expected-error {{expected expression}} + #pragma omp target data map(to: a) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} + #pragma omp target data map(to: a) if (argc > 0 ? argv[1] : argv[2]) + #pragma omp target data map(to: a) if (argc + argc) + #pragma omp target data map(to: a) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}} + #pragma omp target data map(to: a) if (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target data map(to: a) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target data map(to: a) if(target data : argc) + #pragma omp target data map(to: a) if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}} + #pragma omp target data map(to: a) if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}} + #pragma omp target data map(to: a) if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); return 0; diff --git a/test/OpenMP/target_data_messages.c b/test/OpenMP/target_data_messages.c index cd60d85a9030b..153b4377290ca 100644 --- a/test/OpenMP/target_data_messages.c +++ b/test/OpenMP/target_data_messages.c @@ -3,19 +3,22 @@ void foo() { } int main(int argc, char **argv) { + int a; + #pragma omp target data // expected-error {{expected at least one map clause for '#pragma omp target data'}} + {} L1: foo(); - #pragma omp target data + #pragma omp target data map(a) { foo(); goto L1; // expected-error {{use of undeclared label 'L1'}} } goto L2; // expected-error {{use of undeclared label 'L2'}} - #pragma omp target data + #pragma omp target data map(a) L2: foo(); - #pragma omp target data(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} + #pragma omp target data map(a)(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} { foo(); } diff --git a/test/OpenMP/target_data_use_device_ptr_ast_print.cpp b/test/OpenMP/target_data_use_device_ptr_ast_print.cpp new file mode 100644 index 0000000000000..4e3253b2798fd --- /dev/null +++ b/test/OpenMP/target_data_use_device_ptr_ast_print.cpp @@ -0,0 +1,154 @@ +// RxUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct ST { + int *a; +}; +struct SA { + int i, j; + int *k = &j; + int *&z = k; + void func(int arg) { +#pragma omp target data map(tofrom: i) use_device_ptr(k) + {} +#pragma omp target data map(tofrom: i) use_device_ptr(z) + {} + return; + } +}; +// CHECK: struct SA +// CHECK: void func( +// CHECK: #pragma omp target data map(tofrom: this->i) use_device_ptr(this->k) +// CHECK: #pragma omp target data map(tofrom: this->i) use_device_ptr(this->z) +struct SB { + unsigned A; + unsigned B; + float Arr[100]; + float *Ptr; + float *foo() { + return &Arr[0]; + } +}; + +struct SC { + unsigned A : 2; + unsigned B : 3; + unsigned C; + unsigned D; + float Arr[100]; + SB S; + SB ArrS[100]; + SB *PtrS; + SB *&RPtrS; + float *Ptr; + + SC(SB *&_RPtrS) : RPtrS(_RPtrS) {} +}; + +union SD { + unsigned A; + float B; +}; + +struct S1; +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) + +typedef int from; + +template <typename T> +T tmain(T argc) { + T i; + T &j = i; + T *k = &j; + T *&z = k; +#pragma omp target data map(tofrom: i) use_device_ptr(k) + {} +#pragma omp target data map(tofrom: i) use_device_ptr(z) + {} + return 0; +} + +// CHECK: template <typename T = int> int tmain(int argc) { +// CHECK-NEXT: int i; +// CHECK-NEXT: int &j = i; +// CHECK-NEXT: int *k = &j; +// CHECK-NEXT: int *&z = k; +// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(k) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(z) + +// CHECK: template <typename T = int *> int *tmain(int *argc) { +// CHECK-NEXT: int *i; +// CHECK-NEXT: int *&j = i; +// CHECK-NEXT: int **k = &j; +// CHECK-NEXT: int **&z = k; +// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(k) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(z) + +// CHECK-LABEL: int main(int argc, char **argv) { +int main(int argc, char **argv) { + int i; + int &j = i; + int *k = &j; + int *&z = k; +// CHECK-NEXT: int i; +// CHECK-NEXT: int &j = i; +// CHECK-NEXT: int *k = &j; +// CHECK-NEXT: int *&z = k; +#pragma omp target data map(tofrom: i) use_device_ptr(k) +// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(k) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target data map(tofrom: i) use_device_ptr(z) +// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(z) + {} + return tmain<int>(argc) + (*tmain<int*>(&argc)); +} + +#endif diff --git a/test/OpenMP/target_data_use_device_ptr_messages.cpp b/test/OpenMP/target_data_use_device_ptr_messages.cpp new file mode 100644 index 0000000000000..1d8002c1ff603 --- /dev/null +++ b/test/OpenMP/target_data_use_device_ptr_messages.cpp @@ -0,0 +1,206 @@ +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s +struct ST { + int *a; +}; +struct SA { + const int d = 5; + const int da[5] = { 0 }; + ST e; + ST g[10]; + int i; + int &j = i; + int *k = &j; + int *&z = k; + int aa[10]; + void func(int arg) { +#pragma omp target data map(i) use_device_ptr // expected-error {{expected '(' after 'use_device_ptr'}} + {} +#pragma omp target data map(i) use_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} +#pragma omp target data map(i) use_device_ptr() // expected-error {{expected expression}} + {} +#pragma omp target data map(i) use_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} +#pragma omp target data map(i) use_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(i) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(j) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(k) // OK + {} +#pragma omp target data map(i) use_device_ptr(z) // OK + {} +#pragma omp target data map(i) use_device_ptr(aa) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(e) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(g) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(k,i,j) // expected-error2 {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(d) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(da) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} + return; + } +}; +struct SB { + unsigned A; + unsigned B; + float Arr[100]; + float *Ptr; + float *foo() { + return &Arr[0]; + } +}; + +struct SC { + unsigned A : 2; + unsigned B : 3; + unsigned C; + unsigned D; + float Arr[100]; + SB S; + SB ArrS[100]; + SB *PtrS; + SB *&RPtrS; + float *Ptr; + + SC(SB *&_RPtrS) : RPtrS(_RPtrS) {} +}; + +union SD { + unsigned A; + float B; +}; + +struct S1; +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) + +typedef int from; + +template <typename T, int I> +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + T i; + T &j = i; + T *k = &j; + T *&z = k; + T aa[10]; +#pragma omp target data map(i) use_device_ptr // expected-error {{expected '(' after 'use_device_ptr'}} + {} +#pragma omp target data map(i) use_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} +#pragma omp target data map(i) use_device_ptr() // expected-error {{expected expression}} + {} +#pragma omp target data map(i) use_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} +#pragma omp target data map(i) use_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(i) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(j) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(k) // OK + {} +#pragma omp target data map(i) use_device_ptr(z) // OK + {} +#pragma omp target data map(i) use_device_ptr(aa) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(e) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(g) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(k,i,j) // expected-error2 {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(d) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(da) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int *k = &j; + int *&z = k; + int aa[10]; +#pragma omp target data map(i) use_device_ptr // expected-error {{expected '(' after 'use_device_ptr'}} + {} +#pragma omp target data map(i) use_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} +#pragma omp target data map(i) use_device_ptr() // expected-error {{expected expression}} + {} +#pragma omp target data map(i) use_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} +#pragma omp target data map(i) use_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(i) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(j) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(k) // OK + {} +#pragma omp target data map(i) use_device_ptr(z) // OK + {} +#pragma omp target data map(i) use_device_ptr(aa) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(e) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(g) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(k,i,j) // expected-error2 {{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(d) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} +#pragma omp target data map(i) use_device_ptr(da) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}} + {} + return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} +} diff --git a/test/OpenMP/target_defaultmap_messages.cpp b/test/OpenMP/target_defaultmap_messages.cpp new file mode 100644 index 0000000000000..59348d42c5253 --- /dev/null +++ b/test/OpenMP/target_defaultmap_messages.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +template <class T, typename S, int N, int ST> +T tmain(T argc, S **argv) { + #pragma omp target defaultmap // expected-error {{expected '(' after 'defaultmap'}} + foo(); + #pragma omp target defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + foo(); + #pragma omp target defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + foo(); + #pragma omp target defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + #pragma omp target defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target defaultmap // expected-error {{expected '(' after 'defaultmap'}} + foo(); + #pragma omp target defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + foo(); + #pragma omp target defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + foo(); + #pragma omp target defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + #pragma omp target defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_depend_messages.cpp b/test/OpenMP/target_depend_messages.cpp new file mode 100644 index 0000000000000..c13a3edaf699a --- /dev/null +++ b/test/OpenMP/target_depend_messages.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + auto arr = x; // expected-error {{use of undeclared identifier 'x'}} + + #pragma omp target depend // expected-error {{expected '(' after 'depend'}} + foo(); + #pragma omp target depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + foo(); + #pragma omp target depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target depend (out: ) // expected-error {{expected expression}} + foo(); + #pragma omp target depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + foo(); + #pragma omp target depend (out :S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target depend (in : argv[0]) + foo(); + #pragma omp target depend (in : ) // expected-error {{expected expression}} + foo(); + #pragma omp target depend (in : main) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + foo(); + #pragma omp target depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + foo(); + #pragma omp target depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); + #pragma omp target depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + foo(); + #pragma omp target depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + foo(); + #pragma omp target depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + foo(); + #pragma omp target depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + foo(); + #pragma omp target depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); + #pragma omp target depend(in : argv[ : argc][1 : argc - 1]) + foo(); + #pragma omp target depend(in : arr[0]) + foo(); + + return 0; +} diff --git a/test/OpenMP/target_device_messages.cpp b/test/OpenMP/target_device_messages.cpp index fb0f2defa42bc..3befcd690810b 100644 --- a/test/OpenMP/target_device_messages.cpp +++ b/test/OpenMP/target_device_messages.cpp @@ -11,16 +11,27 @@ struct S1; // expected-note {{declared here}} int main(int argc, char **argv) { #pragma omp target device // expected-error {{expected '(' after 'device'}} + foo(); #pragma omp target device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target device () // expected-error {{expected expression}} + foo(); #pragma omp target device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} -#pragma omp target device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + #pragma omp target device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); #pragma omp target device (argc + argc) + foo(); #pragma omp target device (argc), device (argc+1) // expected-error {{directive '#pragma omp target' cannot contain more than one 'device' clause}} + foo(); #pragma omp target device (S1) // expected-error {{'S1' does not refer to a value}} + foo(); #pragma omp target device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + foo(); #pragma omp target device (-10u) + foo(); #pragma omp target device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} foo(); diff --git a/test/OpenMP/target_enter_data_ast_print.cpp b/test/OpenMP/target_enter_data_ast_print.cpp new file mode 100644 index 0000000000000..10ec925284998 --- /dev/null +++ b/test/OpenMP/target_enter_data_ast_print.cpp @@ -0,0 +1,228 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template <typename T, int C> +T tmain(T argc, T *argv) { + T i, j, b, c, d, e, x[20]; + + i = argc; +#pragma omp target enter data map(to: i) + +#pragma omp target enter data map(to: i) if (target enter data: j > 0) + +#pragma omp target enter data map(to: i) if (b) + +#pragma omp target enter data map(to: c) + +#pragma omp target enter data map(to: c) if(b>e) + +#pragma omp target enter data map(alloc: x[0:10], c) + +#pragma omp target enter data map(to: c) map(alloc: d) + +#pragma omp target enter data map(always,alloc: e) + +#pragma omp target enter data nowait map(to: i) + +#pragma omp target enter data nowait map(to: i) if (target enter data: j > 0) + +#pragma omp target enter data map(to: i) if (b) nowait + +#pragma omp target enter data map(to: c) nowait + +#pragma omp target enter data map(to: c) nowait if(b>e) + +#pragma omp target enter data nowait map(alloc: x[0:10], c) + +#pragma omp target enter data nowait map(to: c) map(alloc: d) + +#pragma omp target enter data nowait map(always,alloc: e) + +#pragma omp target enter data nowait depend(in : argc, argv[i:argc], x[:]) map(to: i) + +#pragma omp target enter data nowait map(to: i) if (target enter data: j > 0) depend(in : argc, argv[i:argc], x[:]) + +#pragma omp target enter data depend(in : argc, argv[i:argc], x[:]) map(to: i) if (b) nowait + +#pragma omp target enter data map(to: c) depend(in : argc, argv[i:argc], x[:]) nowait + +#pragma omp target enter data map(to: c) nowait if(b>e) depend(in : argc, argv[i:argc], x[:]) + +#pragma omp target enter data nowait map(alloc: x[0:10], c) depend(in : argc, argv[i:argc], x[:]) + +#pragma omp target enter data nowait depend(in : argc, argv[i:argc], x[:]) map(to: c) map(alloc: d) + +#pragma omp target enter data nowait map(always,alloc: e) depend(in : argc, argv[i:argc], x[:]) + + return 0; +} + +// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) { +// CHECK-NEXT: int i, j, b, c, d, e, x[20]; +// CHECK-NEXT: i = argc; +// CHECK-NEXT: #pragma omp target enter data map(to: i) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(target enter data: j > 0) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) +// CHECK-NEXT: #pragma omp target enter data map(to: c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) if(b > e) +// CHECK-NEXT: #pragma omp target enter data map(alloc: x[0:10],c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) +// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: i) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(to: i) if(b) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:]) +// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) { +// CHECK-NEXT: char i, j, b, c, d, e, x[20]; +// CHECK-NEXT: i = argc; +// CHECK-NEXT: #pragma omp target enter data map(to: i) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(target enter data: j > 0) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) +// CHECK-NEXT: #pragma omp target enter data map(to: c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) if(b > e) +// CHECK-NEXT: #pragma omp target enter data map(alloc: x[0:10],c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) +// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: i) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(to: i) if(b) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:]) +// CHECK: template <typename T, int C> T tmain(T argc, T *argv) { +// CHECK-NEXT: T i, j, b, c, d, e, x[20]; +// CHECK-NEXT: i = argc; +// CHECK-NEXT: #pragma omp target enter data map(to: i) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(target enter data: j > 0) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) +// CHECK-NEXT: #pragma omp target enter data map(to: c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) if(b > e) +// CHECK-NEXT: #pragma omp target enter data map(alloc: x[0:10],c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) +// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) +// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: i) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(to: i) if(b) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:]) + +int main (int argc, char **argv) { + int b = argc, i, c, d, e, f, g, x[20]; + static int a; +// CHECK: static int a; + +#pragma omp target enter data map(to: a) +// CHECK: #pragma omp target enter data map(to: a) + a=2; +// CHECK-NEXT: a = 2; +#pragma omp target enter data map(to: a) if (target enter data: b) +// CHECK: #pragma omp target enter data map(to: a) if(target enter data: b) + +#pragma omp target enter data map(to: a) if (b > g) +// CHECK: #pragma omp target enter data map(to: a) if(b > g) + +#pragma omp target enter data map(to: c) +// CHECK-NEXT: #pragma omp target enter data map(to: c) + +#pragma omp target enter data map(alloc: c) if(b>g) +// CHECK-NEXT: #pragma omp target enter data map(alloc: c) if(b > g) + +#pragma omp target enter data map(to: x[0:10], c) +// CHECK-NEXT: #pragma omp target enter data map(to: x[0:10],c) + +#pragma omp target enter data map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d) + +#pragma omp target enter data map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e) + +#pragma omp target enter data nowait map(to: a) +// CHECK: #pragma omp target enter data nowait map(to: a) + +#pragma omp target enter data nowait map(to: a) if (target enter data: b) +// CHECK: #pragma omp target enter data nowait map(to: a) if(target enter data: b) + +#pragma omp target enter data map(to: a) if (b > g) nowait +// CHECK: #pragma omp target enter data map(to: a) if(b > g) nowait + +#pragma omp target enter data map(to: c) nowait +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait + +#pragma omp target enter data map(alloc: c) nowait if(b>g) +// CHECK-NEXT: #pragma omp target enter data map(alloc: c) nowait if(b > g) + +#pragma omp target enter data nowait map(to: x[0:10], c) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: x[0:10],c) + +#pragma omp target enter data nowait map(to: c) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d) + +#pragma omp target enter data nowait map(always,alloc: e) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) + +#pragma omp target enter data depend(in : argc, argv[i:argc], x[:]) nowait map(to: a) +// CHECK: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) nowait map(to: a) + +#pragma omp target enter data nowait depend(in : argc, argv[i:argc], x[:]) map(to: a) if (target enter data: b) +// CHECK: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: a) if(target enter data: b) + +#pragma omp target enter data map(to: a) depend(in : argc, argv[i:argc], x[:]) if (b > g) nowait +// CHECK: #pragma omp target enter data map(to: a) depend(in : argc,argv[i:argc],x[:]) if(b > g) nowait + +#pragma omp target enter data map(to: c) nowait depend(in : argc, argv[i:argc], x[:]) +// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait depend(in : argc,argv[i:argc],x[:]) + +#pragma omp target enter data depend(in : argc, argv[i:argc], x[:]) map(alloc: c) nowait if(b>g) +// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(alloc: c) nowait if(b > g) + +#pragma omp target enter data nowait map(to: x[0:10], c) depend(in : argc, argv[i:argc], x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) + +#pragma omp target enter data nowait map(to: c) depend(in : argc, argv[i:argc], x[:]) map(alloc: d) +// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) depend(in : argc,argv[i:argc],x[:]) map(alloc: d) + +#pragma omp target enter data nowait map(always,alloc: e) depend(in : argc, argv[i:argc], x[:]) +// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:]) + + return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]); +} + +#endif diff --git a/test/OpenMP/target_enter_data_codegen.cpp b/test/OpenMP/target_enter_data_codegen.cpp new file mode 100644 index 0000000000000..152cd46b4a2ff --- /dev/null +++ b/test/OpenMP/target_enter_data_codegen.cpp @@ -0,0 +1,249 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +///==========================================================================/// +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +#ifdef CK1 + +// CK1: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; +}; + +ST<int> gb; +double gc[100]; + +// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800] +// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 32] + +// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4] +// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33] + +// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 37] + +// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24] +// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17] + +// CK1-LABEL: _Z3fooi +void foo(int arg) { + int la; + float lb[arg]; + + // Region 00 + // CK1-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]] + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1-NOT: __tgt_target_data_end + #pragma omp target enter data if(1+3-5) device(arg) map(alloc: gc) + {++arg;} + + // Region 01 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target enter data map(to: la) if(1+3-4) + {++arg;} + + // Region 02 + // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + // CK1: [[IFTHEN]] + // CK1-DAG: call void @__tgt_target_data_begin(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + // CK1: br label %[[IFEND:[^,]+]] + + // CK1: [[IFELSE]] + // CK1: br label %[[IFEND]] + // CK1: [[IFEND]] + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1-NOT: __tgt_target_data_end + #pragma omp target enter data map(to: arg) if(arg) device(4) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 03 + // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]] + // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8* + // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1-NOT: __tgt_target_data_end + #pragma omp target enter data map(always, to: lb) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 04 + // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]] + + + // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]] + // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8* + // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0 + // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1-NOT: __tgt_target_data_end + #pragma omp target enter data map(to: gb.b[:3]) + {++arg;} +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +#ifdef CK2 + +// CK2: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; + + T foo(T arg) { + // Region 00 + #pragma omp target enter data map(always, to: b[1:3]) if(a>123) device(arg) + {arg++;} + return arg; + } +}; + +// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24] +// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 37, i32 21] + +// CK2-LABEL: _Z3bari +int bar(int arg){ + ST<int> A; + return A.foo(arg); +} + +// Region 00 +// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] +// CK2: [[IFTHEN]] +// CK2-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}) +// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, +// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* +// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8* +// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + + +// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8* +// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8* +// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1 +// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]], +// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + +// CK2: br label %[[IFEND:[^,]+]] + +// CK2: [[IFELSE]] +// CK2: br label %[[IFEND]] +// CK2: [[IFEND]] +// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 +// CK2-NOT: __tgt_target_data_end +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +#ifdef CK3 + +// CK3-LABEL: no_target_devices +void no_target_devices(int arg) { + // CK3-NOT: tgt_target_data_begin + // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK3-NOT: tgt_target_data_end + // CK3: ret + #pragma omp target enter data map(to: arg) if(arg) device(4) + {++arg;} +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 +// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 + +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64 +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32 +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32 +#ifdef CK4 + +// CK4-LABEL: device_side_scan +void device_side_scan(int arg) { + // CK4: tgt_target_data_begin + // CK4: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK4: ret + // TCK4-NOT: tgt_target_data_begin + #pragma omp target enter data map(to: arg) if(arg) device(4) + {++arg;} +} +#endif +#endif diff --git a/test/OpenMP/target_enter_data_depend_messages.cpp b/test/OpenMP/target_enter_data_depend_messages.cpp new file mode 100644 index 0000000000000..84254b5c312a9 --- /dev/null +++ b/test/OpenMP/target_enter_data_depend_messages.cpp @@ -0,0 +1,166 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +template <class T, class S, class R> +int tmain(T argc, S **argv, R *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + char *arr; + + int i; + #pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}} + foo(); + #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + foo(); + #pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + foo(); + #pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}} + foo(); + #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + foo(); + #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[0]) + foo(); + #pragma omp target enter data map(to: i) depend (in : ) // expected-error {{expected expression}} + foo(); + #pragma omp target enter data map(to: i) depend (in : tmain) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + foo(); + #pragma omp target enter data map(to: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + foo(); + #pragma omp target enter data map(to: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + foo(); + #pragma omp target enter data map(to: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target enter data map(to: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); + #pragma omp target enter data map(to: i) depend(in : argv[ : argc][1 : argc - 1]) + foo(); + #pragma omp target enter data map(to: i) depend(in : arr[0]) + foo(); + + return 0; +} + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + char *arr; + + int i; + #pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}} + foo(); + #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + foo(); + #pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + foo(); + #pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}} + foo(); + #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + foo(); + #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[0]) + foo(); + #pragma omp target enter data map(to: i) depend (in : ) // expected-error {{expected expression}} + foo(); + #pragma omp target enter data map(to: i) depend (in : main) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + foo(); + #pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target enter data map(to: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + foo(); + #pragma omp target enter data map(to: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + foo(); + #pragma omp target enter data map(to: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + foo(); + #pragma omp target enter data map(to: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target enter data map(to: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); + #pragma omp target enter data map(to: i) depend(in : argv[ : argc][1 : argc - 1]) + foo(); + #pragma omp target enter data map(to: i) depend(in : arr[0]) + foo(); + + return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain<int, char, char>' requested here}} +} diff --git a/test/OpenMP/target_enter_data_device_messages.cpp b/test/OpenMP/target_enter_data_device_messages.cpp new file mode 100644 index 0000000000000..d954eca319dd2 --- /dev/null +++ b/test/OpenMP/target_enter_data_device_messages.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + int i; + #pragma omp target enter data map(to: i) device // expected-error {{expected '(' after 'device'}} + #pragma omp target enter data map(to: i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) device () // expected-error {{expected expression}} + #pragma omp target enter data map(to: i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} +#pragma omp target enter data map(to: i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target enter data map(to: i) device (argc + argc) + #pragma omp target enter data map(to: i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'device' clause}} + #pragma omp target enter data map(to: i) device (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target enter data map(to: i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + #pragma omp target enter data map(to: i) device (-10u) + #pragma omp target enter data map(to: i) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_enter_data_if_messages.cpp b/test/OpenMP/target_enter_data_if_messages.cpp new file mode 100644 index 0000000000000..0d18af187b19e --- /dev/null +++ b/test/OpenMP/target_enter_data_if_messages.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + int i; + #pragma omp target enter data map(to: i) if // expected-error {{expected '(' after 'if'}} + #pragma omp target enter data map(to: i) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) if () // expected-error {{expected expression}} + #pragma omp target enter data map(to: i) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + #pragma omp target enter data map(to: i) if (argc > 0 ? argv[1] : argv[2]) + #pragma omp target enter data map(to: i) if (argc + argc) + #pragma omp target enter data map(to: i) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'if' clause}} + #pragma omp target enter data map(to: i) if (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target enter data map(to: i) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) if(target data : true) // expected-error {{directive name modifier 'target data' is not allowed for '#pragma omp target enter data'}} + #pragma omp target enter data map(to: i) if(target enter data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) if(target enter data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) if(target enter data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target enter data map(to: i) if(target enter data : argc) + #pragma omp target enter data map(to: i) if(target enter data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target enter data'}} + #pragma omp target enter data map(to: i) if(target enter data : argc) if (target enter data:argc) // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'if' clause with 'target enter data' name modifier}} + #pragma omp target enter data map(to: i) if(target enter data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_enter_data_map_messages.c b/test/OpenMP/target_enter_data_map_messages.c new file mode 100644 index 0000000000000..6f5aad1ef6504 --- /dev/null +++ b/test/OpenMP/target_enter_data_map_messages.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - -x c++ %s + +int main(int argc, char **argv) { + + int r; + #pragma omp target enter data // expected-error {{expected at least one map clause for '#pragma omp target enter data'}} + + #pragma omp target enter data map(r) // expected-error {{map type must be specified for '#pragma omp target enter data'}} + #pragma omp target enter data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target enter data'}} + + #pragma omp target enter data map(always, to: r) + #pragma omp target enter data map(always, alloc: r) + #pragma omp target enter data map(always, from: r) // expected-error {{map type 'from' is not allowed for '#pragma omp target enter data'}} + #pragma omp target enter data map(release: r) // expected-error {{map type 'release' is not allowed for '#pragma omp target enter data'}} + #pragma omp target enter data map(delete: r) // expected-error {{map type 'delete' is not allowed for '#pragma omp target enter data'}} + + return 0; +} diff --git a/test/OpenMP/target_enter_data_nowait_messages.cpp b/test/OpenMP/target_enter_data_nowait_messages.cpp new file mode 100644 index 0000000000000..e682e8c47d703 --- /dev/null +++ b/test/OpenMP/target_enter_data_nowait_messages.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +int main(int argc, char **argv) { + int i; + + #pragma omp nowait target enter data map(to: i) // expected-error {{expected an OpenMP directive}} + #pragma omp target nowait enter data map(to: i) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + #pragma omp target enter nowait data map(to: i) // expected-error {{expected an OpenMP directive}} + #pragma omp target enter data nowait() map(to: i) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} expected-error {{expected at least one map clause for '#pragma omp target enter data'}} + #pragma omp target enter data map(to: i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + #pragma omp target enter data map(to: i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + #pragma omp target enter data map(to: i) nowait device (-10u) + #pragma omp target enter data map(to: i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} + #pragma omp target enter data map(to: i) nowait nowait // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}} + #pragma omp target enter data nowait map(to: i) nowait // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}} + return 0; +} diff --git a/test/OpenMP/target_exit_data_ast_print.cpp b/test/OpenMP/target_exit_data_ast_print.cpp new file mode 100644 index 0000000000000..e2c6d7fd65ceb --- /dev/null +++ b/test/OpenMP/target_exit_data_ast_print.cpp @@ -0,0 +1,244 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template <typename T, int C> +T tmain(T argc, T *argv) { + T i, j, b, c, d, e, x[20]; + + i = argc; +#pragma omp target exit data map(from: i) + +#pragma omp target exit data map(from: i) if (target exit data: j > 0) + +#pragma omp target exit data map(from: i) if (b) + +#pragma omp target exit data map(from: c) + +#pragma omp target exit data map(from: c) if(b>e) + +#pragma omp target exit data map(release: x[0:10], c) + +#pragma omp target exit data map(delete: x[0:10]) + +#pragma omp target exit data map(always, delete: x[0:10]) + +#pragma omp target exit data map(from: c) map(release: d) + +#pragma omp target exit data map(always,release: e) + +#pragma omp target exit data nowait map(from: i) + +#pragma omp target exit data nowait map(from: i) if (target exit data: j > 0) + +#pragma omp target exit data map(from: i) if (b) nowait + +#pragma omp target exit data map(from: c) nowait + +#pragma omp target exit data map(from: c) nowait if(b>e) + +#pragma omp target exit data nowait map(release: x[0:10], c) + +#pragma omp target exit data nowait map(from: c) map(release: d) + +#pragma omp target exit data nowait map(always,release: e) + +#pragma omp target exit data depend(in : argc, argv[i:argc], x[:]) nowait map(from: i) + +#pragma omp target exit data nowait depend(in : argc, argv[i:argc], x[:]) map(from: i) if (target exit data: j > 0) + +#pragma omp target exit data map(from: i) depend(in : argc, argv[i:argc], x[:]) if (b) nowait + +#pragma omp target exit data map(from: c) depend(in : argc, argv[i:argc], x[:]) nowait + +#pragma omp target exit data map(from: c) depend(in : argc, argv[i:argc], x[:]) nowait if(b>e) + +#pragma omp target exit data nowait map(release: x[0:10], c) depend(in : argc, argv[i:argc], x[:]) + +#pragma omp target exit data nowait map(from: c) depend(in : argc, argv[i:argc], x[:]) map(release: d) + +#pragma omp target exit data depend(in : argc, argv[i:argc], x[:]) nowait map(always,release: e) + + return 0; +} + +// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) { +// CHECK-NEXT: int i, j, b, c, d, e, x[20]; +// CHECK-NEXT: i = argc; +// CHECK-NEXT: #pragma omp target exit data map(from: i) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) +// CHECK-NEXT: #pragma omp target exit data map(from: c) +// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e) +// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c) +// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait if(b > e) +// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(from: i) +// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) depend(in : argc,argv[i:argc],x[:]) if(b) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait if(b > e) +// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(always,release: e) +// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) { +// CHECK-NEXT: char i, j, b, c, d, e, x[20]; +// CHECK-NEXT: i = argc; +// CHECK-NEXT: #pragma omp target exit data map(from: i) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) +// CHECK-NEXT: #pragma omp target exit data map(from: c) +// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e) +// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c) +// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait if(b > e) +// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(from: i) +// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) depend(in : argc,argv[i:argc],x[:]) if(b) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait if(b > e) +// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(always,release: e) +// CHECK: template <typename T, int C> T tmain(T argc, T *argv) { +// CHECK-NEXT: T i, j, b, c, d, e, x[20]; +// CHECK-NEXT: i = argc; +// CHECK-NEXT: #pragma omp target exit data map(from: i) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) +// CHECK-NEXT: #pragma omp target exit data map(from: c) +// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e) +// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c) +// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait if(b > e) +// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(from: i) +// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: i) if(target exit data: j > 0) +// CHECK-NEXT: #pragma omp target exit data map(from: i) depend(in : argc,argv[i:argc],x[:]) if(b) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait if(b > e) +// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(always,release: e) + +int main (int argc, char **argv) { + int b = argc, i, c, d, e, f, g, x[20]; + static int a; +// CHECK: static int a; + +#pragma omp target exit data map(from: a) +// CHECK: #pragma omp target exit data map(from: a) + a=2; +// CHECK-NEXT: a = 2; +#pragma omp target exit data map(from: a) if (target exit data: b) +// CHECK: #pragma omp target exit data map(from: a) if(target exit data: b) + +#pragma omp target exit data map(from: a) if (b > g) +// CHECK: #pragma omp target exit data map(from: a) if(b > g) + +#pragma omp target exit data map(from: c) +// CHECK-NEXT: #pragma omp target exit data map(from: c) + +#pragma omp target exit data map(release: c) if(b>g) +// CHECK-NEXT: #pragma omp target exit data map(release: c) if(b > g) + +#pragma omp target exit data map(from: x[0:10], c) +// CHECK-NEXT: #pragma omp target exit data map(from: x[0:10],c) + +#pragma omp target exit data map(delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10]) + +#pragma omp target exit data map(always, delete: x[0:10]) +// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10]) + +#pragma omp target exit data map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d) + +#pragma omp target exit data map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data map(always,release: e) + +#pragma omp target exit data nowait map(from: a) +// CHECK: #pragma omp target exit data nowait map(from: a) + +#pragma omp target exit data nowait map(from: a) if (target exit data: b) +// CHECK: #pragma omp target exit data nowait map(from: a) if(target exit data: b) + +#pragma omp target exit data map(from: a) if (b > g) nowait +// CHECK: #pragma omp target exit data map(from: a) if(b > g) nowait + +#pragma omp target exit data map(from: c) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait + +#pragma omp target exit data map(release: c) nowait if(b>g) +// CHECK-NEXT: #pragma omp target exit data map(release: c) nowait if(b > g) + +#pragma omp target exit data nowait map(from: x[0:10], c) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: x[0:10],c) + +#pragma omp target exit data nowait map(from: c) map(release: d) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d) + +#pragma omp target exit data nowait map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e) + +#pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: a) +// CHECK: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: a) + +#pragma omp target exit data nowait map(from: a) depend(in : argc,argv[i:argc],x[:]) if (target exit data: b) +// CHECK: #pragma omp target exit data nowait map(from: a) depend(in : argc,argv[i:argc],x[:]) if(target exit data: b) + +#pragma omp target exit data map(from: a) if (b > g) nowait depend(in : argc,argv[i:argc],x[:]) +// CHECK: #pragma omp target exit data map(from: a) if(b > g) nowait depend(in : argc,argv[i:argc],x[:]) + +#pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait +// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait + +#pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) map(release: c) nowait if(b>g) +// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) map(release: c) nowait if(b > g) + +#pragma omp target exit data nowait map(from: x[0:10], c) depend(in : argc,argv[i:argc],x[:]) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: x[0:10],c) depend(in : argc,argv[i:argc],x[:]) + +#pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d) +// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d) + +#pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(always,release: e) +// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(always,release: e) + + return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]); +} + +#endif diff --git a/test/OpenMP/target_exit_data_codegen.cpp b/test/OpenMP/target_exit_data_codegen.cpp new file mode 100644 index 0000000000000..d3a38592a6103 --- /dev/null +++ b/test/OpenMP/target_exit_data_codegen.cpp @@ -0,0 +1,221 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +///==========================================================================/// +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +#ifdef CK1 + +// CK1: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; +}; + +ST<int> gb; +double gc[100]; + +// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800] +// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34] + +// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4] +// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 32] + +// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 38] + +// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24] +// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 32, i32 16] + +// CK1-LABEL: _Z3fooi +void foo(int arg) { + int la; + float lb[arg]; + + // Region 00 + // CK1-NOT: __tgt_target_data_begin + // CK1-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]] + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target exit data if(1+3-5) device(arg) map(from: gc) + {++arg;} + + // Region 01 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target exit data map(release: la) if(1+3-4) + {++arg;} + + // Region 02 + // CK1-NOT: __tgt_target_data_begin + // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + // CK1: [[IFTHEN]] + // CK1-DAG: call void @__tgt_target_data_end(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + // CK1: br label %[[IFEND:[^,]+]] + + // CK1: [[IFELSE]] + // CK1: br label %[[IFEND]] + // CK1: [[IFEND]] + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target exit data map(release: arg) if(arg) device(4) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 03 + // CK1-NOT: __tgt_target_data_begin + // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]] + // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8* + // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target exit data map(always, from: lb) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 04 + // CK1-NOT: __tgt_target_data_begin + // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]] + + + // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]] + // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8* + // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0 + // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target exit data map(release: gb.b[:3]) + {++arg;} +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +#ifdef CK2 + +// CK2: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; + + T foo(T arg) { + // Region 00 + #pragma omp target exit data map(always, release: b[1:3]) if(a>123) device(arg) + {arg++;} + return arg; + } +}; + +// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24] +// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 36, i32 20] + +// CK2-LABEL: _Z3bari +int bar(int arg){ + ST<int> A; + return A.foo(arg); +} + +// Region 00 +// CK2-NOT: __tgt_target_data_begin +// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] +// CK2: [[IFTHEN]] +// CK2-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}) +// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, +// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* +// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8* +// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + + +// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8* +// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8* +// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1 +// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]], +// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + +// CK2: br label %[[IFEND:[^,]+]] + +// CK2: [[IFELSE]] +// CK2: br label %[[IFEND]] +// CK2: [[IFEND]] +// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +#ifdef CK3 + +// CK3-LABEL: no_target_devices +void no_target_devices(int arg) { + // CK3-NOT: tgt_target_data_begin + // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK3-NOT: tgt_target_data_end + // CK3: ret + #pragma omp target exit data map(from: arg) if(arg) device(4) + {++arg;} +} +#endif +#endif diff --git a/test/OpenMP/target_exit_data_depend_messages.cpp b/test/OpenMP/target_exit_data_depend_messages.cpp new file mode 100644 index 0000000000000..4c59b6205f188 --- /dev/null +++ b/test/OpenMP/target_exit_data_depend_messages.cpp @@ -0,0 +1,166 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +template <class T, class S, class R> +int tmain(T argc, S **argv, R *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + char *arr; + + int i; + #pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}} + foo(); + #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + foo(); + #pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + foo(); + #pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}} + foo(); + #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + foo(); + #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[0]) + foo(); + #pragma omp target exit data map(from: i) depend (in : ) // expected-error {{expected expression}} + foo(); + #pragma omp target exit data map(from: i) depend (in : tmain) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + foo(); + #pragma omp target exit data map(from: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + foo(); + #pragma omp target exit data map(from: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + foo(); + #pragma omp target exit data map(from: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target exit data map(from: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); + #pragma omp target exit data map(from: i) depend(in : argv[ : argc][1 : argc - 1]) + foo(); + #pragma omp target exit data map(from: i) depend(in : arr[0]) + foo(); + + return 0; +} + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + char *arr; + + int i; + #pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}} + foo(); + #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + foo(); + #pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + foo(); + #pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}} + foo(); + #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + foo(); + #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[0]) + foo(); + #pragma omp target exit data map(from: i) depend (in : ) // expected-error {{expected expression}} + foo(); + #pragma omp target exit data map(from: i) depend (in : main) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + foo(); + #pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target exit data map(from: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + foo(); + #pragma omp target exit data map(from: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + foo(); + #pragma omp target exit data map(from: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + foo(); + #pragma omp target exit data map(from: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target exit data map(from: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); + #pragma omp target exit data map(from: i) depend(in : argv[ : argc][1 : argc - 1]) + foo(); + #pragma omp target exit data map(from: i) depend(in : arr[0]) + foo(); + + return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain<int, char, char>' requested here}} +} diff --git a/test/OpenMP/target_exit_data_device_messages.cpp b/test/OpenMP/target_exit_data_device_messages.cpp new file mode 100644 index 0000000000000..d9ce0ddd7ea00 --- /dev/null +++ b/test/OpenMP/target_exit_data_device_messages.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + int i; + #pragma omp target exit data map(from: i) device // expected-error {{expected '(' after 'device'}} + #pragma omp target exit data map(from: i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) device () // expected-error {{expected expression}} + #pragma omp target exit data map(from: i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} +#pragma omp target exit data map(from: i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target exit data map(from: i) device (argc + argc) + #pragma omp target exit data map(from: i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'device' clause}} + #pragma omp target exit data map(from: i) device (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target exit data map(from: i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + #pragma omp target exit data map(from: i) device (-10u) + #pragma omp target exit data map(from: i) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_exit_data_if_messages.cpp b/test/OpenMP/target_exit_data_if_messages.cpp new file mode 100644 index 0000000000000..cc674e6933cc3 --- /dev/null +++ b/test/OpenMP/target_exit_data_if_messages.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + int i; + #pragma omp target exit data map(from: i) if // expected-error {{expected '(' after 'if'}} + #pragma omp target exit data map(from: i) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) if () // expected-error {{expected expression}} + #pragma omp target exit data map(from: i) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + #pragma omp target exit data map(from: i) if (argc > 0 ? argv[1] : argv[2]) + #pragma omp target exit data map(from: i) if (argc + argc) + #pragma omp target exit data map(from: i) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'if' clause}} + #pragma omp target exit data map(from: i) if (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target exit data map(from: i) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) if(target data : true) // expected-error {{directive name modifier 'target data' is not allowed for '#pragma omp target exit data'}} + #pragma omp target exit data map(from: i) if(target exit data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) if(target exit data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) if(target exit data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target exit data map(from: i) if(target exit data : argc) + #pragma omp target exit data map(from: i) if(target exit data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target exit data'}} + #pragma omp target exit data map(from: i) if(target exit data : argc) if (target exit data:argc) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'if' clause with 'target exit data' name modifier}} + #pragma omp target exit data map(from: i) if(target exit data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_exit_data_map_messages.c b/test/OpenMP/target_exit_data_map_messages.c new file mode 100644 index 0000000000000..a9953fbbb4c6f --- /dev/null +++ b/test/OpenMP/target_exit_data_map_messages.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - -x c++ %s + +int main(int argc, char **argv) { + + int r; + #pragma omp target exit data // expected-error {{expected at least one map clause for '#pragma omp target exit data'}} + + #pragma omp target exit data map(r) // expected-error {{map type must be specified for '#pragma omp target exit data'}} + #pragma omp target exit data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target exit data'}} + + #pragma omp target exit data map(always, from: r) + #pragma omp target exit data map(delete: r) + #pragma omp target exit data map(release: r) + #pragma omp target exit data map(always, alloc: r) // expected-error {{map type 'alloc' is not allowed for '#pragma omp target exit data'}} + #pragma omp target exit data map(to: r) // expected-error {{map type 'to' is not allowed for '#pragma omp target exit data'}} + + return 0; +} diff --git a/test/OpenMP/target_exit_data_nowait_messages.cpp b/test/OpenMP/target_exit_data_nowait_messages.cpp new file mode 100644 index 0000000000000..cd743d89278ef --- /dev/null +++ b/test/OpenMP/target_exit_data_nowait_messages.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +int main(int argc, char **argv) { + int i; + + #pragma omp nowait target exit data map(from: i) // expected-error {{expected an OpenMP directive}} + #pragma omp target nowait exit data map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + #pragma omp target exit nowait data map(from: i) // expected-error {{expected an OpenMP directive}} + #pragma omp target exit data nowait() map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} expected-error {{expected at least one map clause for '#pragma omp target exit data'}} + #pragma omp target exit data map(from: i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + #pragma omp target exit data map(from: i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + #pragma omp target exit data map(from: i) nowait device (-10u) + #pragma omp target exit data map(from: i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} + #pragma omp target exit data map(from: i) nowait nowait // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'nowait' clause}} + #pragma omp target exit data nowait map(from: i) nowait // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'nowait' clause}} + return 0; +} diff --git a/test/OpenMP/target_firstprivate_codegen.cpp b/test/OpenMP/target_firstprivate_codegen.cpp new file mode 100644 index 0000000000000..ca459e02a4256 --- /dev/null +++ b/test/OpenMP/target_firstprivate_codegen.cpp @@ -0,0 +1,580 @@ +// Test host codegen. +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 + +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 + +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +template<typename tx, typename ty> +struct TT{ + tx X; + ty Y; +}; + +// CHECK: [[TT:%.+]] = type { i64, i8 } +// CHECK: [[S1:%.+]] = type { double } + +// TCHECK: [[TT:%.+]] = type { i64, i8 } +// TCHECK: [[S1:%.+]] = type { double } + +// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 4] +// CHECK: [[MAPT:@.+]] = private unnamed_addr constant [1 x i32] [i32 288] +// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 161, i32 288, i32 161, i32 161, i32 288, i32 288, i32 161, i32 161] +// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] zeroinitializer +// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [1 x i32] [i32 32] +// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 161] +// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 1, i[[SZ]] 40] +// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 161] +// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [2 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 40] +// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 161] + + +// CHECK: define {{.*}}[[FOO:@.+]]( +int foo(int n, double *ptr) { + int a = 0; + short aa = 0; + float b[10]; + float bn[n]; + double c[5][10]; + double cn[5][n]; + TT<long long, char> d; + + #pragma omp target firstprivate(a) + { + } + + // a is passed by value to tgt_target + // CHECK: [[N_ADDR:%.+]] = alloca i{{[0-9]+}}, + // CHECK: [[PTR_ADDR:%.+]] = alloca double*, + // CHECK: [[A:%.+]] = alloca i{{[0-9]+}}, + // CHECK: [[A2:%.+]] = alloca i{{[0-9]+}}, + // CHECK: [[B:%.+]] = alloca [10 x float], + // CHECK: [[SSTACK:%.+]] = alloca i8*, + // CHECK: [[C:%.+]] = alloca [5 x [10 x double]], + // CHECK: [[D:%.+]] = alloca [[TT]], + // CHECK: [[ACAST:%.+]] = alloca i{{[0-9]+}}, + // CHECK: {{.+}} = alloca i{{[0-9]+}}, + // CHECK: [[BASE_PTR_ARR:%.+]] = alloca [1 x i8*], + // CHECK: [[PTR_ARR:%.+]] = alloca [1 x i8*], + // CHECK: [[A2CAST:%.+]] = alloca i{{[0-9]+}}, + // CHECK: [[BASE_PTR_ARR2:%.+]] = alloca [9 x i8*], + // CHECK: [[PTR_ARR2:%.+]] = alloca [9 x i8*], + // CHECK: [[SIZET2:%.+]] = alloca [9 x i{{[0-9]+}}], + // CHECK: [[BASE_PTR_ARR3:%.+]] = alloca [1 x i8*], + // CHECK: [[PTR_ARR3:%.+]] = alloca [1 x i8*], + // CHECK: [[N_ADDR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[N_ADDR]], + // CHECK-64: [[N_EXT:%.+]] = zext i{{[0-9]+}} [[N_ADDR_VAL]] to i{{[0-9]+}} + // CHECK: [[SSAVE_RET:%.+]] = call i8* @llvm.stacksave() + // CHECK: store i8* [[SSAVE_RET]], i8** [[SSTACK]], + // CHECK-64: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_EXT]], + // CHECK-32: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_ADDR_VAL]], + // CHECK: [[N_ADDR_VAL2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[N_ADDR]], + // CHECK-64: [[N_EXT2:%.+]] = zext i{{[0-9]+}} [[N_ADDR_VAL2]] to i{{[0-9]+}} + // CHECK-64: [[CN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_EXT2]] + // CHECK-32: [[CN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_ADDR_VAL2]] + // CHECK: [[CN_VLA:%.+]] = alloca double, i{{[0-9]+}} [[CN_SIZE]], + // CHECK: [[AVAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A]], + // CHECK-64: [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ACAST]] to i{{[0-9]+}}* + // CHECK-64: store i{{[0-9]+}} [[AVAL]], i{{[0-9]+}}* [[CONV]], + // CHECK-32: store i{{[0-9]+}} [[AVAL]], i{{[0-9]+}}* [[ACAST]], + // CHECK: [[ACAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ACAST]], + // CHECK: [[ACAST_TOPTR:%.+]] = inttoptr i{{[0-9]+}} [[ACAST_VAL]] to i8* + // CHECK: [[BASE_PTR_GEP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[ACAST_TOPTR]], i8** [[BASE_PTR_GEP]], + // CHECK: [[ACAST_TOPTR2:%.+]] = inttoptr i{{[0-9]+}} [[ACAST_VAL]] to i8* + // CHECK: [[PTR_GEP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[ACAST_TOPTR2]], i8** [[PTR_GEP]], + // CHECK: [[BASE_PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: [[PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG]], i8** [[PTR_GEP_ARG]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT]], i32 0, i32 0)) + + // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]]) + // TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK-NOT: alloca i{{[0-9]+}}, + // TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]], + // TCHECK-NOT: store i{{[0-9]+}} % + // TCHECK: ret void + +#pragma omp target firstprivate(aa,b,bn,c,cn,d) + { + aa += 1; + b[2] = 1.0; + bn[3] = 1.0; + c[1][2] = 1.0; + cn[1][3] = 1.0; + d.X = 1; + d.Y = 1; + } + + // CHECK: [[A2VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A2]], + // CHECK: [[A2CASTCONV:%.+]] = bitcast i{{[0-9]+}}* [[A2CAST]] to i{{[0-9]+}}* + // CHECK: store i{{[0-9]+}} [[A2VAL]], i{{[0-9]+}}* [[A2CASTCONV]], + // CHECK: [[A2CAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A2CAST]], + // CHECK-64: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_EXT]], 4 + // CHECK-32: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_ADDR_VAL]], 4 + // CHECK-64: [[CN_SIZE_1:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_EXT2]] + // CHECK-32: [[CN_SIZE_1:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_ADDR_VAL2]] + // CHECK: [[CN_SIZE_2:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SIZE_1]], 8 + + // firstprivate(aa) --> base_ptr = aa, ptr = aa, size = 2 (short) + // CHECK: [[A2CAST_TO_INT:%.+]] = inttoptr i{{[0-9]+}} [[A2CAST_VAL]] to i8* + // CHECK: [[BASE_PTR_GEP2_0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[A2CAST_TO_INT]], i8** [[BASE_PTR_GEP2_0]], + // CHECK: [[A2CAST_TO_INT_2:%.+]] = inttoptr i{{[0-9]+}} [[A2CAST_VAL]] to i8* + // CHECK: [[PTR_GEP2_0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[A2CAST_TO_INT_2]], i8** [[PTR_GEP2_0]], + // CHECK: [[SIZE_GEPA2:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIZE_GEPA2]], + + // firstprivate(b): base_ptr = &b[0], ptr = &b[0], size = 40 (sizeof(float)*10) + // CHECK: [[BCAST:%.+]] = bitcast [10 x float]* [[B]] to i8* + // CHECK: [[BASE_PTR_GEP2_1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i8* [[BCAST]], i8** [[BASE_PTR_GEP2_1]], + // CHECK: [[BCAST2:%.+]] = bitcast [10 x float]* [[B]] to i8* + // CHECK: [[PTR_GEP2_1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i8* [[BCAST2]], i8** [[PTR_GEP2_1]], + // CHECK: [[SIZE_GEPB:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i{{[0-9]+}} 40, i{{[0-9]+}}* [[SIZE_GEPB]], + + // firstprivate(bn), 2 entries, n and bn: (1) base_ptr = n, ptr = n, size = 8 ; (2) base_ptr = &c[0], ptr = &c[0], size = n*sizeof(float) + // CHECK-64: [[N_EXT3_1:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT]] to i8* + // CHECK-32: [[N_EXT3_1:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL]] to i8* + // CHECK: [[BASE_PTR_GEP2_2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i8* [[N_EXT3_1]], i8** [[BASE_PTR_GEP2_2]], + // CHECK-64: [[N_EXT3_2:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT]] to i8* + // CHECK-32: [[N_EXT3_2:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL]] to i8* + // CHECK: [[PTR_GEP2_2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i8* [[N_EXT3_2]], i8** [[PTR_GEP2_2]], + // CHECK: [[SIZE_GEPBN_1:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i{{[0-9]+}} {{[0-9]}}, i{{[0-9]+}}* [[SIZE_GEPBN_1]], + // CHECK: [[VLABN_BCAST:%.+]] = bitcast float* [[BN_VLA]] to i8* + // CHECK: [[BASE_PTR_GEP2_3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // CHECK: store i8* [[VLABN_BCAST]], i8** [[BASE_PTR_GEP2_3]], + // CHECK: [[SIZE_GEPBN_3:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // CHECK: store i{{[0-9]+}} [[BN_SIZE]], i{{[0-9]+}}* [[SIZE_GEPBN_3]] + + // firstprivate(c): base_ptr = &c[0], ptr = &c[0], size = 400 (5*10*sizeof(double)) + // CHECK: [[C_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C]] to i8* + // CHECK: [[BASE_PTR_GEP2_4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 + // CHECK: store i8* [[C_BCAST]], i8** [[BASE_PTR_GEP2_4]], + // CHECK: [[C_BCAST2:%.+]] = bitcast [5 x [10 x double]]* [[C]] to i8* + // CHECK: [[PTR_GEP2_4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 + // CHECK: store i8* [[C_BCAST2]], i8** [[PTR_GEP2_4]], + // CHECK: [[SIZE_GEPC_4:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 + // CHECK: store i{{[0-9]+}} 400, i{{[0-9]+}}* [[SIZE_GEPC_4]], + + // firstprivate(cn), 3 entries, 5, n, cn: (1) base_ptr = 5, ptr = 5, size = 8; (2) (1) base_ptr = n, ptr = n, size = 8; (3) base_ptr = &cn[0], ptr = &cn[0], size = 5*n*sizeof(double) + // CHECK: [[BASE_PTR_GEP2_5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5 + // CHECK: store i8* inttoptr (i{{[0-9]+}} 5 to i8*), i8** [[BASE_PTR_GEP2_5]], + // CHECK: [[PTR_GEP2_5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5 + // CHECK: store i8* inttoptr (i{{[0-9]+}} 5 to i8*), i8** [[PTR_GEP2_5]], + // CHECK: [[SIZE_GEPCN_5:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5 + // CHECK: store i{{[0-9]+}} {{[0-9]}}, i{{[0-9]+}}* [[SIZE_GEPCN_5]], + // CHECK-64: [[CN_SZ_2_1:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT2]] to i8* + // CHECK-32: [[CN_SZ_2_1:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL2]] to i8* + // CHECK: [[BASE_PTR_GEP2_6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 6 + // CHECK: store i8* [[CN_SZ_2_1]], i8** [[BASE_PTR_GEP2_6]], + // CHECK-64: [[CN_SZ_2_2:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT2]] to i8* + // CHECK-32: [[CN_SZ_2_2:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL2]] to i8* + // CHECK: [[PTR_GEP2_6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 6 + // CHECK: store i8* [[CN_SZ_2_2]], i8** [[PTR_GEP2_6]], + // CHECK: [[SIZE_GEPCN_6:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 6 + // CHECK: store i{{[0-9]+}} {{[0-9]}}, i{{[0-9]+}}* [[SIZE_GEPCN_6]], + // CHECK: [[VLA_CN_BCAST:%.+]] = bitcast double* [[CN_VLA]] to i8* + // CHECK: [[BASE_PTR_GEP2_7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7 + // CHECK: store i8* [[VLA_CN_BCAST]], i8** [[BASE_PTR_GEP2_7]], + // CHECK: [[VLA_CN_BCAST2:%.+]] = bitcast double* [[CN_VLA]] to i8* + // CHECK: [[PTR_GEP2_7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7 + // CHECK: store i8* [[VLA_CN_BCAST2]], i8** [[PTR_GEP2_7]], + // CHECK: [[SIZE_GEPCN_7:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7 + // CHECK: store i{{[0-9]+}} [[CN_SIZE_2]], i{{[0-9]+}}* [[SIZE_GEPCN_7]], + + // firstprivate(d): base_ptr = &d, ptr = &d, size = 16 + // CHECK: [[D_REF:%.+]] = bitcast [[TT]]* [[D]] to i8* + // CHECK: [[BASE_PTR_GEP2_8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8 + // CHECK: store i8* [[D_REF]], i8** [[BASE_PTR_GEP2_8]], + // CHECK: [[D_REF2:%.+]] = bitcast [[TT]]* [[D]] to i8* + // CHECK: [[PTR_GEP2_8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8 + // CHECK: store i8* [[D_REF2]], i8** [[PTR_GEP2_8]], + // CHECK: [[SIZE_GEPCN_8:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8 + // CHECK: store i{{[0-9]+}} {{[0-9]+}}, i{{[0-9]+}}* [[SIZE_GEPCN_8]], + + + // CHECK: [[BASE_PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: [[PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: [[SIZES_ARG2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 9, i8** [[BASE_PTR_GEP_ARG2]], i8** [[PTR_GEP_ARG2]], i[[SZ]]* [[SIZES_ARG2]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT2]], i32 0, i32 0)) + + // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the + // target region + // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]]) + // TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*, + // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[BN_ADDR:%.+]] = alloca float*, + // TCHECK: [[C_ADDR:%.+]] = alloca [5 x [10 x double]]*, + // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[VLA_ADDR4:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[CN_ADDR:%.+]] = alloca double*, + // TCHECK: [[D_ADDR:%.+]] = alloca [[TT]]*, + // TCHECK-NOT: alloca i{{[0-9]+}}, + // TCHECK: [[B_PRIV:%.+]] = alloca [10 x float], + // TCHECK: [[SSTACK:%.+]] = alloca i8*, + // TCHECK: [[C_PRIV:%.+]] = alloca [5 x [10 x double]], + // TCHECK: [[D_PRIV:%.+]] = alloca [[TT]], + // TCHECK: store i{{[0-9]+}} [[A2_IN]], i{{[0-9]+}}* [[A2_ADDR]], + // TCHECK: store [10 x float]* [[B_IN]], [10 x float]** [[B_ADDR]], + // TCHECK: store i{{[0-9]+}} [[BN_SZ]], i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: store float* [[BN_IN]], float** [[BN_ADDR]], + // TCHECK: store [5 x [10 x double]]* [[C_IN]], [5 x [10 x double]]** [[C_ADDR]], + // TCHECK: store i{{[0-9]+}} [[CN_SZ1]], i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: store i{{[0-9]+}} [[CN_SZ2]], i{{[0-9]+}}* [[VLA_ADDR4]], + // TCHECK: store double* [[CN_IN]], double** [[CN_ADDR]], + // TCHECK: store [[TT]]* [[D_IN]], [[TT]]** [[D_ADDR]], + // TCHECK: [[CONV_A2ADDR:%.+]] = bitcast i{{[0-9]+}}* [[A2_ADDR]] to i{{[0-9]+}}* + // TCHECK: [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** [[B_ADDR]], + // TCHECK: [[BN_SZ_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: [[BN_ADDR_REF:%.+]] = load float*, float** [[BN_ADDR]], + // TCHECK: [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[C_ADDR]], + // TCHECK: [[CN_SZ1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: [[CN_SZ2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR4]], + // TCHECK: [[CN_ADDR_REF:%.+]] = load double*, double** [[CN_ADDR]], + // TCHECK: [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** [[D_ADDR]], + + // firstprivate(aa): a_priv = a_in + // TCHECK-NOT: store i{{[0-9]+}} % + + // firstprivate(b): memcpy(b_priv,b_in) + // TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x float]* [[B_PRIV]] to i8* + // TCHECK: [[B_ADDR_REF_BCAST:%.+]] = bitcast [10 x float]* [[B_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_ADDR_REF_BCAST]], {{.+}}) + + // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave() + // TCHECK: store i8* [[RET_STACK]], i8** [[SSTACK]], + + // firstprivate(bn) + // TCHECK: [[BN_PRIV:%.+]] = alloca float, i{{[0-9]+}} [[BN_SZ_VAL]], + // TCHECK: [[BN_COPY_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[BN_SZ_VAL]], 4 + // TCHECK: [[BN_PRIV__BCAST:%.+]] = bitcast float* [[BN_PRIV]] to i8* + // TCHECK: [[BN_REF_IN_BCAST:%.+]] = bitcast float* [[BN_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[BN_PRIV__BCAST]], i8* [[BN_REF_IN_BCAST]], i{{[0-9]+}} [[BN_COPY_SZ]],{{.+}}) + + // firstprivate(c) + // TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8* + // TCHECK: [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}}) + + // firstprivate(cn) + // TCHECK: [[CN_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ1_VAL]], [[CN_SZ2_VAL]] + // TCHECK: [[CN_PRIV:%.+]] = alloca double, i{{[0-9]+}} [[CN_SZ]], + // TCHECK: [[CN_SZ2:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ1_VAL]], [[CN_SZ2_VAL]] + // TCHECK: [[CN_SZ2_CPY:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ2]], 8 + // TCHECK: [[CN_PRIV_BCAST:%.+]] = bitcast double* [[CN_PRIV]] to i8* + // TCHECK: [[CN_IN_BCAST:%.+]] = bitcast double* [[CN_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[CN_PRIV_BCAST]], i8* [[CN_IN_BCAST]], i{{[0-9]+}} [[CN_SZ2_CPY]],{{.+}}) + + // firstprivate(d) + // TCHECK: [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8* + // TCHECK: [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[D_PRIV_BCAST]], i8* [[D_IN_BCAST]],{{.+}}) + + + #pragma omp target firstprivate(ptr) + { + ptr[0]++; + } + // CHECK: [[PTR_ADDR_REF:%.+]] = load double*, double** [[PTR_ADDR]], + // CHECK: [[PTR_ADDR_BCAST:%.+]] = bitcast double* [[PTR_ADDR_REF]] to i8* + + // CHECK: [[BASE_PTR_GEP3_0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[PTR_ADDR_BCAST]], i8** [[BASE_PTR_GEP3_0]], + // CHECK: [[PTR_ADDR_BCAST2:%.+]] = bitcast double* [[PTR_ADDR_REF]] to i8* + // CHECK: [[PTR_GEP3_0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[PTR_ADDR_BCAST2]], i8** [[PTR_GEP3_0]], + + // CHECK: [[BASE_PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: [[PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG3]], i8** [[PTR_GEP_ARG3]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT3]], i32 0, i32 0)) + + // TCHECK: define void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]]) + // TCHECK: [[PTR_ADDR:%.+]] = alloca double*, + // TCHECK-NOT: alloca double*, + // TCHECK: store double* [[PTR_IN]], double** [[PTR_ADDR]], + // TCHECK-NOT: store double* % + + return a; +} + + +template<typename tx> +tx ftemplate(int n) { + tx a = 0; + tx b[10]; + +#pragma omp target firstprivate(a,b) + { + a += 1; + b[2] += 1; + } + + return a; +} + +static +int fstatic(int n) { + int a = 0; + char aaa = 0; + int b[10]; + +#pragma omp target firstprivate(a,aaa,b) + { + a += 1; + aaa += 1; + b[2] += 1; + } + + return a; +} + +// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]]) +// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[A3_ADDR:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*, +// TCHECK-NOT: alloca i{{[0-9]+}}, +// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}], +// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]], +// TCHECK: store i{{[0-9]+}} [[A3_IN]], i{{[0-9]+}}* [[A3_ADDR]], +// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]], +// TCHECK-64: [[A_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}* +// TCHECK: [[A3_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A3_ADDR]] to i8* +// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]], + +// firstprivate(a): a_priv = a_in + +// firstprivate(aaa) +// TCHECK-NOT: store i{{[0-9]+}} % + +// firstprivate(b) +// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8* +// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8* +// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}}) + +// TCHECK: ret void + +struct S1 { + double a; + + int r1(int n){ + int b = n+1; + short int c[2][n]; + +#pragma omp target firstprivate(b,c) + { + this->a = (double)b + 1.5; + c[1][1] = ++a; + } + + return c[1][1] + (int)b; + } + + // on the host side, we first generate r1, then the static function and the template above + // CHECK: define{{.+}} i32 {{.+}}([[S1]]* {{.+}}, i{{[0-9]+}} {{.+}}) + // CHECK: [[BASE_PTRS4:%.+]] = alloca [5 x i8*], + // CHECK: [[PTRS4:%.+]] = alloca [5 x i8*], + // CHECK: [[SIZET4:%.+]] = alloca [5 x i{{[0-9]+}}], + + // map(this: this ptr is implicitly captured (not firstprivate matter) + // CHECK: {{.+}} = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store {{.+}}, {{.+}}, + // CHECK: {{.+}} = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store {{.+}}, {{.+}}, + // CHECK: {{.+}} getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store {{.+}}, {{.+}} + + // firstprivate(b): base_ptr = b, ptr = b, size = 4 (pass by-value) + // CHECK: [[B_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[B_CAST:%.+]] to i8* + // CHECK: [[BASE_PTRS_GEP4_1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i8* [[B_CAST_PTR]], i8** [[BASE_PTRS_GEP4_1]], + // CHECK: [[B_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[B_CAST:%.+]] to i8* + // CHECK: [[PTRS_GEP4_1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i8* [[B_CAST_PTR2]], i8** [[PTRS_GEP4_1]], + // CHECK: [[SIZES_GEP4_1:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIZES_GEP4_1]], + + // firstprivate(c), 3 entries: 2, n, c + // CHECK: [[BASE_PTRS_GEP4_2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i8* inttoptr (i{{[0-9]+}} 2 to i8*), i8** [[BASE_PTRS_GEP4_2]], + // CHECK: [[PTRS_GEP4_2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i8* inttoptr (i{{[0-9]+}} 2 to i8*), i8** [[PTRS_GEP4_2]], + // CHECK: [[SIZES_GEP4_2:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK-64: store i{{[0-9]+}} 8, i{{[0-9]+}}* [[SIZES_GEP4_2]], + // CHECK-32: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIZES_GEP4_2]], + // CHECK: [[N_PTR:%.+]] = inttoptr i{{[0-9]+}} [[N:%.+]] to i8* + // CHECK: [[BASE_PTRS_GEP4_3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // CHECK: store i8* [[N_PTR]], i8** [[BASE_PTRS_GEP4_3]], + // CHECK: [[N_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[N:%.+]] to i8* + // CHECK: [[PTRS_GEP4_3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // CHECK: store i8* [[N_PTR2]], i8** [[PTRS_GEP4_3]], + // CHECK: [[SIZES_GEP4_3:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // CHECK-64: store i{{[0-9]+}} 8, i{{[0-9]+}}* [[SIZES_GEP4_3]], + // CHECK-32: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIZES_GEP4_3]], + // CHECK: [[B_BCAST:%.+]] = bitcast i{{[0-9]+}}* [[B:%.+]] to i8* + // CHECK: [[BASE_PTRS_GEP4_4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 + // CHECK: store i8* [[B_BCAST]], i8** [[BASE_PTRS_GEP4_4]], + // CHECK: [[B_BCAST2:%.+]] = bitcast i{{[0-9]+}}* [[B:%.+]] to i8* + // CHECK: [[PTRS_GEP4_4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 + // CHECK: store i8* [[B_BCAST2]], i8** [[PTRS_GEP4_4]], + // CHECK: [[SIZES_GEP4_4:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 + // CHECK: store i{{[0-9]+}} [[B_SIZE:%.+]], i{{[0-9]+}}* [[SIZES_GEP4_4]], + + // only check that we use the map types stored in the global variable + // CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 5, i8** {{.+}}, i8** {{.+}}, i{{[0-9]+}}* {{.+}}, i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT4]], i32 0, i32 0)) + + // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]], i{{[0-9]+}}{{.+}} [[C_IN:%.+]]) + // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*, + // TCHECK: [[B_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[C_ADDR:%.+]] = alloca i{{[0-9]+}}*, + // TCHECK-NOT: alloca i{{[0-9]+}}, + // TCHECK: [[SSTACK:%.+]] = alloca i8*, + + // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]], + // TCHECK: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[B_ADDR]], + // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: store i{{[0-9]+}}* [[C_IN]], i{{[0-9]+}}** [[C_ADDR]], + // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]], + // TCHECK-64: [[B_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[B_ADDR]] to i{{[0-9]+}}* + // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: [[C_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_ADDR]], + + // firstprivate(b) + // TCHECK-NOT: store i{{[0-9]+}} % + + // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave() + // TCHECK: store i8* [[RET_STACK:%.+]], i8** [[SSTACK]], + + // firstprivate(c) + // TCHECK: [[C_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF]], [[VLA_ADDR_REF2]] + // TCHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, i{{[0-9]+}} [[C_SZ]], + // TCHECK: [[C_SZ2:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF]], [[VLA_ADDR_REF2]] + // TCHECK: [[C_SZ_CPY:%.+]] = mul{{.+}} i{{[0-9]+}} [[C_SZ2]], 2 + // TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast i{{[0-9]+}}* [[C_PRIV]] to i8* + // TCHECK: [[C_IN_BCAST:%.+]] = bitcast i{{[0-9]+}}* [[C_ADDR_REF]] to i8* + // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}}) + + // finish + // TCHECK: [[RELOAD_SSTACK:%.+]] = load i8*, i8** [[SSTACK]], + // TCHECK: call void @llvm.stackrestore(i8* [[RELOAD_SSTACK]]) + // TCHECK: ret void + + + // static host function + // CHECK: define{{.+}} i32 {{.+}}(i{{[0-9]+}} {{.+}}) + // CHECK: [[BASE_PTRS5:%.+]] = alloca [3 x i8*], + // CHECK: [[PTRS5:%.+]] = alloca [3 x i8*], + + // firstprivate(a): by value + // CHECK: [[A_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[A_CAST:%.+]] to i8* + // CHECK: [[BASE_PTRS_GEP5_0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BASE_PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[A_CAST_PTR]], i8** [[BASE_PTRS_GEP5_0]], + // CHECK: [[A_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[A_CAST:%.+]] to i8* + // CHECK: [[PTRS_GEP5_0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // CHECK: store i8* [[A_CAST_PTR2]], i8** [[PTRS_GEP5_0]], + + // firstprivate(aaa): by value + // CHECK: [[A3_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[A3_CAST:%.+]] to i8* + // CHECK: [[BASE_PTRS_GEP5_1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BASE_PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i8* [[A3_CAST_PTR]], i8** [[BASE_PTRS_GEP5_1]], + // CHECK: [[A3_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[A3_CAST:%.+]] to i8* + // CHECK: [[PTRS_GEP5_1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // CHECK: store i8* [[A3_CAST_PTR2]], i8** [[PTRS_GEP5_1]], + + // firstprivate(b): base_ptr = &b[0], ptr= &b[0] + // CHECK: [[B_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8* + // CHECK: [[BASE_PTRS_GEP5_2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BASE_PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i8* [[B_BCAST]], i8** [[BASE_PTRS_GEP5_2]], + // CHECK: [[B_BCAST2:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8* + // CHECK: [[PTRS_GEP5_2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // CHECK: store i8* [[B_BCAST2]], i8** [[PTRS_GEP5_2]], + + // only check that the right sizes and map types are used + // CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 3, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0)) +}; + + + +int bar(int n, double *ptr){ + int a = 0; + a += foo(n, ptr); + S1 S; + a += S.r1(n); + a += fstatic(n); + a += ftemplate<int>(n); + + return a; +} + +// template host and device + +// CHECK: define{{.+}} i32 {{.+}}(i{{[0-9]+}} {{.+}}) +// CHECK: [[BASE_PTRS6:%.+]] = alloca [2 x i8*], +// CHECK: [[PTRS6:%.+]] = alloca [2 x i8*], + +// firstprivate(a): by value +// CHECK: [[AT_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[AT_CAST:%.+]] to i8* +// CHECK: [[BASE_PTRS_GEP6_0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store i8* [[AT_CAST_PTR]], i8** [[BASE_PTRS_GEP6_0]], +// CHECK: [[AT_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[AT_CAST:%.+]] to i8* +// CHECK: [[PTRS_GEP6_0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store i8* [[AT_CAST_PTR2]], i8** [[PTRS_GEP6_0]], + +// firstprivate(b): pointer +// CHECK: [[B_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8* +// CHECK: [[BASE_PTRS_GEP6_1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i8* [[B_BCAST]], i8** [[BASE_PTRS_GEP6_1]], +// CHECK: [[B_BCAST2:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8* +// CHECK: [[PTRS_GEP6_1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i8* [[B_BCAST2]], i8** [[PTRS_GEP6_1]], + +// CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 2, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT6]], i32 0, i32 0)) + + +// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]]) +// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*, +// TCHECK-NOT: alloca i{{[0-9]+}}, +// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}], +// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]], +// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]], +// TCHECK-64: [[A_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}* +// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]], + +// firstprivate(a) +// TCHECK-NOT: store i{{[0-9]+}} % + +// firstprivate(b) +// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8* +// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8* +// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}}) + +// TCHECK: ret void + +#endif diff --git a/test/OpenMP/target_firstprivate_messages.cpp b/test/OpenMP/target_firstprivate_messages.cpp new file mode 100644 index 0000000000000..6dbad671de7c6 --- /dev/null +++ b/test/OpenMP/target_firstprivate_messages.cpp @@ -0,0 +1,198 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); + +public: + S4(int v) : a(v) { +#pragma omp target firstprivate(a) firstprivate(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target firstprivate(a) firstprivate(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) firstprivate(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target firstprivate // expected-error {{expected '(' after 'firstprivate'}} +{} +#pragma omp target firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target firstprivate() // expected-error {{expected expression}} +{} +#pragma omp target firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +{} +#pragma omp target firstprivate(argc) +{} +#pragma omp target firstprivate(S1) // expected-error {{'S1' does not refer to a value}} +{} +#pragma omp target firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} +{} +#pragma omp target firstprivate(argv[1]) // expected-error {{expected variable name}} +{} +#pragma omp target firstprivate(e, g) +{} +#pragma omp target firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +{} +#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}} +#pragma omp parallel + { + int v = 0; + int i; + } +#pragma omp parallel shared(i) +#pragma omp parallel firstprivate(i) +#pragma omp target firstprivate(j) +{} +#pragma omp target firstprivate(i) + {} + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp target firstprivate(a) + {} +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target firstprivate // expected-error {{expected '(' after 'firstprivate'}} +{} +#pragma omp target firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target firstprivate() // expected-error {{expected expression}} +{} +#pragma omp target firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +{} +#pragma omp target firstprivate(argc) +{} +#pragma omp target firstprivate(S1) // expected-error {{'S1' does not refer to a value}} +{} +#pragma omp target firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} +{} +#pragma omp target firstprivate(argv[1]) // expected-error {{expected variable name}} +{} +#pragma omp target firstprivate(e, g) +{} +#pragma omp target firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +{} +#pragma omp target firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} +{} +#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}} +#pragma omp parallel + { + int i; + } +#pragma omp parallel shared(i) +#pragma omp parallel firstprivate(i) +#pragma omp target firstprivate(j) +{} +#pragma omp target firstprivate(i) + {} + static int si; +#pragma omp target firstprivate(si) // OK + {} +#pragma omp target map(i) firstprivate(i) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}} + {} + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/target_if_messages.cpp b/test/OpenMP/target_if_messages.cpp index 4ee7302282f6c..189256e60fea2 100644 --- a/test/OpenMP/target_if_messages.cpp +++ b/test/OpenMP/target_if_messages.cpp @@ -12,21 +12,37 @@ struct S1; // expected-note {{declared here}} template <class T, class S> // expected-note {{declared here}} int tmain(T argc, S **argv) { #pragma omp target if // expected-error {{expected '(' after 'if'}} + foo(); #pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if () // expected-error {{expected expression}} + foo(); #pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); #pragma omp target if (argc > 0 ? argv[1] : argv[2]) + foo(); #pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}} + foo(); #pragma omp target if (S) // expected-error {{'S' does not refer to a value}} + foo(); #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(argc) + foo(); #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(target : argc) + foo(); #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}} + foo(); #pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}} + foo(); #pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); @@ -35,22 +51,39 @@ int tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp target if // expected-error {{expected '(' after 'if'}} + foo(); #pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if () // expected-error {{expected expression}} + foo(); #pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); #pragma omp target if (argc > 0 ? argv[1] : argv[2]) + foo(); #pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}} + foo(); #pragma omp target if (S1) // expected-error {{'S1' does not refer to a value}} + foo(); #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); #pragma omp target if(target : argc) + foo(); #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}} + foo(); #pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}} + foo(); #pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); diff --git a/test/OpenMP/target_is_device_ptr_ast_print.cpp b/test/OpenMP/target_is_device_ptr_ast_print.cpp new file mode 100644 index 0000000000000..f519235a0b365 --- /dev/null +++ b/test/OpenMP/target_is_device_ptr_ast_print.cpp @@ -0,0 +1,294 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +struct ST { + int *a; +}; +typedef int arr[10]; +typedef ST STarr[10]; +struct SA { + const int da[5] = { 0 }; + ST g[10]; + STarr &rg = g; + int i; + int &j = i; + int *k = &j; + int *&z = k; + int aa[10]; + arr &raa = aa; + void func(int arg) { +#pragma omp target is_device_ptr(k) + {} +#pragma omp target is_device_ptr(z) + {} +#pragma omp target is_device_ptr(aa) // OK + {} +#pragma omp target is_device_ptr(raa) // OK + {} +#pragma omp target is_device_ptr(g) // OK + {} +#pragma omp target is_device_ptr(rg) // OK + {} +#pragma omp target is_device_ptr(da) // OK + {} + return; + } +}; +// CHECK: struct SA +// CHECK-NEXT: const int da[5] = {0}; +// CHECK-NEXT: ST g[10]; +// CHECK-NEXT: STarr &rg = this->g; +// CHECK-NEXT: int i; +// CHECK-NEXT: int &j = this->i; +// CHECK-NEXT: int *k = &this->j; +// CHECK-NEXT: int *&z = this->k; +// CHECK-NEXT: int aa[10]; +// CHECK-NEXT: arr &raa = this->aa; +// CHECK-NEXT: func( +// CHECK-NEXT: #pragma omp target is_device_ptr(this->k) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(this->z) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(this->aa) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(this->raa) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(this->g) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(this->rg) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(this->da) + +struct SB { + unsigned A; + unsigned B; + float Arr[100]; + float *Ptr; + float *foo() { + return &Arr[0]; + } +}; + +struct SC { + unsigned A : 2; + unsigned B : 3; + unsigned C; + unsigned D; + float Arr[100]; + SB S; + SB ArrS[100]; + SB *PtrS; + SB *&RPtrS; + float *Ptr; + + SC(SB *&_RPtrS) : RPtrS(_RPtrS) {} +}; + +union SD { + unsigned A; + float B; +}; + +struct S1; +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) + +typedef struct { + int a; +} S6; + +template <typename T> +T tmain(T argc) { + const T da[5] = { 0 }; + S6 h[10]; + auto &rh = h; + T i; + T &j = i; + T *k = &j; + T *&z = k; + T aa[10]; + auto &raa = aa; +#pragma omp target is_device_ptr(k) + {} +#pragma omp target is_device_ptr(z) + {} +#pragma omp target is_device_ptr(aa) + {} +#pragma omp target is_device_ptr(raa) + {} +#pragma omp target is_device_ptr(h) + {} +#pragma omp target is_device_ptr(rh) + {} +#pragma omp target is_device_ptr(da) + {} + return 0; +} + +// CHECK: template <typename T = int> int tmain(int argc) { +// CHECK-NEXT: const int da[5] = {0}; +// CHECK-NEXT: S6 h[10]; +// CHECK-NEXT: auto &rh = h; +// CHECK-NEXT: int i; +// CHECK-NEXT: int &j = i; +// CHECK-NEXT: int *k = &j; +// CHECK-NEXT: int *&z = k; +// CHECK-NEXT: int aa[10]; +// CHECK-NEXT: auto &raa = aa; +// CHECK-NEXT: #pragma omp target is_device_ptr(k) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(z) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(aa) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(raa) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(h) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(rh) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(da) + +// CHECK: template <typename T = int *> int *tmain(int *argc) { +// CHECK-NEXT: int *const da[5] = {0}; +// CHECK-NEXT: S6 h[10]; +// CHECK-NEXT: auto &rh = h; +// CHECK-NEXT: int *i; +// CHECK-NEXT: int *&j = i; +// CHECK-NEXT: int **k = &j; +// CHECK-NEXT: int **&z = k; +// CHECK-NEXT: int *aa[10]; +// CHECK-NEXT: auto &raa = aa; +// CHECK-NEXT: #pragma omp target is_device_ptr(k) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(z) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(aa) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(raa) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(h) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(rh) +// CHECK-NEXT: { +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target is_device_ptr(da) + +// CHECK-LABEL: int main(int argc, char **argv) { +int main(int argc, char **argv) { + const int da[5] = { 0 }; + S6 h[10]; + auto &rh = h; + int i; + int &j = i; + int *k = &j; + int *&z = k; + int aa[10]; + auto &raa = aa; +// CHECK-NEXT: const int da[5] = {0}; +// CHECK-NEXT: S6 h[10]; +// CHECK-NEXT: auto &rh = h; +// CHECK-NEXT: int i; +// CHECK-NEXT: int &j = i; +// CHECK-NEXT: int *k = &j; +// CHECK-NEXT: int *&z = k; +// CHECK-NEXT: int aa[10]; +// CHECK-NEXT: auto &raa = aa; +#pragma omp target is_device_ptr(k) +// CHECK-NEXT: #pragma omp target is_device_ptr(k) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target is_device_ptr(z) +// CHECK-NEXT: #pragma omp target is_device_ptr(z) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target is_device_ptr(aa) +// CHECK-NEXT: #pragma omp target is_device_ptr(aa) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target is_device_ptr(raa) +// CHECK-NEXT: #pragma omp target is_device_ptr(raa) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target is_device_ptr(h) +// CHECK-NEXT: #pragma omp target is_device_ptr(h) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target is_device_ptr(rh) +// CHECK-NEXT: #pragma omp target is_device_ptr(rh) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } +#pragma omp target is_device_ptr(da) +// CHECK-NEXT: #pragma omp target is_device_ptr(da) + {} +// CHECK-NEXT: { +// CHECK-NEXT: } + return tmain<int>(argc) + *tmain<int *>(&argc); +} + + +#endif diff --git a/test/OpenMP/target_is_device_ptr_messages.cpp b/test/OpenMP/target_is_device_ptr_messages.cpp new file mode 100644 index 0000000000000..634e16114e1be --- /dev/null +++ b/test/OpenMP/target_is_device_ptr_messages.cpp @@ -0,0 +1,234 @@ +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s +struct ST { + int *a; +}; +typedef int arr[10]; +typedef ST STarr[10]; +struct SA { + const int d = 5; + const int da[5] = { 0 }; + ST e; + ST g[10]; + STarr &rg = g; + int i; + int &j = i; + int *k = &j; + int *&z = k; + int aa[10]; + arr &raa = aa; + void func(int arg) { +#pragma omp target is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}} + {} +#pragma omp target is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} +#pragma omp target is_device_ptr() // expected-error {{expected expression}} + {} +#pragma omp target is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} +#pragma omp target is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(k) // OK + {} +#pragma omp target is_device_ptr(z) // OK + {} +#pragma omp target is_device_ptr(aa) // OK + {} +#pragma omp target is_device_ptr(raa) // OK + {} +#pragma omp target is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(g) // OK + {} +#pragma omp target is_device_ptr(rg) // OK + {} +#pragma omp target is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(da) // OK + {} + return; + } +}; +struct SB { + unsigned A; + unsigned B; + float Arr[100]; + float *Ptr; + float *foo() { + return &Arr[0]; + } +}; + +struct SC { + unsigned A : 2; + unsigned B : 3; + unsigned C; + unsigned D; + float Arr[100]; + SB S; + SB ArrS[100]; + SB *PtrS; + SB *&RPtrS; + float *Ptr; + + SC(SB *&_RPtrS) : RPtrS(_RPtrS) {} +}; + +union SD { + unsigned A; + float B; +}; + +struct S1; +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) + +typedef struct { + int a; +} S6; + +template <typename T, int I> +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + S6 h[10]; + auto &rh = h; + T i; + T &j = i; + T *k = &j; + T *&z = k; + T aa[10]; + auto &raa = aa; +#pragma omp target is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}} + {} +#pragma omp target is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} +#pragma omp target is_device_ptr() // expected-error {{expected expression}} + {} +#pragma omp target is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} +#pragma omp target is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(k) // OK + {} +#pragma omp target is_device_ptr(z) // OK + {} +#pragma omp target is_device_ptr(aa) // OK + {} +#pragma omp target is_device_ptr(raa) // OK + {} +#pragma omp target is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(h) // OK + {} +#pragma omp target is_device_ptr(rh) // OK + {} +#pragma omp target is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(da) // OK + {} + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + S6 h[10]; + auto &rh = h; + int i; + int &j = i; + int *k = &j; + int *&z = k; + int aa[10]; + auto &raa = aa; +#pragma omp target is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}} + {} +#pragma omp target is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} +#pragma omp target is_device_ptr() // expected-error {{expected expression}} + {} +#pragma omp target is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} +#pragma omp target is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(k) // OK + {} +#pragma omp target is_device_ptr(z) // OK + {} +#pragma omp target is_device_ptr(aa) // OK + {} +#pragma omp target is_device_ptr(raa) // OK + {} +#pragma omp target is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(h) // OK + {} +#pragma omp target is_device_ptr(rh) // OK + {} +#pragma omp target is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}} + {} +#pragma omp target is_device_ptr(da) // OK + {} + return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} +} diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp index 942cc4c09fd30..626f68d5a2a94 100644 --- a/test/OpenMP/target_map_codegen.cpp +++ b/test/OpenMP/target_map_codegen.cpp @@ -7,17 +7,17 @@ /// ///==========================================================================/// -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 -// RUN: %clang_cc1 -DCK1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 -// RUN: %clang_cc1 -DCK1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 #ifdef CK1 // CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK1-LABEL: implicit_maps_integer void implicit_maps_integer (int a){ @@ -52,17 +52,17 @@ void implicit_maps_integer (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 -// RUN: %clang_cc1 -DCK2 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 -// RUN: %clang_cc1 -DCK2 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 #ifdef CK2 // CK2-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK2-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK2-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK2-LABEL: implicit_maps_integer_reference void implicit_maps_integer_reference (int a){ @@ -101,17 +101,17 @@ void implicit_maps_integer_reference (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK3 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 -// RUN: %clang_cc1 -DCK3 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 -// RUN: %clang_cc1 -DCK3 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 -// RUN: %clang_cc1 -DCK3 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 #ifdef CK3 // CK3-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK3-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK3-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK3-LABEL: implicit_maps_parameter void implicit_maps_parameter (int a){ @@ -145,17 +145,17 @@ void implicit_maps_parameter (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK4 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 -// RUN: %clang_cc1 -DCK4 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 -// RUN: %clang_cc1 -DCK4 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 -// RUN: %clang_cc1 -DCK4 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 +// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 #ifdef CK4 // CK4-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK4-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK4-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK4-LABEL: implicit_maps_nested_integer void implicit_maps_nested_integer (int a){ @@ -201,17 +201,17 @@ void implicit_maps_nested_integer (int a){ // CK4: define internal void [[KERNELP2]](i32* {{[^,]+}}, i32* {{[^,]+}}, i32* {{[^,]+}}) #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK5 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 -// RUN: %clang_cc1 -DCK5 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 -// RUN: %clang_cc1 -DCK5 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 -// RUN: %clang_cc1 -DCK5 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 +// RUN: %clang_cc1 -DCK5 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 +// RUN: %clang_cc1 -DCK5 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 #ifdef CK5 // CK5-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK5-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK5-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK5-LABEL: implicit_maps_nested_integer_and_enum void implicit_maps_nested_integer_and_enum (int a){ @@ -252,17 +252,17 @@ void implicit_maps_nested_integer_and_enum (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK6 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64 -// RUN: %clang_cc1 -DCK6 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64 -// RUN: %clang_cc1 -DCK6 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32 -// RUN: %clang_cc1 -DCK6 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32 +// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64 +// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64 +// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32 +// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32 #ifdef CK6 // CK6-DAG: [[GBL:@Gi]] = global i32 0 // CK6-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK6-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK6-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK6-LABEL: implicit_maps_host_global int Gi; @@ -298,22 +298,22 @@ void implicit_maps_host_global (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK7 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64 -// RUN: %clang_cc1 -DCK7 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64 -// RUN: %clang_cc1 -DCK7 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32 -// RUN: %clang_cc1 -DCK7 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32 +// RUN: %clang_cc1 -DCK7 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64 +// RUN: %clang_cc1 -DCK7 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64 +// RUN: %clang_cc1 -DCK7 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32 +// RUN: %clang_cc1 -DCK7 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32 #ifdef CK7 // For a 32-bit targets, the value doesn't fit the size of the pointer, // therefore it is passed by reference with a map 'to' specification. // CK7-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 8] -// Map types: OMP_MAP_BYCOPY = 128 -// CK7-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] -// Map types: OMP_MAP_TO = 1 -// CK7-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 1] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK7-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] +// Map types: OMP_MAP_TO | OMP_MAP_IS_FIRST = 33 +// CK7-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33] // CK7-LABEL: implicit_maps_double void implicit_maps_double (int a){ @@ -360,17 +360,17 @@ void implicit_maps_double (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK8 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8 -// RUN: %clang_cc1 -DCK8 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8 -// RUN: %clang_cc1 -DCK8 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8 -// RUN: %clang_cc1 -DCK8 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8 +// RUN: %clang_cc1 -DCK8 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8 +// RUN: %clang_cc1 -DCK8 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8 +// RUN: %clang_cc1 -DCK8 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8 +// RUN: %clang_cc1 -DCK8 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8 #ifdef CK8 // CK8-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] -// Map types: OMP_MAP_BYCOPY = 128 -// CK8-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288 +// CK8-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] // CK8-LABEL: implicit_maps_float void implicit_maps_float (int a){ @@ -404,17 +404,17 @@ void implicit_maps_float (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK9 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9 -// RUN: %clang_cc1 -DCK9 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9 -// RUN: %clang_cc1 -DCK9 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9 -// RUN: %clang_cc1 -DCK9 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9 +// RUN: %clang_cc1 -DCK9 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9 +// RUN: %clang_cc1 -DCK9 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9 +// RUN: %clang_cc1 -DCK9 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9 +// RUN: %clang_cc1 -DCK9 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9 #ifdef CK9 // CK9-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 16] -// Map types: OMP_MAP_TO + OMP_MAP_FROM = 2 + 1 -// CK9-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 3] +// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35 +// CK9-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 35] // CK9-LABEL: implicit_maps_array void implicit_maps_array (int a){ @@ -445,17 +445,17 @@ void implicit_maps_array (int a){ // CK9: {{.+}} = getelementptr inbounds [2 x double], [2 x double]* [[REF]], i[[sz]] 0, i[[sz]] 0 #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK10 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10 -// RUN: %clang_cc1 -DCK10 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10 -// RUN: %clang_cc1 -DCK10 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10 -// RUN: %clang_cc1 -DCK10 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10 +// RUN: %clang_cc1 -DCK10 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10 +// RUN: %clang_cc1 -DCK10 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10 +// RUN: %clang_cc1 -DCK10 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10 +// RUN: %clang_cc1 -DCK10 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10 #ifdef CK10 -// CK10-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}] -// Map types: OMP_MAP_BYCOPY | OMP_MAP_PTR = 128 + 32 -// CK10-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 160] +// CK10-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] zeroinitializer +// Map types: OMP_MAP_IS_FIRST = 32 +// CK10-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 32] // CK10-LABEL: implicit_maps_pointer void implicit_maps_pointer (){ @@ -487,17 +487,17 @@ void implicit_maps_pointer (){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK11 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11 -// RUN: %clang_cc1 -DCK11 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11 -// RUN: %clang_cc1 -DCK11 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11 -// RUN: %clang_cc1 -DCK11 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11 #ifdef CK11 // CK11-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 16] -// Map types: OMP_MAP_TO = 1 -// CK11-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 1] +// Map types: OMP_MAP_TO + OMP_MAP_IS_FIRST = 33 +// CK11-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33] // CK11-LABEL: implicit_maps_double_complex void implicit_maps_double_complex (int a){ @@ -527,22 +527,22 @@ void implicit_maps_double_complex (int a){ // CK11: {{.+}} = getelementptr inbounds { double, double }, { double, double }* [[REF]], i32 0, i32 0 #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK12 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64 -// RUN: %clang_cc1 -DCK12 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64 -// RUN: %clang_cc1 -DCK12 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32 -// RUN: %clang_cc1 -DCK12 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32 +// RUN: %clang_cc1 -DCK12 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64 +// RUN: %clang_cc1 -DCK12 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64 +// RUN: %clang_cc1 -DCK12 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32 +// RUN: %clang_cc1 -DCK12 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32 #ifdef CK12 // For a 32-bit targets, the value doesn't fit the size of the pointer, // therefore it is passed by reference with a map 'to' specification. // CK12-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 8] -// Map types: OMP_MAP_BYCOPY = 128 -// CK12-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] -// Map types: OMP_MAP_TO = 1 -// CK12-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 1] +// Map types: OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 +// CK12-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] +// Map types: OMP_MAP_TO + OMP_MAP_IS_FIRST = 33 +// CK12-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33] // CK12-LABEL: implicit_maps_float_complex void implicit_maps_float_complex (int a){ @@ -588,20 +588,20 @@ void implicit_maps_float_complex (int a){ // CK12-32: {{.+}} = getelementptr inbounds { float, float }, { float, float }* [[REF]], i32 0, i32 0 #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK13 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13 -// RUN: %clang_cc1 -DCK13 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13 -// RUN: %clang_cc1 -DCK13 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13 -// RUN: %clang_cc1 -DCK13 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13 +// RUN: %clang_cc1 -DCK13 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13 +// RUN: %clang_cc1 -DCK13 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13 +// RUN: %clang_cc1 -DCK13 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13 +// RUN: %clang_cc1 -DCK13 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13 #ifdef CK13 // We don't have a constant map size for VLAs. // Map types: -// - OMP_MAP_BYCOPY = 128 (vla size) -// - OMP_MAP_BYCOPY = 128 (vla size) -// - OMP_MAP_TO + OMP_MAP_FROM = 2 + 1 -// CK13-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i32] [i32 128, i32 128, i32 3] +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 (vla size) +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 (vla size) +// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35 +// CK13-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i32] [i32 288, i32 288, i32 35] // CK13-LABEL: implicit_maps_variable_length_array void implicit_maps_variable_length_array (int a){ @@ -658,20 +658,20 @@ void implicit_maps_variable_length_array (int a){ // CK13: {{.+}} = getelementptr inbounds double, double* [[REF]], i[[sz]] %{{.+}} #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK14 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64 -// RUN: %clang_cc1 -DCK14 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64 -// RUN: %clang_cc1 -DCK14 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32 -// RUN: %clang_cc1 -DCK14 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32 +// RUN: %clang_cc1 -DCK14 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64 +// RUN: %clang_cc1 -DCK14 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64 +// RUN: %clang_cc1 -DCK14 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32 +// RUN: %clang_cc1 -DCK14 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32 #ifdef CK14 // CK14-DAG: [[ST:%.+]] = type { i32, double } // CK14-DAG: [[SIZES:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{16|12}}, i{{64|32}} 4] // Map types: -// - OMP_MAP_TO | OMP_MAP_FROM = 1 + 2 -// - OMP_MAP_BYCOPY = 128 -// CK14-DAG: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 3, i32 128] +// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35 +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 +// CK14-DAG: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288] class SSS { public: @@ -732,26 +732,26 @@ void implicit_maps_class (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK15 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64 -// RUN: %clang_cc1 -DCK15 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64 -// RUN: %clang_cc1 -DCK15 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32 -// RUN: %clang_cc1 -DCK15 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32 +// RUN: %clang_cc1 -DCK15 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64 +// RUN: %clang_cc1 -DCK15 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64 +// RUN: %clang_cc1 -DCK15 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32 +// RUN: %clang_cc1 -DCK15 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32 #ifdef CK15 // CK15: [[ST:%.+]] = type { i32, double, i32* } // CK15: [[SIZES:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{24|16}}, i{{64|32}} 4] // Map types: -// - OMP_MAP_TO | OMP_MAP_FROM = 1 + 2 -// - OMP_MAP_BYCOPY = 128 -// CK15: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 3, i32 128] +// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35 +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 +// CK15: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288] // CK15: [[SIZES2:@.+]] = {{.+}}constant [2 x i[[sz]]] [i{{64|32}} {{24|16}}, i{{64|32}} 4] // Map types: -// - OMP_MAP_TO | OMP_MAP_FROM = 1 + 2 -// - OMP_MAP_BYCOPY = 128 -// CK15: [[TYPES2:@.+]] = {{.+}}constant [2 x i32] [i32 3, i32 128] +// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35 +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 +// CK15: [[TYPES2:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288] template<int x> class SSST { @@ -860,18 +860,18 @@ void implicit_maps_templated_class (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK16 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64 -// RUN: %clang_cc1 -DCK16 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64 -// RUN: %clang_cc1 -DCK16 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32 -// RUN: %clang_cc1 -DCK16 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32 +// RUN: %clang_cc1 -DCK16 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64 +// RUN: %clang_cc1 -DCK16 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64 +// RUN: %clang_cc1 -DCK16 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32 +// RUN: %clang_cc1 -DCK16 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32 #ifdef CK16 // CK16-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] // Map types: -// - OMP_MAP_BYCOPY = 128 -// CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 +// CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] template<int y> int foo(int d) { @@ -913,18 +913,18 @@ void implicit_maps_templated_function (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK17 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17 -// RUN: %clang_cc1 -DCK17 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17 -// RUN: %clang_cc1 -DCK17 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17 -// RUN: %clang_cc1 -DCK17 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17 +// RUN: %clang_cc1 -DCK17 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17 +// RUN: %clang_cc1 -DCK17 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17 +// RUN: %clang_cc1 -DCK17 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17 +// RUN: %clang_cc1 -DCK17 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17 #ifdef CK17 // CK17-DAG: [[ST:%.+]] = type { i32, double } // CK17-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{16|12}}] -// Map types: OMP_MAP_TO + OMP_MAP_FROM = 2 + 1 -// CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 3] +// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35 +// CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 35] class SSS { public: @@ -961,18 +961,18 @@ void implicit_maps_struct (int a){ // CK17: {{.+}} = getelementptr inbounds [[ST]], [[ST]]* [[REF]], i32 0, i32 0 #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK18 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 -// RUN: %clang_cc1 -DCK18 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 -// RUN: %clang_cc1 -DCK18 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 -// RUN: %clang_cc1 -DCK18 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 +// RUN: %clang_cc1 -DCK18 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 +// RUN: %clang_cc1 -DCK18 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 +// RUN: %clang_cc1 -DCK18 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 +// RUN: %clang_cc1 -DCK18 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 #ifdef CK18 // CK18-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4] // Map types: -// - OMP_MAP_BYCOPY = 128 -// CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128] +// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 +// CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288] template<typename T> int foo(T d) { @@ -1012,4 +1012,3463 @@ void implicit_maps_template_type_capture (int a){ // CK18-32: {{.+}} = load i32, i32* [[ADDR]], #endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK19 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-64 +// RUN: %clang_cc1 -DCK19 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-64 +// RUN: %clang_cc1 -DCK19 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-32 +// RUN: %clang_cc1 -DCK19 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-32 +#ifdef CK19 + +// CK19: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK19: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK19: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400] +// CK19: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK19: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240] +// CK19: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK19: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240] +// CK19: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400] +// CK19: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK19: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK19: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK19: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK19: [[SIZE08:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK19: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}] +// CK19: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK19: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240] +// CK19: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE11:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240] +// CK19: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK19: [[SIZE12:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK19: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK19: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK19: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK19: [[SIZE15:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK19: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK19: [[MTYPE16:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 33] + +// CK19: [[SIZE17:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 240] +// CK19: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 34] + +// CK19: [[SIZE18:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 240] +// CK19: [[MTYPE18:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35] + +// CK19: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 32] + +// CK19: [[SIZE20:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK19: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 33] + +// CK19: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35] + +// CK19: [[SIZE22:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK19: [[MTYPE22:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35] + +// CK19: [[SIZE23:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK19: [[MTYPE23:@.+]] = private {{.*}}constant [1 x i32] [i32 39] + +// CK19: [[SIZE24:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 480] +// CK19: [[MTYPE24:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE25:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16] +// CK19: [[MTYPE25:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE26:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 24] +// CK19: [[MTYPE26:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE27:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK19: [[MTYPE27:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE28:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 16] +// CK19: [[MTYPE28:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19] + +// CK19: [[SIZE29:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4] +// CK19: [[MTYPE29:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19] + +// CK19: [[MTYPE30:@.+]] = private {{.*}}constant [4 x i32] [i32 288, i32 288, i32 288, i32 35] + +// CK19: [[SIZE31:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 40] +// CK19: [[MTYPE31:@.+]] = private {{.*}}constant [4 x i32] [i32 288, i32 288, i32 288, i32 35] + +// CK19: [[SIZE32:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728] +// CK19: [[MTYPE32:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE33:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728] +// CK19: [[MTYPE33:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE34:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728] +// CK19: [[MTYPE34:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[MTYPE35:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[SIZE36:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 208] +// CK19: [[MTYPE36:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19: [[MTYPE37:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35] + +// CK19: [[MTYPE38:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35] + +// CK19: [[MTYPE39:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35] + +// CK19: [[MTYPE40:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35] + +// CK19: [[SIZE41:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 208] +// CK19: [[MTYPE41:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35] + +// CK19: [[SIZE42:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 104] +// CK19: [[MTYPE42:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19] + +// CK19: [[MTYPE43:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK19-LABEL: explicit_maps_single +void explicit_maps_single (int ii){ + // Map of a scalar. + int a = ii; + + // Region 00 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + + // CK19: call void [[CALL00:@.+]](i32* {{[^,]+}}) + #pragma omp target map(alloc:a) + { + ++a; + } + + // Map of an array. + int arra[100]; + + // Region 01 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [100 x i32]* [[VAR0]] to i8* + + // CK19: call void [[CALL01:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(to:arra) + { + arra[50]++; + } + + // Region 02 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 20 + + // CK19: call void [[CALL02:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(from:arra[20:60]) + { + arra[50]++; + } + + // Region 03 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 0 + + // CK19: call void [[CALL03:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(tofrom:arra[:60]) + { + arra[50]++; + } + + // Region 04 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 0 + + // CK19: call void [[CALL04:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(alloc:arra[:]) + { + arra[50]++; + } + + // Region 05 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 15 + + // CK19: call void [[CALL05:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(to:arra[15]) + { + arra[15]++; + } + + // Region 06 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4 + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} %{{.*}} + + // CK19: call void [[CALL06:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(tofrom:arra[ii:ii+23]) + { + arra[50]++; + } + + // Region 07 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4 + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 0 + + // CK19: call void [[CALL07:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(alloc:arra[:ii]) + { + arra[50]++; + } + + // Region 08 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} %{{.*}} + + // CK19: call void [[CALL08:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(tofrom:arra[ii]) + { + arra[15]++; + } + + // Map of a pointer. + int *pa; + + // Region 09 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32** [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32** [[VAR0]] to i8* + + // CK19: call void [[CALL09:@.+]](i32** {{[^,]+}}) + #pragma omp target map(from:pa) + { + pa[50]++; + } + + // Region 10 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 20 + // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK19: call void [[CALL10:@.+]](i32* {{[^,]+}}) + #pragma omp target map(tofrom:pa[20:60]) + { + pa[50]++; + } + + // Region 11 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0 + // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK19: call void [[CALL11:@.+]](i32* {{[^,]+}}) + #pragma omp target map(alloc:pa[:60]) + { + pa[50]++; + } + + // Region 12 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 15 + // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK19: call void [[CALL12:@.+]](i32* {{[^,]+}}) + #pragma omp target map(to:pa[15]) + { + pa[15]++; + } + + // Region 13 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4 + // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} %{{.*}} + // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK19: call void [[CALL13:@.+]](i32* {{[^,]+}}) + #pragma omp target map(alloc:pa[ii-23:ii]) + { + pa[50]++; + } + + // Region 14 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4 + // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0 + // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK19: call void [[CALL14:@.+]](i32* {{[^,]+}}) + #pragma omp target map(to:pa[:ii]) + { + pa[50]++; + } + + // Region 15 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} %{{.*}} + // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK19: call void [[CALL15:@.+]](i32* {{[^,]+}}) + #pragma omp target map(from:pa[ii+12]) + { + pa[15]++; + } + + // Map of a variable-size array. + int va[ii]; + + // Region 16 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE16]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} {{8|4}}, i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i{{.+}} [[CSVAL1:%[^,]+]], i{{.+}}* [[S1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[VAR1]] to i8* + // CK19-DAG: [[CSVAL1]] = mul nuw i{{.+}} %{{.*}}, 4 + + // CK19: call void [[CALL16:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(to:va) + { + va[50]++; + } + + // Region 17 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 20 + + // CK19: call void [[CALL17:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(from:va[20:60]) + { + va[50]++; + } + + // Region 18 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE18]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 0 + + // CK19: call void [[CALL18:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(tofrom:va[:60]) + { + va[50]++; + } + + // Region 19 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} {{8|4}}, i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i{{.+}} [[CSVAL1:%[^,]+]], i{{.+}}* [[S1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK19-DAG: [[CSVAL1]] = mul nuw i{{.+}} %{{.*}}, 4 + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 0 + + // CK19: call void [[CALL19:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(alloc:va[:]) + { + va[50]++; + } + + // Region 20 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 15 + + // CK19: call void [[CALL20:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(to:va[15]) + { + va[15]++; + } + + // Region 21 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i{{.+}} {{8|4}}, i{{.+}}* [[S0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i{{.+}} [[CSVAL1:%[^,]+]], i{{.+}}* [[S1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK19-DAG: [[CSVAL1]] = mul nuw i{{.+}} %{{.*}}, 4 + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} %{{.+}} + + // CK19: call void [[CALL21:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(tofrom:va[ii:ii+23]) + { + va[50]++; + } + + // Region 22 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE22]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8* + // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8* + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} %{{.+}} + + // CK19: call void [[CALL22:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(tofrom:va[ii]) + { + va[15]++; + } + + // Always. + // Region 23 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE23]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + + // CK19: call void [[CALL23:@.+]](i32* {{[^,]+}}) + #pragma omp target map(always, tofrom: a) + { + a++; + } + + // Multidimensional arrays. + int marr[4][5][6]; + int ***mptr; + + // Region 24 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE24]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0]] to i8* + + // CK19: call void [[CALL24:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}}) + #pragma omp target map(tofrom: marr) + { + marr[1][2][3]++; + } + + // Region 25 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE25]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE25]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[6 x i32]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[SEC00]] = getelementptr {{.*}}[5 x [6 x i32]]* [[SEC000:[^,]+]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[SEC000]] = getelementptr {{.*}}[4 x [5 x [6 x i32]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + + // CK19: call void [[CALL25:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}}) + #pragma omp target map(tofrom: marr[1][2][2:4]) + { + marr[1][2][3]++; + } + + // Region 26 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE26]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE26]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[6 x i32]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[SEC00]] = getelementptr {{.*}}[5 x [6 x i32]]* [[SEC000:[^,]+]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[SEC000]] = getelementptr {{.*}}[4 x [5 x [6 x i32]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + + // CK19: call void [[CALL26:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}}) + #pragma omp target map(tofrom: marr[1][2][:]) + { + marr[1][2][3]++; + } + + // Region 27 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE27]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE27]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[6 x i32]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 3 + // CK19-DAG: [[SEC00]] = getelementptr {{.*}}[5 x [6 x i32]]* [[SEC000:[^,]+]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[SEC000]] = getelementptr {{.*}}[4 x [5 x [6 x i32]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + + // CK19: call void [[CALL27:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}}) + #pragma omp target map(tofrom: marr[1][2][3]) + { + marr[1][2][3]++; + } + + // Region 28 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE28]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE28]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32*** [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32*** [[SEC0:%.+]] to i8* + // CK19-DAG: [[VAR0]] = load i32***, i32**** [[PTR:%[^,]+]], + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32*** [[SEC00:[^,]+]], i{{.+}} 1 + // CK19-DAG: [[SEC00]] = load i32***, i32**** [[PTR]], + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32*** [[SEC0]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32** [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32** [[SEC11:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC11]] = load i32**, i32*** [[SEC111:%[^,]+]], + // CK19-DAG: [[SEC111]] = getelementptr {{.*}}i32*** [[SEC1111:[^,]+]], i{{.+}} 1 + // CK19-DAG: [[SEC1111]] = load i32***, i32**** [[PTR]], + + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: [[CBPVAL2]] = bitcast i32** [[SEC1]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast i32* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.*}}i32* [[SEC22:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC22]] = load i32*, i32** [[SEC222:%[^,]+]], + // CK19-DAG: [[SEC222]] = getelementptr {{.*}}i32** [[SEC2222:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC2222]] = load i32**, i32*** [[SEC22222:%[^,]+]], + // CK19-DAG: [[SEC22222]] = getelementptr {{.*}}i32*** [[SEC222222:[^,]+]], i{{.+}} 1 + // CK19-DAG: [[SEC222222]] = load i32***, i32**** [[PTR]], + + // CK19: call void [[CALL28:@.+]](i32*** {{[^,]+}}) + #pragma omp target map(tofrom: mptr[1][2][2:4]) + { + mptr[1][2][3]++; + } + + // Region 29 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE29]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE29]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast i32*** [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast i32*** [[SEC0:%.+]] to i8* + // CK19-DAG: [[VAR0]] = load i32***, i32**** [[PTR:%[^,]+]], + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32*** [[SEC00:[^,]+]], i{{.+}} 1 + // CK19-DAG: [[SEC00]] = load i32***, i32**** [[PTR]], + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast i32*** [[SEC0]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast i32** [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32** [[SEC11:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC11]] = load i32**, i32*** [[SEC111:%[^,]+]], + // CK19-DAG: [[SEC111]] = getelementptr {{.*}}i32*** [[SEC1111:[^,]+]], i{{.+}} 1 + // CK19-DAG: [[SEC1111]] = load i32***, i32**** [[PTR]], + + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: [[CBPVAL2]] = bitcast i32** [[SEC1]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast i32* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.*}}i32* [[SEC22:[^,]+]], i{{.+}} 3 + // CK19-DAG: [[SEC22]] = load i32*, i32** [[SEC222:%[^,]+]], + // CK19-DAG: [[SEC222]] = getelementptr {{.*}}i32** [[SEC2222:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC2222]] = load i32**, i32*** [[SEC22222:%[^,]+]], + // CK19-DAG: [[SEC22222]] = getelementptr {{.*}}i32*** [[SEC222222:[^,]+]], i{{.+}} 1 + // CK19-DAG: [[SEC222222]] = load i32***, i32**** [[PTR]], + + // CK19: call void [[CALL29:@.+]](i32*** {{[^,]+}}) + #pragma omp target map(tofrom: mptr[1][2][3]) + { + mptr[1][2][3]++; + } + + // Multidimensional VLA. + double mva[23][ii][ii+5]; + + // Region 30 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE30]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[P0]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // CK19-64-DAG: [[VAR1]] = zext i32 %{{[^,]+}} to i64 + // CK19-64-DAG: [[VAR11]] = zext i32 %{{[^,]+}} to i64 + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S2]] + // CK19-DAG: [[CBPVAL2]] = inttoptr i[[Z]] [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = inttoptr i[[Z]] [[VAR22:%.+]] to i8* + // CK19-64-DAG: [[VAR2]] = zext i32 %{{[^,]+}} to i64 + // CK19-64-DAG: [[VAR22]] = zext i32 %{{[^,]+}} to i64 + // + // CK19-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3 + // CK19-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3 + // CK19-DAG: [[S3:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 3 + // CK19-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]] + // CK19-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]] + // CK19-DAG: store i[[Z]] [[CSVAL3:%[^,]+]], i[[Z]]* [[S3]] + // CK19-DAG: [[CBPVAL3]] = bitcast double* [[VAR3:%.+]] to i8* + // CK19-DAG: [[CPVAL3]] = bitcast double* [[VAR3]] to i8* + // CK19-DAG: [[CSVAL3]] = mul nuw i[[Z]] %{{[^,]+}}, {{8|4}} + + // CK19: call void [[CALL30:@.+]](i[[Z]] 23, i[[Z]] %{{[^,]+}}, i[[Z]] %{{[^,]+}}, double* %{{[^,]+}}) + #pragma omp target map(tofrom: mva) + { + mva[1][2][3]++; + } + + // Region 31 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE31]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE31]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[P0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: [[CBPVAL2]] = inttoptr i[[Z]] [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = inttoptr i[[Z]] [[VAR22:%.+]] to i8* + // + // CK19-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3 + // CK19-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3 + // CK19-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]] + // CK19-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]] + // CK19-DAG: [[CBPVAL3]] = bitcast double* [[VAR3:%.+]] to i8* + // CK19-DAG: [[CPVAL3]] = bitcast double* [[SEC3:%.+]] to i8* + // CK19-DAG: [[SEC3]] = getelementptr {{.*}}double* [[SEC33:%.+]], i[[Z]] 0 + // CK19-DAG: [[SEC33]] = getelementptr {{.*}}double* [[SEC333:%.+]], i[[Z]] [[IDX3:%.+]] + // CK19-DAG: [[IDX3]] = mul nsw i[[Z]] %{{[^,]+}}, %{{[^,]+}} + // CK19-DAG: [[SEC333]] = getelementptr {{.*}}double* [[VAR3]], i[[Z]] [[IDX33:%.+]] + // CK19-DAG: [[IDX33]] = mul nsw i[[Z]] 1, %{{[^,]+}} + + // CK19: call void [[CALL31:@.+]](i[[Z]] 23, i[[Z]] %{{[^,]+}}, i[[Z]] %{{[^,]+}}, double* %{{[^,]+}}) + #pragma omp target map(tofrom: mva[1][ii-2][:5]) + { + mva[1][2][3]++; + } + + // Multidimensional array sections. + double marras[11][12][13]; + double mvlaas[11][ii][13]; + double ***mptras; + + // Region 32 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE32]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE32]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0]] to i8* + + // CK19: call void [[CALL32:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}}) + #pragma omp target map(marras) + { + marras[1][2][3]++; + } + + // Region 33 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE33]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE33]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [12 x [13 x double]]* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 0 + + // CK19: call void [[CALL33:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}}) + #pragma omp target map(marras[:]) + { + marras[1][2][3]++; + } + + // Region 34 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE34]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE34]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [12 x [13 x double]]* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 0 + + // CK19: call void [[CALL34:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}}) + #pragma omp target map(marras[:][:][:]) + { + marras[1][2][3]++; + } + + // Region 35 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE35]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i[[Z]] [[CSVAL0:%[^,]+]], i[[Z]]* [[S0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [13 x double]* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[12 x [13 x double]]* [[SEC00:%[^,]+]], i[[Z]] 0, i[[Z]] 0 + // CK19-DAG: [[SEC00]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 1 + // CK19-DAG: [[CSVAL0]] = mul nuw i[[Z]] %{{[^,]+}}, 104 + + // CK19: call void [[CALL35:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}}) + #pragma omp target map(marras[1][:ii][:]) + { + marras[1][2][3]++; + } + + // Region 36 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE36]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE36]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [13 x double]* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[13 x double]* [[SEC00:%[^,]+]], i{{.+}} 0 + // CK19-DAG: [[SEC00]] = getelementptr {{.+}}[12 x [13 x double]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[SEC000]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 0 + + // CK19: call void [[CALL36:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}}) + #pragma omp target map(marras[:1][:2][:13]) + { + marras[1][2][3]++; + } + + // Region 37 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE37]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]] + // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[VAR2]] to i8* + // CK19-DAG: [[CSVAL2]] = mul nuw i[[Z]] %{{[^,]+}}, 104 + + // CK19: call void [[CALL37:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}}) + #pragma omp target map(mvlaas) + { + mvlaas[1][2][3]++; + } + + // Region 38 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE38]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]] + // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC22:%[^,]+]] + // CK19-DAG: [[SEC22]] = mul nsw i[[Z]] 0, %{{[^,]+}} + // CK19-DAG: [[CSVAL2]] = mul nuw i[[Z]] %{{[^,]+}}, 104 + + // CK19: call void [[CALL38:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}}) + #pragma omp target map(mvlaas[:]) + { + mvlaas[1][2][3]++; + } + + // Region 39 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE39]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]] + // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC22:%[^,]+]] + // CK19-DAG: [[SEC22]] = mul nsw i[[Z]] 0, %{{[^,]+}} + // CK19-DAG: [[CSVAL2]] = mul nuw i[[Z]] %{{[^,]+}}, 104 + + // CK19: call void [[CALL39:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}}) + #pragma omp target map(mvlaas[:][:][:]) + { + mvlaas[1][2][3]++; + } + + // Region 40 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE40]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]] + // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[SEC22:%[^,]+]], i[[Z]] 0 + // CK19-DAG: [[SEC22]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC222:%[^,]+]] + // CK19-DAG: [[SEC222]] = mul nsw i[[Z]] 1, %{{[^,]+}} + + // CK19: call void [[CALL40:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}}) + #pragma omp target map(mvlaas[1][:ii][:]) + { + mvlaas[1][2][3]++; + } + + // Region 41 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE41]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE41]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]] + // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]] + // + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8* + // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8* + // + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[SEC22:%[^,]+]], i[[Z]] 0 + // CK19-DAG: [[SEC22]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC222:%[^,]+]] + // CK19-DAG: [[SEC222]] = mul nsw i[[Z]] 0, %{{[^,]+}} + + // CK19: call void [[CALL41:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}}) + #pragma omp target map(mvlaas[:1][:2][:13]) + { + mvlaas[1][2][3]++; + } + + // Region 42 + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE42]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE42]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: [[CBPVAL0]] = bitcast double*** [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast double*** [[SEC0:%.+]] to i8* + // CK19-DAG: [[VAR0]] = load double***, double**** [[PTR:%[^,]+]], + // CK19-DAG: [[SEC0]] = getelementptr {{.*}}double*** [[SEC00:[^,]+]], i{{.+}} 0 + // CK19-DAG: [[SEC00]] = load double***, double**** [[PTR]], + + // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK19-DAG: [[CBPVAL1]] = bitcast double*** [[SEC0]] to i8* + // CK19-DAG: [[CPVAL1]] = bitcast double** [[SEC1:%.+]] to i8* + // CK19-DAG: [[SEC1]] = getelementptr {{.*}}double** [[SEC11:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC11]] = load double**, double*** [[SEC111:%[^,]+]], + // CK19-DAG: [[SEC111]] = getelementptr {{.*}}double*** [[SEC1111:[^,]+]], i{{.+}} 0 + // CK19-DAG: [[SEC1111]] = load double***, double**** [[PTR]], + + // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 + // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] + // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] + // CK19-DAG: [[CBPVAL2]] = bitcast double** [[SEC1]] to i8* + // CK19-DAG: [[CPVAL2]] = bitcast double* [[SEC2:%.+]] to i8* + // CK19-DAG: [[SEC2]] = getelementptr {{.*}}double* [[SEC22:[^,]+]], i{{.+}} 0 + // CK19-DAG: [[SEC22]] = load double*, double** [[SEC222:%[^,]+]], + // CK19-DAG: [[SEC222]] = getelementptr {{.*}}double** [[SEC2222:[^,]+]], i{{.+}} 2 + // CK19-DAG: [[SEC2222]] = load double**, double*** [[SEC22222:%[^,]+]], + // CK19-DAG: [[SEC22222]] = getelementptr {{.*}}double*** [[SEC222222:[^,]+]], i{{.+}} 0 + // CK19-DAG: [[SEC222222]] = load double***, double**** [[PTR]], + + // CK19: call void [[CALL42:@.+]](double*** {{[^,]+}}) + #pragma omp target map(mptras[:1][2][:13]) + { + mptras[1][2][3]++; + } + + // Region 43 - the memory is not contiguous for this map - will map the whole last dimension. + // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE43]]{{.+}}) + // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + // + // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK19-DAG: store i[[Z]] [[CSVAL0:%[^,]+]], i[[Z]]* [[S0]] + // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8* + // CK19-DAG: [[CPVAL0]] = bitcast [13 x double]* [[SEC0:%.+]] to i8* + // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[12 x [13 x double]]* [[SEC00:%[^,]+]], i[[Z]] 0, i[[Z]] 0 + // CK19-DAG: [[SEC00]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 1 + // CK19-DAG: [[CSVAL0]] = mul nuw i[[Z]] %{{[^,]+}}, 104 + + // CK19: call void [[CALL43:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}}) + #pragma omp target map(marras[1][:ii][1:]) + { + marras[1][2][3]++; + } + +} + +// CK19: define {{.+}}[[CALL00]] +// CK19: define {{.+}}[[CALL01]] +// CK19: define {{.+}}[[CALL02]] +// CK19: define {{.+}}[[CALL03]] +// CK19: define {{.+}}[[CALL04]] +// CK19: define {{.+}}[[CALL05]] +// CK19: define {{.+}}[[CALL06]] +// CK19: define {{.+}}[[CALL07]] +// CK19: define {{.+}}[[CALL08]] +// CK19: define {{.+}}[[CALL09]] +// CK19: define {{.+}}[[CALL10]] +// CK19: define {{.+}}[[CALL11]] +// CK19: define {{.+}}[[CALL12]] +// CK19: define {{.+}}[[CALL13]] +// CK19: define {{.+}}[[CALL14]] +// CK19: define {{.+}}[[CALL15]] +// CK19: define {{.+}}[[CALL16]] +// CK19: define {{.+}}[[CALL17]] +// CK19: define {{.+}}[[CALL18]] +// CK19: define {{.+}}[[CALL19]] +// CK19: define {{.+}}[[CALL20]] +// CK19: define {{.+}}[[CALL21]] +// CK19: define {{.+}}[[CALL22]] +// CK19: define {{.+}}[[CALL23]] +// CK19: define {{.+}}[[CALL24]] +// CK19: define {{.+}}[[CALL25]] +// CK19: define {{.+}}[[CALL26]] +// CK19: define {{.+}}[[CALL27]] +// CK19: define {{.+}}[[CALL28]] +// CK19: define {{.+}}[[CALL29]] +// CK19: define {{.+}}[[CALL30]] +// CK19: define {{.+}}[[CALL31]] +// CK19: define {{.+}}[[CALL32]] +// CK19: define {{.+}}[[CALL33]] +// CK19: define {{.+}}[[CALL34]] +// CK19: define {{.+}}[[CALL35]] +// CK19: define {{.+}}[[CALL36]] +// CK19: define {{.+}}[[CALL37]] +// CK19: define {{.+}}[[CALL38]] +// CK19: define {{.+}}[[CALL39]] +// CK19: define {{.+}}[[CALL40]] +// CK19: define {{.+}}[[CALL41]] +// CK19: define {{.+}}[[CALL42]] +// CK19: define {{.+}}[[CALL43]] + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK20 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-64 +// RUN: %clang_cc1 -DCK20 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-64 +// RUN: %clang_cc1 -DCK20 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-32 +// RUN: %clang_cc1 -DCK20 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-32 +#ifdef CK20 + +// CK20: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK20: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK20: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20] +// CK20: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK20: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK20: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK20: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 12] +// CK20: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK20-LABEL: explicit_maps_references_and_function_args +void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], float *d){ + + int &aa = a; + float &bb = b; + int (&cc)[10] = c; + float *&dd = d; + + // Region 00 + // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK20-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK20-DAG: [[CPVAL0]] = bitcast i32* [[RVAR00:%.+]] to i8* + // CK20-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK20-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK20: call void [[CALL00:@.+]](i32* {{[^,]+}}) + #pragma omp target map(to:aa) + { + aa += 1; + } + + // Region 01 + // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK20-DAG: [[CBPVAL0]] = bitcast [10 x i32]* [[RVAR0:%.+]] to i8* + // CK20-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK20-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[RVAR00:%.+]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: [[RVAR0]] = load [10 x i32]*, [10 x i32]** [[VAR0:%[^,]+]] + // CK20-DAG: [[RVAR00]] = load [10 x i32]*, [10 x i32]** [[VAR0]] + + // CK20: call void [[CALL01:@.+]]([10 x i32]* {{[^,]+}}) + #pragma omp target map(to:cc[:5]) + { + cc[3] += 1; + } + + // Region 02 + // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK20-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8* + // CK20-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8* + + // CK20: call void [[CALL02:@.+]](float* {{[^,]+}}) + #pragma omp target map(from:b) + { + b += 1.0f; + } + + // Region 03 + // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK20-DAG: [[CBPVAL0]] = bitcast float* [[RVAR0:%.+]] to i8* + // CK20-DAG: [[CPVAL0]] = bitcast float* [[SEC0:%.+]] to i8* + // CK20-DAG: [[RVAR0]] = load float*, float** [[VAR0:%[^,]+]] + // CK20-DAG: [[SEC0]] = getelementptr {{.*}}float* [[RVAR00:%.+]], i{{.+}} 2 + // CK20-DAG: [[RVAR00]] = load float*, float** [[VAR0]] + + // CK20: call void [[CALL03:@.+]](float* {{[^,]+}}) + #pragma omp target map(from:d[2:3]) + { + d[2] += 1.0f; + } +} + +// CK20: define {{.+}}[[CALL00]] +// CK20: define {{.+}}[[CALL01]] +// CK20: define {{.+}}[[CALL02]] +// CK20: define {{.+}}[[CALL03]] + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK21 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-64 +// RUN: %clang_cc1 -DCK21 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-64 +// RUN: %clang_cc1 -DCK21 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-32 +// RUN: %clang_cc1 -DCK21 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-32 +#ifdef CK21 +// CK21: [[ST:%.+]] = type { i32, i32, float* } + +// CK21: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK21: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK21: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 492] +// CK21: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK21: [[SIZE02:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 500] +// CK21: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i32] [i32 34, i32 18] + +// CK21: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 492] +// CK21: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK21: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK21: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 34] + +// CK21: [[SIZE05:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] 4, i[[Z]] 4] +// CK21: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 3] + +// CK21-LABEL: explicit_maps_template_args_and_members + +template <int X, typename T> +struct CC { + T A; + int A2; + float *B; + + int foo(T arg) { + float la[X]; + T *lb; + + // Region 00 + // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK21-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK21-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK21-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0:%.+]], i{{.+}} 0, i{{.+}} 0 + + // CK21: call void [[CALL00:@.+]]([[ST]]* {{[^,]+}}) + #pragma omp target map(A) + { + A += 1; + } + + // Region 01 + // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK21-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK21-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK21-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK21-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0 + // CK21-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK21: call void [[CALL01:@.+]](i32* {{[^,]+}}) + #pragma omp target map(lb[:X]) + { + lb[4] += 1; + } + + // Region 02 + // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK21-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK21-DAG: [[CPVAL0]] = bitcast float** [[SEC0:%.+]] to i8* + // CK21-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + + // CK21-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK21-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK21-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK21-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK21-DAG: [[CBPVAL1]] = bitcast float** [[SEC0]] to i8* + // CK21-DAG: [[CPVAL1]] = bitcast float* [[SEC1:%.+]] to i8* + // CK21-DAG: [[SEC1]] = getelementptr {{.*}}float* [[RVAR1:%[^,]+]], i{{.+}} 123 + // CK21-DAG: [[RVAR1]] = load float*, float** [[SEC1_:%[^,]+]] + // CK21-DAG: [[SEC1_]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + + // CK21: call void [[CALL02:@.+]]([[ST]]* {{[^,]+}}) + #pragma omp target map(from:B[X:X+2]) + { + B[2] += 1.0f; + } + + // Region 03 + // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK21-DAG: [[CBPVAL0]] = bitcast [123 x float]* [[VAR0:%.+]] to i8* + // CK21-DAG: [[CPVAL0]] = bitcast [123 x float]* [[VAR0]] to i8* + + // CK21: call void [[CALL03:@.+]]([123 x float]* {{[^,]+}}) + #pragma omp target map(from:la) + { + la[3] += 1.0f; + } + + // Region 04 + // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK21-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK21-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + + // CK21: call void [[CALL04:@.+]](i32* {{[^,]+}}) + #pragma omp target map(from:arg) + { + arg +=1; + } + + // Make sure the extra flag is passed to the second map. + // Region 05 + // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}}) + // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK21-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK21-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK21-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 0 + + // CK21-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK21-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK21-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK21-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK21-DAG: [[CBPVAL1]] = bitcast [[ST]]* [[VAR1:%.+]] to i8* + // CK21-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK21-DAG: [[SEC1]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + + // CK21: call void [[CALL05:@.+]]([[ST]]* {{[^,]+}}) + #pragma omp target map(A, A2) + { + A += 1; + A2 += 1; + } + return A; + } +}; + +int explicit_maps_template_args_and_members(int a){ + CC<123,int> c; + return c.foo(a); +} + +// CK21: define {{.+}}[[CALL00]] +// CK21: define {{.+}}[[CALL01]] +// CK21: define {{.+}}[[CALL02]] +// CK21: define {{.+}}[[CALL03]] +// CK21: define {{.+}}[[CALL04]] +// CK21: define {{.+}}[[CALL05]] +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK22 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-64 +// RUN: %clang_cc1 -DCK22 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-64 +// RUN: %clang_cc1 -DCK22 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-32 +// RUN: %clang_cc1 -DCK22 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-32 +#ifdef CK22 + +// CK22-DAG: [[ST:%.+]] = type { float } +// CK22-DAG: [[STT:%.+]] = type { i32 } + +// CK22: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK22: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400] +// CK22: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}] +// CK22: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16] +// CK22: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20] +// CK22: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK22: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE06:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400] +// CK22: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE07:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}] +// CK22: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE08:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16] +// CK22: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20] +// CK22: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK22: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE11:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400] +// CK22: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE12:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}] +// CK22: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE13:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16] +// CK22: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK22: [[SIZE14:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20] +// CK22: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +int a; +int c[100]; +int *d; + +struct ST { + float fa; +}; + +ST sa ; +ST sc[100]; +ST *sd; + +template<typename T> +struct STT { + T fa; +}; + +STT<int> sta ; +STT<int> stc[100]; +STT<int> *std; + +// CK22-LABEL: explicit_maps_globals +int explicit_maps_globals(void){ + // Region 00 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast (i32* @a to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast (i32* @a to i8*), i8** [[P0]] + + // CK22: call void [[CALL00:@.+]](i32* {{[^,]+}}) + #pragma omp target map(a) + { a+=1; } + + // Region 01 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([100 x i32]* @c to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([100 x i32]* @c to i8*), i8** [[P0]] + + // CK22: call void [[CALL01:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(c) + { c[3]+=1; } + + // Region 02 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast (i32** @d to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast (i32** @d to i8*), i8** [[P0]] + + // CK22: call void [[CALL02:@.+]](i32** {{[^,]+}}) + #pragma omp target map(d) + { d[3]+=1; } + + // Region 03 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([100 x i32]* @c to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast (i32* getelementptr inbounds ([100 x i32], [100 x i32]* @c, i{{.+}} 0, i{{.+}} 1) to i8*), i8** [[P0]] + + // CK22: call void [[CALL03:@.+]]([100 x i32]* {{[^,]+}}) + #pragma omp target map(c[1:4]) + { c[3]+=1; } + + // Region 04 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK22-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK22-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK22-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK22-DAG: [[RVAR0]] = load i32*, i32** @d + // CK22-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 2 + // CK22-DAG: [[RVAR00]] = load i32*, i32** @d + + // CK22: call void [[CALL04:@.+]](i32* {{[^,]+}}) + #pragma omp target map(d[2:5]) + { d[3]+=1; } + + // Region 05 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([[ST]]* @sa to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([[ST]]* @sa to i8*), i8** [[P0]] + + // CK22: call void [[CALL05:@.+]]([[ST]]* {{[^,]+}}) + #pragma omp target map(sa) + { sa.fa+=1; } + + // Region 06 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([100 x [[ST]]]* @sc to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([100 x [[ST]]]* @sc to i8*), i8** [[P0]] + + // CK22: call void [[CALL06:@.+]]([100 x [[ST]]]* {{[^,]+}}) + #pragma omp target map(sc) + { sc[3].fa+=1; } + + // Region 07 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([[ST]]** @sd to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([[ST]]** @sd to i8*), i8** [[P0]] + + // CK22: call void [[CALL07:@.+]]([[ST]]** {{[^,]+}}) + #pragma omp target map(sd) + { sd[3].fa+=1; } + + // Region 08 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([100 x [[ST]]]* @sc to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([[ST]]* getelementptr inbounds ([100 x [[ST]]], [100 x [[ST]]]* @sc, i{{.+}} 0, i{{.+}} 1) to i8*), i8** [[P0]] + + // CK22: call void [[CALL08:@.+]]([100 x [[ST]]]* {{[^,]+}}) + #pragma omp target map(sc[1:4]) + { sc[3].fa+=1; } + + // Region 09 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK22-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK22-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[RVAR0:%.+]] to i8* + // CK22-DAG: [[CPVAL0]] = bitcast [[ST]]* [[SEC0:%.+]] to i8* + // CK22-DAG: [[RVAR0]] = load [[ST]]*, [[ST]]** @sd + // CK22-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[RVAR00:%.+]], i{{.+}} 2 + // CK22-DAG: [[RVAR00]] = load [[ST]]*, [[ST]]** @sd + + // CK22: call void [[CALL09:@.+]]([[ST]]* {{[^,]+}}) + #pragma omp target map(sd[2:5]) + { sd[3].fa+=1; } + + // Region 10 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([[STT]]* @sta to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([[STT]]* @sta to i8*), i8** [[P0]] + + // CK22: call void [[CALL10:@.+]]([[STT]]* {{[^,]+}}) + #pragma omp target map(sta) + { sta.fa+=1; } + + // Region 11 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([100 x [[STT]]]* @stc to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([100 x [[STT]]]* @stc to i8*), i8** [[P0]] + + // CK22: call void [[CALL11:@.+]]([100 x [[STT]]]* {{[^,]+}}) + #pragma omp target map(stc) + { stc[3].fa+=1; } + + // Region 12 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([[STT]]** @std to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([[STT]]** @std to i8*), i8** [[P0]] + + // CK22: call void [[CALL12:@.+]]([[STT]]** {{[^,]+}}) + #pragma omp target map(std) + { std[3].fa+=1; } + + // Region 13 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* bitcast ([100 x [[STT]]]* @stc to i8*), i8** [[BP0]] + // CK22-DAG: store i8* bitcast ([[STT]]* getelementptr inbounds ([100 x [[STT]]], [100 x [[STT]]]* @stc, i{{.+}} 0, i{{.+}} 1) to i8*), i8** [[P0]] + + // CK22: call void [[CALL13:@.+]]([100 x [[STT]]]* {{[^,]+}}) + #pragma omp target map(stc[1:4]) + { stc[3].fa+=1; } + + // Region 14 + // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}}) + // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK22-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK22-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK22-DAG: [[CBPVAL0]] = bitcast [[STT]]* [[RVAR0:%.+]] to i8* + // CK22-DAG: [[CPVAL0]] = bitcast [[STT]]* [[SEC0:%.+]] to i8* + // CK22-DAG: [[RVAR0]] = load [[STT]]*, [[STT]]** @std + // CK22-DAG: [[SEC0]] = getelementptr {{.*}}[[STT]]* [[RVAR00:%.+]], i{{.+}} 2 + // CK22-DAG: [[RVAR00]] = load [[STT]]*, [[STT]]** @std + + // CK22: call void [[CALL14:@.+]]([[STT]]* {{[^,]+}}) + #pragma omp target map(std[2:5]) + { std[3].fa+=1; } + + return 0; +} +// CK22: define {{.+}}[[CALL00]] +// CK22: define {{.+}}[[CALL01]] +// CK22: define {{.+}}[[CALL02]] +// CK22: define {{.+}}[[CALL03]] +// CK22: define {{.+}}[[CALL04]] +// CK22: define {{.+}}[[CALL05]] +// CK22: define {{.+}}[[CALL06]] +// CK22: define {{.+}}[[CALL07]] +// CK22: define {{.+}}[[CALL08]] +// CK22: define {{.+}}[[CALL09]] +// CK22: define {{.+}}[[CALL10]] +// CK22: define {{.+}}[[CALL11]] +// CK22: define {{.+}}[[CALL12]] +// CK22: define {{.+}}[[CALL13]] +// CK22: define {{.+}}[[CALL14]] +#endif +///==========================================================================/// +// RUN: %clang_cc1 -std=c++11 -DCK23 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-64 +// RUN: %clang_cc1 -std=c++11 -DCK23 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-64 +// RUN: %clang_cc1 -std=c++11 -DCK23 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-32 +// RUN: %clang_cc1 -std=c++11 -DCK23 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-32 +#ifdef CK23 + +// CK23: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK23: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK23: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK23: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK23: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400] +// CK23: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK23: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}] +// CK23: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK23: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16] +// CK23: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK23: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16] +// CK23: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK23-LABEL: explicit_maps_inside_captured +int explicit_maps_inside_captured(int a){ + float b; + float c[100]; + float *d; + + // CK23: call void @{{.*}}explicit_maps_inside_captured{{.*}}([[SA:%.+]]* {{.*}}) + // CK23: define {{.*}}explicit_maps_inside_captured{{.*}} + [&](void){ + // Region 00 + // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK23-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK23-DAG: [[CPVAL0]] = bitcast i32* [[VAR00:%.+]] to i8* + // CK23-DAG: [[VAR0]] = load i32*, i32** [[CAP0:%[^,]+]] + // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]] + // CK23-DAG: [[VAR00]] = load i32*, i32** [[CAP00:%[^,]+]] + // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]] + + // CK23: call void [[CALL00:@.+]](i32* {{[^,]+}}) + #pragma omp target map(a) + { a+=1; } + // Region 01 + // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK23-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8* + // CK23-DAG: [[CPVAL0]] = bitcast float* [[VAR00:%.+]] to i8* + // CK23-DAG: [[VAR0]] = load float*, float** [[CAP0:%[^,]+]] + // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]] + // CK23-DAG: [[VAR00]] = load float*, float** [[CAP00:%[^,]+]] + // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]] + + // CK23: call void [[CALL01:@.+]](float* {{[^,]+}}) + #pragma omp target map(b) + { b+=1; } + // Region 02 + // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK23-DAG: [[CBPVAL0]] = bitcast [100 x float]* [[VAR0:%.+]] to i8* + // CK23-DAG: [[CPVAL0]] = bitcast [100 x float]* [[VAR00:%.+]] to i8* + // CK23-DAG: [[VAR0]] = load [100 x float]*, [100 x float]** [[CAP0:%[^,]+]] + // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]] + // CK23-DAG: [[VAR00]] = load [100 x float]*, [100 x float]** [[CAP00:%[^,]+]] + // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]] + + // CK23: call void [[CALL02:@.+]]([100 x float]* {{[^,]+}}) + #pragma omp target map(c) + { c[3]+=1; } + + // Region 03 + // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK23-DAG: [[CBPVAL0]] = bitcast float** [[VAR0:%.+]] to i8* + // CK23-DAG: [[CPVAL0]] = bitcast float** [[VAR00:%.+]] to i8* + // CK23-DAG: [[VAR0]] = load float**, float*** [[CAP0:%[^,]+]] + // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]] + // CK23-DAG: [[VAR00]] = load float**, float*** [[CAP00:%[^,]+]] + // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]] + + // CK23: call void [[CALL03:@.+]](float** {{[^,]+}}) + #pragma omp target map(d) + { d[3]+=1; } + // Region 04 + // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK23-DAG: [[CBPVAL0]] = bitcast [100 x float]* [[VAR0:%.+]] to i8* + // CK23-DAG: [[CPVAL0]] = bitcast float* [[SEC0:%.+]] to i8* + // CK23-DAG: [[SEC0]] = getelementptr {{.*}}[100 x float]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2 + // CK23-DAG: [[VAR0]] = load [100 x float]*, [100 x float]** [[CAP0:%[^,]+]] + // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]] + // CK23-DAG: [[VAR00]] = load [100 x float]*, [100 x float]** [[CAP00:%[^,]+]] + // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]] + + // CK23: call void [[CALL04:@.+]]([100 x float]* {{[^,]+}}) + #pragma omp target map(c[2:4]) + { c[3]+=1; } + + // Region 05 + // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}}) + // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK23-DAG: [[CBPVAL0]] = bitcast float* [[RVAR0:%.+]] to i8* + // CK23-DAG: [[CPVAL0]] = bitcast float* [[SEC0:%.+]] to i8* + // CK23-DAG: [[RVAR0]] = load float*, float** [[VAR0:%[^,]+]] + // CK23-DAG: [[SEC0]] = getelementptr {{.*}}float* [[RVAR00:%.+]], i{{.+}} 2 + // CK23-DAG: [[RVAR00]] = load float*, float** [[VAR00:%[^,]+]] + // CK23-DAG: [[VAR0]] = load float**, float*** [[CAP0:%[^,]+]] + // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]] + // CK23-DAG: [[VAR00]] = load float**, float*** [[CAP00:%[^,]+]] + // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]] + + // CK23: call void [[CALL05:@.+]](float* {{[^,]+}}) + #pragma omp target map(d[2:4]) + { d[3]+=1; } + }(); + return b; +} + +// CK23: define {{.+}}[[CALL00]] +// CK23: define {{.+}}[[CALL01]] +// CK23: define {{.+}}[[CALL02]] +// CK23: define {{.+}}[[CALL03]] +// CK23: define {{.+}}[[CALL04]] +// CK23: define {{.+}}[[CALL05]] +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK24 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-64 +// RUN: %clang_cc1 -DCK24 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-64 +// RUN: %clang_cc1 -DCK24 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-32 +// RUN: %clang_cc1 -DCK24 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-32 +#ifdef CK24 + +// CK24-DAG: [[SC:%.+]] = type { i32, [[SB:%.+]], [[SB:%.+]]*, [10 x i32] } +// CK24-DAG: [[SB]] = type { i32, [[SA:%.+]], [10 x [[SA:%.+]]], [10 x [[SA:%.+]]*], [[SA:%.+]]* } +// CK24-DAG: [[SA]] = type { i32, [[SA]]*, [10 x i32] } + +struct SA{ + int a; + struct SA *p; + int b[10]; +}; +struct SB{ + int a; + struct SA s; + struct SA sa[10]; + struct SA *sp[10]; + struct SA *p; +}; +struct SC{ + int a; + struct SB s; + struct SB *p; + int b[10]; +}; + +// CK24: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK24: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{56|48}}] +// CK24: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK24: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20] +// CK24: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE05:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{3560|2880}}] +// CK24: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE06:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK24: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE07:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE07:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE08:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE08:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE09:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE09:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 8] +// CK24: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE11:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}] +// CK24: [[MTYPE11:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE12:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE12:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 19, i32 19, i32 19] + +// CK24: [[SIZE13:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK24: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE14:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{56|48}}] +// CK24: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE15:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK24: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE16:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20] +// CK24: [[MTYPE16:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE17:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{3560|2880}}] +// CK24: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE18:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK24: [[MTYPE18:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE19:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE20:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE21:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE22:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}] +// CK24: [[MTYPE22:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK24: [[SIZE23:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}] +// CK24: [[MTYPE23:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19] + +// CK24: [[SIZE24:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4] +// CK24: [[MTYPE24:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 19, i32 19, i32 19] + +// CK24-LABEL: explicit_maps_struct_fields +int explicit_maps_struct_fields(int a){ + SC s; + SC *p; + +// Region 01 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 0 + +// CK24: call void [[CALL01:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.a) + { s.a++; } + +// Region 02 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL02:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.s) + { s.a++; } + +// Region 03 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL03:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.s.a) + { s.a++; } + +// Region 04 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 3 + +// CK24: call void [[CALL04:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.b[:5]) + { s.a++; } + +// Region 05 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast [[SB]]* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24: call void [[CALL05:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.p[:5]) + { s.a++; } + +// Region 06 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[10 x [[SA]]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL06:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.sa[3].a) + { s.a++; } + +// Region 07 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE07]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC1111:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL07:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.sp[3]->a) + { s.a++; } + +// Region 08 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE08]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24: call void [[CALL08:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.p->a) + { s.a++; } + +// Region 09 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE09]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SB]]* [[SEC1111:[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL09:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.p->a) + { s.a++; } + +// Region 10 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SA]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL10:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.s.b[:2]) + { s.a++; } + +// Region 11 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE11]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[10 x i32]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC11]] = getelementptr {{.*}}[[SA]]* [[SEC111:%[^,]+]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[SEC111]] = load [[SA]]*, [[SA]]** [[SEC1111:%[^,]+]], +// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1 + +// CK24: call void [[CALL11:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.s.p->b[:2]) + { s.a++; } + +// Region 12 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE12]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast [[SA]]** [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] +// CK24-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] +// CK24-DAG: [[CBPVAL2]] = bitcast [[SA]]** [[SEC1]] to i8* +// CK24-DAG: [[CPVAL2]] = bitcast [[SA]]** [[SEC2:%.+]] to i8* +// CK24-DAG: [[SEC2]] = getelementptr {{.*}}[[SA]]* [[SEC22:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC22]] = load [[SA]]*, [[SA]]** [[SEC222:%[^,]+]], +// CK24-DAG: [[SEC222]] = getelementptr {{.*}}[[SB]]* [[SEC2222:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC2222]] = load [[SB]]*, [[SB]]** [[SEC22222:%[^,]+]], +// CK24-DAG: [[SEC22222]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]] +// CK24-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]] +// CK24-DAG: [[CBPVAL3]] = bitcast [[SA]]** [[SEC2]] to i8* +// CK24-DAG: [[CPVAL3]] = bitcast i32* [[SEC3:%.+]] to i8* +// CK24-DAG: [[SEC3]] = getelementptr {{.*}}[[SA]]* [[SEC33:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC33]] = load [[SA]]*, [[SA]]** [[SEC333:%[^,]+]], +// CK24-DAG: [[SEC333]] = getelementptr {{.*}}[[SA]]* [[SEC3333:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC3333]] = load [[SA]]*, [[SA]]** [[SEC33333:%[^,]+]], +// CK24-DAG: [[SEC33333]] = getelementptr {{.*}}[[SB]]* [[SEC333333:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC333333]] = load [[SB]]*, [[SB]]** [[SEC3333333:%[^,]+]], +// CK24-DAG: [[SEC3333333]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2 + +// CK24: call void [[CALL12:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(s.p->p->p->a) + { s.a++; } + +// +// Same thing but starting from a pointer. +// +// Region 13 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 0 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL13:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->a) + { p->a++; } + +// Region 14 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL14:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.s) + { p->a++; } + +// Region 15 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL15:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.s.a) + { p->a++; } + +// Region 16 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE16]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE16]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 3 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL16:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->b[:5]) + { p->a++; } + +// Region 17 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast [[SB]]* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL17:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->p[:5]) + { p->a++; } + +// Region 18 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE18]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[10 x [[SA]]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL18:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.sa[3].a) + { p->a++; } + +// Region 19 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE19]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC1111:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL19:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.sp[3]->a) + { p->a++; } + +// Region 20 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL20:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->p->a) + { p->a++; } + +// Region 21 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE21]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0 +// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SB]]* [[SEC1111:[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL21:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.p->a) + { p->a++; } + +// Region 22 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE22]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SA]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL22:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.s.b[:2]) + { p->a++; } + +// Region 23 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE23]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[10 x i32]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC11]] = getelementptr {{.*}}[[SA]]* [[SEC111:%[^,]+]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[SEC111]] = load [[SA]]*, [[SA]]** [[SEC1111:%[^,]+]], +// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 1 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL23:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->s.p->b[:2]) + { p->a++; } + +// Region 24 +// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE24]]{{.+}}) +// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8* +// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8* +// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8* +// CK24-DAG: [[CPVAL1]] = bitcast [[SA]]** [[SEC1:%.+]] to i8* +// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]], +// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2 +// CK24-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]] +// CK24-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]] +// CK24-DAG: [[CBPVAL2]] = bitcast [[SA]]** [[SEC1]] to i8* +// CK24-DAG: [[CPVAL2]] = bitcast [[SA]]** [[SEC2:%.+]] to i8* +// CK24-DAG: [[SEC2]] = getelementptr {{.*}}[[SA]]* [[SEC22:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC22]] = load [[SA]]*, [[SA]]** [[SEC222:%[^,]+]], +// CK24-DAG: [[SEC222]] = getelementptr {{.*}}[[SB]]* [[SEC2222:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC2222]] = load [[SB]]*, [[SB]]** [[SEC22222:%[^,]+]], +// CK24-DAG: [[SEC22222]] = getelementptr {{.*}}[[SC]]* [[VAR0000:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3 +// CK24-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]] +// CK24-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]] +// CK24-DAG: [[CBPVAL3]] = bitcast [[SA]]** [[SEC2]] to i8* +// CK24-DAG: [[CPVAL3]] = bitcast i32* [[SEC3:%.+]] to i8* +// CK24-DAG: [[SEC3]] = getelementptr {{.*}}[[SA]]* [[SEC33:%[^,]+]], i{{.+}} 0, i{{.+}} 0 +// CK24-DAG: [[SEC33]] = load [[SA]]*, [[SA]]** [[SEC333:%[^,]+]], +// CK24-DAG: [[SEC333]] = getelementptr {{.*}}[[SA]]* [[SEC3333:%[^,]+]], i{{.+}} 0, i{{.+}} 1 +// CK24-DAG: [[SEC3333]] = load [[SA]]*, [[SA]]** [[SEC33333:%[^,]+]], +// CK24-DAG: [[SEC33333]] = getelementptr {{.*}}[[SB]]* [[SEC333333:%[^,]+]], i{{.+}} 0, i{{.+}} 4 +// CK24-DAG: [[SEC333333]] = load [[SB]]*, [[SB]]** [[SEC3333333:%[^,]+]], +// CK24-DAG: [[SEC3333333]] = getelementptr {{.*}}[[SC]]* [[VAR00000:%.+]], i{{.+}} 0, i{{.+}} 2 + +// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR0000]] = load [[SC]]*, [[SC]]** %{{.+}} +// CK24-DAG: [[VAR00000]] = load [[SC]]*, [[SC]]** %{{.+}} + +// CK24: call void [[CALL24:@.+]]([[SC]]* {{[^,]+}}) +#pragma omp target map(p->p->p->p->a) + { p->a++; } + + return s.a; +} + +// CK24: define {{.+}}[[CALL01]] +// CK24: define {{.+}}[[CALL02]] +// CK24: define {{.+}}[[CALL03]] +// CK24: define {{.+}}[[CALL04]] +// CK24: define {{.+}}[[CALL05]] +// CK24: define {{.+}}[[CALL06]] +// CK24: define {{.+}}[[CALL07]] +// CK24: define {{.+}}[[CALL08]] +// CK24: define {{.+}}[[CALL09]] +// CK24: define {{.+}}[[CALL10]] +// CK24: define {{.+}}[[CALL11]] +// CK24: define {{.+}}[[CALL12]] +// CK24: define {{.+}}[[CALL13]] +// CK24: define {{.+}}[[CALL14]] +// CK24: define {{.+}}[[CALL15]] +// CK24: define {{.+}}[[CALL16]] +// CK24: define {{.+}}[[CALL17]] +// CK24: define {{.+}}[[CALL18]] +// CK24: define {{.+}}[[CALL19]] +// CK24: define {{.+}}[[CALL20]] +// CK24: define {{.+}}[[CALL21]] +// CK24: define {{.+}}[[CALL22]] +// CK24: define {{.+}}[[CALL23]] +// CK24: define {{.+}}[[CALL24]] +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK25 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-64 +// RUN: %clang_cc1 -DCK25 -std=c++11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-64 +// RUN: %clang_cc1 -DCK25 -std=c++11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-32 +// RUN: %clang_cc1 -DCK25 -std=c++11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-32 +#ifdef CK25 +// CK25: [[ST:%.+]] = type { i32, float } +// CK25: [[CA00:%.+]] = type { [[ST]]* } +// CK25: [[CA01:%.+]] = type { i32* } + +// CK25: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] +// CK25: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK25: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK25: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33] + +// CK25-LABEL: explicit_maps_with_inner_lambda + +template <int X, typename T> +struct CC { + T A; + float B; + + int foo(T arg) { + // Region 00 + // CK25-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK25-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK25-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK25-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK25-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK25-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK25-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK25-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK25-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK25-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0:%.+]], i{{.+}} 0, i{{.+}} 0 + + // CK25: call void [[CALL00:@.+]]([[ST]]* {{[^,]+}}) + #pragma omp target map(to:A) + { + [&]() { + A += 1; + }(); + } + + // Region 01 + // CK25-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK25-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK25-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK25-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK25-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK25-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK25-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK25-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK25-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + + // CK25: call void [[CALL01:@.+]](i32* {{[^,]+}}) + #pragma omp target map(to:arg) + { + [&]() { + arg += 1; + }(); + } + + return A+arg; + } +}; + +int explicit_maps_with_inner_lambda(int a){ + CC<123,int> c; + return c.foo(a); +} + +// CK25: define {{.+}}[[CALL00]]([[ST]]* [[VAL:%.+]]) +// CK25: store [[ST]]* [[VAL]], [[ST]]** [[VALADDR:%[^,]+]], +// CK25: [[VAL1:%.+]] = load [[ST]]*, [[ST]]** [[VALADDR]], +// CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA00]], [[CA00]]* [[CA:%[^,]+]], i32 0, i32 0 +// CK25: store [[ST]]* [[VAL1]], [[ST]]** [[VALADDR1]], +// CK25: call void {{.*}}[[LAMBDA:@.+]]{{.*}}([[CA00]]* [[CA]]) + +// CK25: define {{.+}}[[LAMBDA]] + +// CK25: define {{.+}}[[CALL01]](i32* {{.*}}[[VAL:%.+]]) +// CK25: store i32* [[VAL]], i32** [[VALADDR:%[^,]+]], +// CK25: [[VAL1:%.+]] = load i32*, i32** [[VALADDR]], +// CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA01]], [[CA01]]* [[CA:%[^,]+]], i32 0, i32 0 +// CK25: store i32* [[VAL1]], i32** [[VALADDR1]], +// CK25: call void {{.*}}[[LAMBDA]]{{.*}}([[CA01]]* [[CA]]) +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64 +// RUN: %clang_cc1 -DCK26 -std=c++11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64 +// RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-32 +// RUN: %clang_cc1 -DCK26 -std=c++11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-32 +#ifdef CK26 +// CK26: [[ST:%.+]] = type { i32, float*, i32, float* } + +// CK26: [[SIZE00:@.+]] = private {{.*}}constant [2 x i[[Z:64|32]]] [i[[Z:64|32]] {{32|16}}, i[[Z:64|32]] 4] +// CK26: [[MTYPE00:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35] + +// CK26: [[SIZE01:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4] +// CK26: [[MTYPE01:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35] + +// CK26: [[SIZE02:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4] +// CK26: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35] + +// CK26: [[SIZE03:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4] +// CK26: [[MTYPE03:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35] + +// CK26-LABEL: explicit_maps_with_private_class_members + +struct CC { + int fA; + float &fB; + int pA; + float &pB; + + CC(float &B) : fB(B), pB(B) { + + // CK26: call {{.*}}@__kmpc_fork_call{{.*}} [[OUTCALL:@.+]] to void (i32*, i32*, ...)* + // define {{.*}}void [[OUTCALL]] + #pragma omp parallel firstprivate(fA,fB) private(pA,pB) + { + // Region 00 + // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8* + + // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK26-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK26-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK26-DAG: [[VAR1]] = load i32*, i32** [[PVT:%.+]], + // CK26-DAG: [[SEC1]] = load i32*, i32** [[PVT]], + + // CK26: call void [[CALL00:@.+]]([[ST]]* {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(fA) + { + ++fA; + } + + // Region 01 + // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8* + + // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK26-DAG: [[CBPVAL1]] = bitcast float* [[VAR1:%.+]] to i8* + // CK26-DAG: [[CPVAL1]] = bitcast float* [[SEC1:%.+]] to i8* + // CK26-DAG: [[VAR1]] = load float*, float** [[PVT:%.+]], + // CK26-DAG: [[SEC1]] = load float*, float** [[PVT]], + + // CK26: call void [[CALL01:@.+]]([[ST]]* {{[^,]+}}, float* {{[^,]+}}) + #pragma omp target map(fB) + { + fB += 1.0; + } + + // Region 02 + // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8* + + // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK26-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8* + // CK26-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8* + // CK26-DAG: [[VAR1]] = load i32*, i32** [[PVT:%.+]], + // CK26-DAG: [[SEC1]] = load i32*, i32** [[PVT]], + + // CK26: call void [[CALL02:@.+]]([[ST]]* {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp target map(pA) + { + ++pA; + } + + // Region 01 + // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* + // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8* + + // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] + // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK26-DAG: [[CBPVAL1]] = bitcast float* [[VAR1:%.+]] to i8* + // CK26-DAG: [[CPVAL1]] = bitcast float* [[SEC1:%.+]] to i8* + // CK26-DAG: [[VAR1]] = load float*, float** [[PVT:%.+]], + // CK26-DAG: [[SEC1]] = load float*, float** [[PVT]], + + // CK26: call void [[CALL03:@.+]]([[ST]]* {{[^,]+}}, float* {{[^,]+}}) + #pragma omp target map(pB) + { + pB += 1.0; + } + } + } + + int foo() { + return fA + pA; + } +}; + +// Make sure the private instance is used in all target regions. +// CK26: define {{.+}}[[CALL00]]({{.*}}i32*{{.*}}[[PVTARG:%.+]]) +// CK26: store i32* [[PVTARG]], i32** [[PVTADDR:%.+]], +// CK26: [[ADDR:%.+]] = load i32*, i32** [[PVTADDR]], +// CK26: [[VAL:%.+]] = load i32, i32* [[ADDR]], +// CK26: add nsw i32 [[VAL]], 1 + +// CK26: define {{.+}}[[CALL01]]({{.*}}float*{{.*}}[[PVTARG:%.+]]) +// CK26: store float* [[PVTARG]], float** [[PVTADDR:%.+]], +// CK26: [[ADDR:%.+]] = load float*, float** [[PVTADDR]], +// CK26: [[VAL:%.+]] = load float, float* [[ADDR]], +// CK26: [[EXT:%.+]] = fpext float [[VAL]] to double +// CK26: fadd double [[EXT]], 1.000000e+00 + +// CK26: define {{.+}}[[CALL02]]({{.*}}i32*{{.*}}[[PVTARG:%.+]]) +// CK26: store i32* [[PVTARG]], i32** [[PVTADDR:%.+]], +// CK26: [[ADDR:%.+]] = load i32*, i32** [[PVTADDR]], +// CK26: [[VAL:%.+]] = load i32, i32* [[ADDR]], +// CK26: add nsw i32 [[VAL]], 1 + +// CK26: define {{.+}}[[CALL03]]({{.*}}float*{{.*}}[[PVTARG:%.+]]) +// CK26: store float* [[PVTARG]], float** [[PVTADDR:%.+]], +// CK26: [[ADDR:%.+]] = load float*, float** [[PVTADDR]], +// CK26: [[VAL:%.+]] = load float, float* [[ADDR]], +// CK26: [[EXT:%.+]] = fpext float [[VAL]] to double +// CK26: fadd double [[EXT]], 1.000000e+00 + +int explicit_maps_with_private_class_members(){ + float B; + CC c(B); + return c.foo(); +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK27 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-64 +// RUN: %clang_cc1 -DCK27 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-64 +// RUN: %clang_cc1 -DCK27 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-32 +// RUN: %clang_cc1 -DCK27 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-32 +#ifdef CK27 + +// CK27: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] zeroinitializer +// CK27: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK27: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer +// CK27: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK27: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer +// CK27: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK27: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer +// CK27: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35] + +// CK27: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer +// CK27: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 32] + +// CK27: [[SIZE07:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4] +// CK27: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 288] + +// CK27: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 40] +// CK27: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 161] + +// CK27-LABEL: zero_size_section_and_private_maps +void zero_size_section_and_private_maps (int ii){ + + // Map of a pointer. + int *pa; + + // Region 00 + // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK27-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + + // CK27: call void [[CALL00:@.+]](i32* {{[^,]+}}) + #pragma omp target + { + pa[50]++; + } + + // Region 01 + // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}}) + // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK27-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK27-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK27-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0 + // CK27-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK27: call void [[CALL01:@.+]](i32* {{[^,]+}}) + #pragma omp target map(pa[:0]) + { + pa[50]++; + } + + // Region 02 + // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK27-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK27-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK27-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0 + // CK27-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK27: call void [[CALL02:@.+]](i32* {{[^,]+}}) + #pragma omp target map(pa[0:0]) + { + pa[50]++; + } + + // Region 03 + // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8* + // CK27-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8* + // CK27-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]] + // CK27-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} %{{.+}} + // CK27-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]] + + // CK27: call void [[CALL03:@.+]](i32* {{[^,]+}}) + #pragma omp target map(pa[ii:0]) + { + pa[50]++; + } + + int *pvtPtr; + int pvtScl; + int pvtArr[10]; + + // Region 04 + // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null) + // CK27: call void [[CALL04:@.+]]() + #pragma omp target private(pvtPtr) + { + pvtPtr[5]++; + } + + // Region 05 + // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}}) + // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK27-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + + // CK27: call void [[CALL05:@.+]](i32* {{[^,]+}}) + #pragma omp target firstprivate(pvtPtr) + { + pvtPtr[5]++; + } + + // Region 06 + // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null) + // CK27: call void [[CALL06:@.+]]() + #pragma omp target private(pvtScl) + { + pvtScl++; + } + + // Region 07 + // CK27-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZE07]]{{.+}}, {{.+}}[[MTYPE07]]{{.+}}) + // CK27-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK27-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK27-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK27-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK27-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK27-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK27-DAG: [[VALBP]] = inttoptr i[[Z]] [[VAL:%.+]] to i8* + // CK27-DAG: [[VALP]] = inttoptr i[[Z]] [[VAL:%.+]] to i8* + // CK27-DAG: [[VAL]] = load i[[Z]], i[[Z]]* [[ADDR:%.+]], + // CK27-64-DAG: [[CADDR:%.+]] = bitcast i[[Z]]* [[ADDR]] to i32* + // CK27-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK27: call void [[CALL07:@.+]](i[[Z]] [[VAL]]) + #pragma omp target firstprivate(pvtScl) + { + pvtScl++; + } + + // Region 08 + // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null) + // CK27: call void [[CALL08:@.+]]() + #pragma omp target private(pvtArr) + { + pvtArr[5]++; + } + + // Region 09 + // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}}) + // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK27-DAG: [[CBPVAL0]] = bitcast [10 x i32]* [[VAR0:%.+]] to i8* + // CK27-DAG: [[CPVAL0]] = bitcast [10 x i32]* [[VAR0]] to i8* + + // CK27: call void [[CALL09:@.+]]([10 x i32]* {{[^,]+}}) + #pragma omp target firstprivate(pvtArr) + { + pvtArr[5]++; + } +} + +// CK27: define {{.+}}[[CALL00]] +// CK27: define {{.+}}[[CALL01]] +// CK27: define {{.+}}[[CALL02]] +// CK27: define {{.+}}[[CALL03]] +// CK27: define {{.+}}[[CALL04]] +// CK27: define {{.+}}[[CALL05]] +// CK27: define {{.+}}[[CALL06]] +// CK27: define {{.+}}[[CALL07]] +#endif #endif diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp index d61e766c6b4b2..543f47f8216a8 100644 --- a/test/OpenMP/target_map_messages.cpp +++ b/test/OpenMP/target_map_messages.cpp @@ -1,5 +1,299 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 200 %s +// RUN: %clang_cc1 -DCCODE -verify -fopenmp -ferror-limit 200 -x c %s +#ifdef CCODE +void foo(int arg) { + const int n = 0; + double marr[10][10][10]; + + #pragma omp target map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:][0:][:]) + {} + #pragma omp target map(marr[:][1:][:]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:][n:][:]) + {} +} +#else +template <typename T, int I> +struct SA { + static int ss; + #pragma omp threadprivate(ss) // expected-note {{defined as threadprivate or thread local}} + float a; + int b[12]; + float *c; + T d; + float e[I]; + T *f; + void func(int arg) { + #pragma omp target map(arg,a,d) + {} + #pragma omp target map(arg[2:2],a,d) // expected-error {{subscripted value is not an array or pointer}} + {} + #pragma omp target map(arg,a*2) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + {} + #pragma omp target map(arg,(c+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + {} + #pragma omp target map(arg,a[:2],d) // expected-error {{subscripted value is not an array or pointer}} + {} + #pragma omp target map(arg,a,d[:2]) // expected-error {{subscripted value is not an array or pointer}} + {} + + #pragma omp target map(to:ss) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + {} + + #pragma omp target map(to:b,e) + {} + #pragma omp target map(to:b,e) map(to:b) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + {} + #pragma omp target map(to:b[:2],e) + {} + #pragma omp target map(to:b,e[:]) + {} + + #pragma omp target map(always, tofrom: c,f) + {} + #pragma omp target map(always, tofrom: c[1:2],f) + {} + #pragma omp target map(always, tofrom: c,f[1:2]) + {} + #pragma omp target map(always, tofrom: c[:],f) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} + #pragma omp target map(always, tofrom: c,f[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} + return; + } +}; + +struct SB { + unsigned A; + unsigned B; + float Arr[100]; + float *Ptr; + float *foo() { + return &Arr[0]; + } +}; + +struct SC { + unsigned A : 2; + unsigned B : 3; + unsigned C; + unsigned D; + float Arr[100]; + SB S; + SB ArrS[100]; + SB *PtrS; + SB *&RPtrS; + float *Ptr; + + SC(SB *&_RPtrS) : RPtrS(_RPtrS) {} +}; + +union SD { + unsigned A; + float B; +}; + +void SAclient(int arg) { + SA<int,123> s; + s.func(arg); // expected-note {{in instantiation of member function}} + double marr[10][10][10]; + double marr2[5][10][1]; + double mvla[5][arg][10]; + double ***mptr; + const int n = 0; + const int m = 1; + double mvla2[5][arg][m+n+10]; + + SB *p; + + SD u; + SC r(p),t(p); + #pragma omp target map(r) + {} + #pragma omp target map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[2][3][0:2]) + {} + #pragma omp target map(marr[:][:][:]) + {} + #pragma omp target map(marr[:2][:][:]) + {} + #pragma omp target map(marr[arg:][:][:]) + {} + #pragma omp target map(marr[arg:]) + {} + #pragma omp target map(marr[arg:][:arg][:]) // correct if arg is the size of dimension 2 + {} + #pragma omp target map(marr[:arg][:]) + {} + #pragma omp target map(marr[:arg][n:]) + {} + #pragma omp target map(marr[:][:arg][n:]) // correct if arg is the size of dimension 2 + {} + #pragma omp target map(marr[:][:m][n:]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[n:m][:arg][n:]) + {} + #pragma omp target map(marr[:2][:1][:]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:2][1:][:]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:2][:][:1]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:2][:][1:]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:1][:2][:]) + {} + #pragma omp target map(marr[:1][0][:]) + {} + #pragma omp target map(marr[:arg][:2][:]) // correct if arg is 1 + {} + #pragma omp target map(marr[:1][3:1][:2]) + {} + #pragma omp target map(marr[:1][3:arg][:2]) // correct if arg is 1 + {} + #pragma omp target map(marr[:1][3:2][:2]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr[:2][:10][:]) + {} + #pragma omp target map(marr[:2][:][:5+5]) + {} + #pragma omp target map(marr[:2][2+2-4:][0:5+5]) + {} + + #pragma omp target map(marr[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(marr2[:1][:2][0]) + {} + + #pragma omp target map(mvla[:1][:][0]) // correct if the size of dimension 2 is 1. + {} + #pragma omp target map(mvla[:2][:arg][:]) // correct if arg is the size of dimension 2. + {} + #pragma omp target map(mvla[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(mvla[1][2:arg][:]) + {} + #pragma omp target map(mvla[:1][:][:]) + {} + #pragma omp target map(mvla2[:1][:2][:11]) + {} + #pragma omp target map(mvla2[:1][:2][:10]) // expected-error {{array section does not specify contiguous storage}} + {} + + #pragma omp target map(mptr[:2][2+2-4:1][0:5+5]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(mptr[:1][:2-1][2:4-3]) + {} + #pragma omp target map(mptr[:1][:arg][2:4-3]) // correct if arg is 1. + {} + #pragma omp target map(mptr[:1][:2-1][0:2]) + {} + #pragma omp target map(mptr[:1][:2][0:2]) // expected-error {{array section does not specify contiguous storage}} + {} + #pragma omp target map(mptr[:1][:][0:2]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} + #pragma omp target map(mptr[:2][:1][0:2]) // expected-error {{array section does not specify contiguous storage}} + {} + + #pragma omp target map(r.ArrS[0].B) + {} + #pragma omp target map(r.ArrS[:1].B) // expected-error {{OpenMP array section is not allowed here}} + {} + #pragma omp target map(r.ArrS[:arg].B) // expected-error {{OpenMP array section is not allowed here}} + {} + #pragma omp target map(r.ArrS[0].Arr[1:23]) + {} + #pragma omp target map(r.ArrS[0].Arr[1:arg]) + {} + #pragma omp target map(r.ArrS[0].Arr[arg:23]) + {} + #pragma omp target map(r.ArrS[0].Error) // expected-error {{no member named 'Error' in 'SB'}} + {} + #pragma omp target map(r.ArrS[0].A, r.ArrS[1].A) // expected-error {{multiple array elements associated with the same variable are not allowed in map clauses of the same construct}} expected-note {{used here}} + {} + #pragma omp target map(r.ArrS[0].A, t.ArrS[1].A) + {} + #pragma omp target map(r.PtrS[0], r.PtrS->B) // expected-error {{same pointer derreferenced in multiple different ways in map clause expressions}} expected-note {{used here}} + {} + #pragma omp target map(r.RPtrS[0], r.RPtrS->B) // expected-error {{same pointer derreferenced in multiple different ways in map clause expressions}} expected-note {{used here}} + {} + #pragma omp target map(r.S.Arr[:12]) + {} + #pragma omp target map(r.S.foo()[:12]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + {} + #pragma omp target map(r.C, r.D) + {} + #pragma omp target map(r.C, r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + {} + #pragma omp target map(r.C) map(r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + {} + #pragma omp target map(r.C, r.S) // this would be an error only caught at runtime - Sema would have to make sure there is not way for the missing data between fields to be mapped somewhere else. + {} + #pragma omp target map(r, r.S) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + {} + #pragma omp target map(r.C, t.C) + {} + #pragma omp target map(r.A) // expected-error {{bit fields cannot be used to specify storage in a 'map' clause}} + {} + #pragma omp target map(r.Arr) + {} + #pragma omp target map(r.Arr[3:5]) + {} + #pragma omp target map(r.Ptr[3:5]) + {} + #pragma omp target map(r.ArrS[3:5].A) // expected-error {{OpenMP array section is not allowed here}} + {} + #pragma omp target map(r.ArrS[3:5].Arr[6:7]) // expected-error {{OpenMP array section is not allowed here}} + {} + #pragma omp target map(r.ArrS[3].Arr[6:7]) + {} + #pragma omp target map(r.S.Arr[4:5]) + {} + #pragma omp target map(r.S.Ptr[4:5]) + {} + #pragma omp target map(r.S.Ptr[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} + #pragma omp target map((p+1)->A) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + {} + #pragma omp target map(u.B) // expected-error {{mapped storage cannot be derived from a union}} + {} + + #pragma omp target data map(to: r.C) //expected-note {{used here}} + { + #pragma omp target map(r.D) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + {} + } + + #pragma omp target data map(to: t.Ptr) //expected-note {{used here}} + { + #pragma omp target map(t.Ptr[:23]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + {} + } + + #pragma omp target data map(to: t.C, t.D) + { + #pragma omp target data map(to: t.C) + { + #pragma omp target map(t.D) + {} + } + } + + #pragma omp target data map(to: t) + { + #pragma omp target data map(to: t.C) + { + #pragma omp target map(t.D) + {} + } + } +} void foo() { } @@ -62,25 +356,31 @@ T tmain(T argc) { T y; T to, tofrom, always; const T (&l)[5] = da; - - #pragma omp target map // expected-error {{expected '(' after 'map'}} + {} #pragma omp target map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + {} #pragma omp target map() // expected-error {{expected expression}} + {} #pragma omp target map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + {} #pragma omp target map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + {} #pragma omp target map(to:) // expected-error {{expected expression}} + {} #pragma omp target map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + {} #pragma omp target map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + {} #pragma omp target map(x) foo(); #pragma omp target map(tofrom: t[:I]) foo(); -#pragma omp target map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}} foo(); #pragma omp target map(T) // expected-error {{'T' does not refer to a value}} foo(); -#pragma omp target map(I) // expected-error 2 {{expected variable name, array element or array section}} +#pragma omp target map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} foo(); #pragma omp target map(S2::S2s) foo(); @@ -96,42 +396,41 @@ T tmain(T argc) { foo(); #pragma omp target map(to, x) foo(); -#pragma omp target map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} -#pragma omp target map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected variable name, array element or array section}} -#pragma omp target map(argc) -#pragma omp target map(S1) // expected-error {{'S1' does not refer to a value}} -#pragma omp target map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} -#pragma omp target map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} -#pragma omp target map(ca) -#pragma omp target map(da) -#pragma omp target map(S2::S2s) -#pragma omp target map(S2::S2sc) -#pragma omp target map(e, g) -#pragma omp target map(h) // expected-error {{threadprivate variables are not allowed in map clause}} -#pragma omp target map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} -#pragma omp target map(k), map(k[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} +#pragma omp target data map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} +#pragma omp target data map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target data map(argc) +#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target data map(ca) +#pragma omp target data map(da) +#pragma omp target data map(S2::S2s) +#pragma omp target data map(S2::S2sc) +#pragma omp target data map(e, g) +#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} +#pragma omp target data map(k) map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} +#pragma omp target map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}} foo(); -#pragma omp target map(da) +#pragma omp target data map(da) #pragma omp target map(da[:4]) foo(); -#pragma omp target map(k, j, l) // expected-note 4 {{used here}} -#pragma omp target map(k[:4]) // expected-error 2 {{variable already marked as mapped in current construct}} -#pragma omp target map(j) -#pragma omp target map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} +#pragma omp target data map(k, j, l) // expected-note 2 {{used here}} +#pragma omp target data map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} +#pragma omp target data map(j) +#pragma omp target map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} foo(); -#pragma omp target map(k[:4], j, l[:5]) // expected-note 4 {{used here}} -#pragma omp target map(k) // expected-error 2 {{variable already marked as mapped in current construct}} -#pragma omp target map(j) -#pragma omp target map(l) // expected-error 2 {{variable already marked as mapped in current construct}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +#pragma omp target data map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} +#pragma omp target data map(j) +#pragma omp target map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} foo(); -#pragma omp target map(always, tofrom: x) -#pragma omp target map(always: x) // expected-error {{missing map type}} -#pragma omp target map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} -#pragma omp target map(always, tofrom: always, tofrom, x) +#pragma omp target data map(always, tofrom: x) +#pragma omp target data map(always: x) // expected-error {{missing map type}} +#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map(always, tofrom: always, tofrom, x) #pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); - return 0; } @@ -147,14 +446,14 @@ int main(int argc, char **argv) { int y; int to, tofrom, always; const int (&l)[5] = da; -#pragma omp target map // expected-error {{expected '(' after 'map'}} -#pragma omp target map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} -#pragma omp target map() // expected-error {{expected expression}} -#pragma omp target map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} -#pragma omp target map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} -#pragma omp target map(to:) // expected-error {{expected expression}} -#pragma omp target map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} -#pragma omp target map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one map clause for '#pragma omp target data'}} +#pragma omp target data map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} +#pragma omp target data map() // expected-error {{expected expression}} +#pragma omp target data map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} +#pragma omp target data map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} +#pragma omp target data map(to:) // expected-error {{expected expression}} +#pragma omp target data map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target data map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} #pragma omp target map(x) foo(); #pragma omp target map(to: x) @@ -165,43 +464,46 @@ int main(int argc, char **argv) { foo(); #pragma omp target map(to, x) foo(); -#pragma omp target map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} -#pragma omp target map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} -#pragma omp target map(argc) -#pragma omp target map(S1) // expected-error {{'S1' does not refer to a value}} -#pragma omp target map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} -#pragma omp target map(argv[1]) -#pragma omp target map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} -#pragma omp target map(ca) -#pragma omp target map(da) -#pragma omp target map(S2::S2s) -#pragma omp target map(S2::S2sc) -#pragma omp target map(e, g) -#pragma omp target map(h) // expected-error {{threadprivate variables are not allowed in map clause}} -#pragma omp target map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} -#pragma omp target map(k), map(k[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} +#pragma omp target data map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} +#pragma omp target data map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{xpected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target data map(argc) +#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target data map(argv[1]) +#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target data map(ca) +#pragma omp target data map(da) +#pragma omp target data map(S2::S2s) +#pragma omp target data map(S2::S2sc) +#pragma omp target data map(e, g) +#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} +#pragma omp target data map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} +#pragma omp target map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} foo(); -#pragma omp target map(da) +#pragma omp target data map(da) #pragma omp target map(da[:4]) foo(); -#pragma omp target map(k, j, l) // expected-note 2 {{used here}} -#pragma omp target map(k[:4]) // expected-error {{variable already marked as mapped in current construct}} -#pragma omp target map(j) -#pragma omp target map(l[:5]) // expected-error {{variable already marked as mapped in current construct}} +#pragma omp target data map(k, j, l) // expected-note {{used here}} +#pragma omp target data map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} +#pragma omp target data map(j) +#pragma omp target map(l) map(l[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} foo(); -#pragma omp target map(k[:4], j, l[:5]) // expected-note 2 {{used here}} -#pragma omp target map(k) // expected-error {{variable already marked as mapped in current construct}} -#pragma omp target map(j) -#pragma omp target map(l) // expected-error {{variable already marked as mapped in current construct}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +#pragma omp target data map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} +#pragma omp target data map(j) +#pragma omp target map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} foo(); -#pragma omp target map(always, tofrom: x) -#pragma omp target map(always: x) // expected-error {{missing map type}} -#pragma omp target map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} -#pragma omp target map(always, tofrom: always, tofrom, x) +#pragma omp target data map(always, tofrom: x) +#pragma omp target data map(always: x) // expected-error {{missing map type}} +#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} +#pragma omp target data map(always, tofrom: always, tofrom, x) #pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); - +#pragma omp target private(j) map(j) // expected-error {{private variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as private}} + {} +#pragma omp target firstprivate(j) map(j) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as firstprivate}} + {} return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}} } - +#endif diff --git a/test/OpenMP/target_messages.cpp b/test/OpenMP/target_messages.cpp index 86a91838ce021..6f79f44627fa4 100644 --- a/test/OpenMP/target_messages.cpp +++ b/test/OpenMP/target_messages.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s -// RUN: not %clang_cc1 -fopenmp -std=c++11 -omptargets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s // CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd' +// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s +// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s +// CHECK-UNSUPPORTED-HOST-TARGET: error: The target '{{nvptx64-nvidia-cuda|nvptx-nvidia-cuda}}' is not a supported OpenMP host target. void foo() { } @@ -21,6 +24,7 @@ int main(int argc, char **argv) { #pragma omp target } // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} foo(); #pragma omp target + foo(); // expected-warning@+1 {{extra tokens at the end of '#pragma omp target' are ignored}} #pragma omp target unknown() foo(); diff --git a/test/OpenMP/target_nowait_messages.cpp b/test/OpenMP/target_nowait_messages.cpp new file mode 100644 index 0000000000000..7531c81c0f6ae --- /dev/null +++ b/test/OpenMP/target_nowait_messages.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +int main(int argc, char **argv) { + #pragma omp target nowait( // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target nowait device (-10u) + foo(); + #pragma omp target nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_ast_print.cpp b/test/OpenMP/target_parallel_ast_print.cpp new file mode 100644 index 0000000000000..1c0fca5ccfc06 --- /dev/null +++ b/test/OpenMP/target_parallel_ast_print.cpp @@ -0,0 +1,233 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <class T> +struct S { + operator T() {return T();} + static T TS; + #pragma omp threadprivate(TS) +}; + +// CHECK: template <class T = int> struct S { +// CHECK: static int TS; +// CHECK-NEXT: #pragma omp threadprivate(S<int>::TS) +// CHECK-NEXT: } +// CHECK: template <class T = char> struct S { +// CHECK: static char TS; +// CHECK-NEXT: #pragma omp threadprivate(S<char>::TS) +// CHECK-NEXT: } +// CHECK: template <class T> struct S { +// CHECK: static T TS; +// CHECK-NEXT: #pragma omp threadprivate(S::TS) +// CHECK: }; + +template <typename T, int C> +T tmain(T argc, T *argv) { + T b = argc, c, d, e, f, g; + static T h; + S<T> s; + T arr[C][10], arr1[C]; + T i, j, a[20]; +#pragma omp target parallel + h=2; +#pragma omp target parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10]) + foo(); +#pragma omp target parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g) + foo(); +#pragma omp target parallel if (target:argc > 0) + foo(); +#pragma omp target parallel if (parallel:argc > 0) + foo(); +#pragma omp target parallel if (C) + foo(); +#pragma omp target parallel map(i) + foo(); +#pragma omp target parallel map(a[0:10], i) + foo(); +#pragma omp target parallel map(to: i) map(from: j) + foo(); +#pragma omp target parallel map(always,alloc: i) + foo(); +#pragma omp target parallel nowait + foo(); +#pragma omp target parallel depend(in : argc, argv[i:argc], a[:]) + foo(); +#pragma omp target parallel defaultmap(tofrom: scalar) + foo(); + return 0; +} + +// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) { +// CHECK-NEXT: int b = argc, c, d, e, f, g; +// CHECK-NEXT: static int h; +// CHECK-NEXT: S<int> s; +// CHECK-NEXT: int arr[5][10], arr1[5]; +// CHECK-NEXT: int i, j, a[20] +// CHECK-NEXT: #pragma omp target parallel +// CHECK-NEXT: h = 2; +// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(5) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(tofrom: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel nowait +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar) +// CHECK-NEXT: foo() +// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) { +// CHECK-NEXT: char b = argc, c, d, e, f, g; +// CHECK-NEXT: static char h; +// CHECK-NEXT: S<char> s; +// CHECK-NEXT: char arr[1][10], arr1[1]; +// CHECK-NEXT: char i, j, a[20] +// CHECK-NEXT: #pragma omp target parallel +// CHECK-NEXT: h = 2; +// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(1) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(tofrom: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel nowait +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar) +// CHECK-NEXT: foo() +// CHECK: template <typename T, int C> T tmain(T argc, T *argv) { +// CHECK-NEXT: T b = argc, c, d, e, f, g; +// CHECK-NEXT: static T h; +// CHECK-NEXT: S<T> s; +// CHECK-NEXT: T arr[C][10], arr1[C]; +// CHECK-NEXT: T i, j, a[20] +// CHECK-NEXT: #pragma omp target parallel +// CHECK-NEXT: h = 2; +// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel if(C) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(tofrom: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel nowait +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:]) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar) +// CHECK-NEXT: foo() + +// CHECK-LABEL: int main(int argc, char **argv) { +int main (int argc, char **argv) { + int i, j, a[20]; +// CHECK-NEXT: int i, j, a[20] +#pragma omp target parallel +// CHECK-NEXT: #pragma omp target parallel + foo(); +// CHECK-NEXT: foo(); +#pragma omp target parallel if (argc > 0) +// CHECK-NEXT: #pragma omp target parallel if(argc > 0) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel if (target: argc > 0) +// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel if (parallel: argc > 0) +// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel map(i) if(argc>0) +// CHECK-NEXT: #pragma omp target parallel map(tofrom: i) if(argc > 0) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel map(i) +// CHECK-NEXT: #pragma omp target parallel map(tofrom: i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel map(a[0:10], i) +// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel map(to: i) map(from: j) +// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel map(always,alloc: i) +// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel nowait +// CHECK-NEXT: #pragma omp target parallel nowait + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel depend(in : argc, argv[i:argc], a[:]) +// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:]) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target parallel defaultmap(tofrom: scalar) +// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar) + foo(); +// CHECK-NEXT: foo(); + + return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]); +} + +extern template int S<int>::TS; +extern template char S<char>::TS; + +#endif diff --git a/test/OpenMP/target_parallel_default_messages.cpp b/test/OpenMP/target_parallel_default_messages.cpp new file mode 100644 index 0000000000000..40f31b84848ae --- /dev/null +++ b/test/OpenMP/target_parallel_default_messages.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +int main(int argc, char **argv) { + #pragma omp target parallel default // expected-error {{expected '(' after 'default'}} + foo(); + #pragma omp target parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + foo(); + #pragma omp target parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel default (shared), default(shared) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'default' clause}} + foo(); + #pragma omp target parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + foo(); + + #pragma omp target parallel default(none) + ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + + #pragma omp target parallel default(none) + foo(); + #pragma omp target parallel default(shared) + ++argc; + return 0; +} diff --git a/test/OpenMP/target_parallel_defaultmap_messages.cpp b/test/OpenMP/target_parallel_defaultmap_messages.cpp new file mode 100644 index 0000000000000..49e7c30a7d15f --- /dev/null +++ b/test/OpenMP/target_parallel_defaultmap_messages.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +template <class T, typename S, int N, int ST> +T tmain(T argc, S **argv) { + #pragma omp target parallel defaultmap // expected-error {{expected '(' after 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + foo(); + #pragma omp target parallel defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target parallel defaultmap // expected-error {{expected '(' after 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + foo(); + #pragma omp target parallel defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + foo(); + #pragma omp target parallel defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + foo(); + + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_depend_messages.cpp b/test/OpenMP/target_parallel_depend_messages.cpp new file mode 100644 index 0000000000000..a9300ca6adb2b --- /dev/null +++ b/test/OpenMP/target_parallel_depend_messages.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + auto arr = x; // expected-error {{use of undeclared identifier 'x'}} + + #pragma omp target parallel depend // expected-error {{expected '(' after 'depend'}} + foo(); + #pragma omp target parallel depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target parallel depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target parallel depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + foo(); + #pragma omp target parallel depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + foo(); + #pragma omp target parallel depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel depend (out: ) // expected-error {{expected expression}} + foo(); + #pragma omp target parallel depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + foo(); + #pragma omp target parallel depend (out :S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target parallel depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target parallel depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target parallel depend (in : argv[0]) + foo(); + #pragma omp target parallel depend (in : ) // expected-error {{expected expression}} + foo(); + #pragma omp target parallel depend (in : main) // expected-error {{expected variable name, array element or array section}} + foo(); + #pragma omp target parallel depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + foo(); + #pragma omp target parallel depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + foo(); + #pragma omp target parallel depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + foo(); + #pragma omp target parallel depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + foo(); + #pragma omp target parallel depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target parallel depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + foo(); + #pragma omp target parallel depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + foo(); + #pragma omp target parallel depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + foo(); + #pragma omp target parallel depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); + #pragma omp target parallel depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); + #pragma omp target parallel depend(in : argv[ : argc][1 : argc - 1]) + foo(); + #pragma omp target parallel depend(in : arr[0]) + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_device_messages.cpp b/test/OpenMP/target_parallel_device_messages.cpp new file mode 100644 index 0000000000000..6c8d4c2e43ab2 --- /dev/null +++ b/test/OpenMP/target_parallel_device_messages.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + #pragma omp target parallel device // expected-error {{expected '(' after 'device'}} + foo(); + #pragma omp target parallel device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel device () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + #pragma omp target parallel device (argc + argc) + foo(); + #pragma omp target parallel device (argc), device (argc+1) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'device' clause}} + foo(); + #pragma omp target parallel device (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target parallel device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + foo(); + #pragma omp target parallel device (-10u) + foo(); + #pragma omp target parallel device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_firstprivate_messages.cpp b/test/OpenMP/target_parallel_firstprivate_messages.cpp new file mode 100644 index 0000000000000..dd6825aa251f9 --- /dev/null +++ b/test/OpenMP/target_parallel_firstprivate_messages.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(const S2 &s2):a(s2.a) { } + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(const S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note {{implicitly declared private here}} +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } // expected-note {{implicitly declared private here}} +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + static int m; + #pragma omp target parallel firstprivate // expected-error {{expected '(' after 'firstprivate'}} + foo(); + #pragma omp target parallel firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel firstprivate () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel firstprivate (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + foo(); + #pragma omp target parallel firstprivate (argc) + foo(); + #pragma omp target parallel firstprivate (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target parallel firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + foo(); + #pragma omp target parallel firstprivate (argv[1]) // expected-error {{expected variable name}} + foo(); + #pragma omp target parallel firstprivate(ba) + foo(); + #pragma omp target parallel firstprivate(ca) + foo(); + #pragma omp target parallel firstprivate(da) + foo(); + #pragma omp target parallel firstprivate(S2::S2s) + foo(); + #pragma omp target parallel firstprivate(S2::S2sc) + foo(); + #pragma omp target parallel firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + foo(); + #pragma omp target parallel firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} + foo(); + #pragma omp target parallel private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} + foo(); + #pragma omp target parallel shared(i) + foo(); + #pragma omp target parallel firstprivate(i) + foo(); + #pragma omp target parallel firstprivate(j) + foo(); + #pragma omp target parallel firstprivate(m) + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_ast_print.cpp b/test/OpenMP/target_parallel_for_ast_print.cpp new file mode 100644 index 0000000000000..6c551cbb9abfe --- /dev/null +++ b/test/OpenMP/target_parallel_for_ast_print.cpp @@ -0,0 +1,252 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target parallel for private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp target parallel for private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp target parallel for private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target parallel for private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target parallel for private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp target parallel for private(this->a) private(this->a) + +template <class T, int N> +T tmain(T argc, T *argv) { + T b = argc, c, d, e, f, h; + T arr[N][10], arr1[N]; + T i, j; + T s; + static T a; +// CHECK: static T a; + static T g; +#pragma omp threadprivate(g) +#pragma omp target parallel for schedule(dynamic) default(none) linear(a) + // CHECK: #pragma omp target parallel for schedule(dynamic) default(none) linear(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + foo(); + // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: foo(); +#pragma omp target parallel for default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(N) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:N][0:10]) + for (int i = 0; i < 2; ++i) {} +// CHECK-NEXT: #pragma omp target parallel for default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(N) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:N][0:10]) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (N) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:N][:argc]) reduction(&& : h) +// CHECK-NEXT: #pragma omp target parallel for if(N) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:N][:argc]) reduction(&&: h) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (target:argc > 0) +// CHECK-NEXT: #pragma omp target parallel for if(target: argc > 0) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (parallel:argc > 0) +// CHECK-NEXT: #pragma omp target parallel for if(parallel: argc > 0) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (N) +// CHECK-NEXT: #pragma omp target parallel for if(N) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(i) +// CHECK-NEXT: #pragma omp target parallel for map(tofrom: i) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(arr1[0:10], i) +// CHECK-NEXT: #pragma omp target parallel for map(tofrom: arr1[0:10],i) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(to: i) map(from: j) +// CHECK-NEXT: #pragma omp target parallel for map(to: i) map(from: j) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(always,alloc: i) +// CHECK-NEXT: #pragma omp target parallel for map(always,alloc: i) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for nowait +// CHECK-NEXT: #pragma omp target parallel for nowait + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for depend(in : argc, arr[i:argc], arr1[:]) +// CHECK-NEXT: #pragma omp target parallel for depend(in : argc,arr[i:argc],arr1[:]) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for defaultmap(tofrom: scalar) +// CHECK-NEXT: #pragma omp target parallel for defaultmap(tofrom: scalar) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + + return T(); +} + +int main(int argc, char **argv) { + int b = argc, c, d, e, f, h; + int arr[5][10], arr1[5]; + int i, j; + int s; + static int a; +// CHECK: static int a; + static float g; +#pragma omp threadprivate(g) +#pragma omp target parallel for schedule(guided, argc) default(none) linear(a) + // CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (target: argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a:-5) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + foo(); + // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: foo(); +#pragma omp target parallel for default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(5) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:5][0:10]) + for (int i = 0; i < 2; ++i) {} +// CHECK-NEXT: #pragma omp target parallel for default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10]) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (5) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:5][:argc]) reduction(&& : h) +// CHECK-NEXT: #pragma omp target parallel for if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: h) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (target:argc > 0) +// CHECK-NEXT: #pragma omp target parallel for if(target: argc > 0) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (parallel:argc > 0) +// CHECK-NEXT: #pragma omp target parallel for if(parallel: argc > 0) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for if (5) +// CHECK-NEXT: #pragma omp target parallel for if(5) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(i) +// CHECK-NEXT: #pragma omp target parallel for map(tofrom: i) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(arr1[0:10], i) +// CHECK-NEXT: #pragma omp target parallel for map(tofrom: arr1[0:10],i) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(to: i) map(from: j) +// CHECK-NEXT: #pragma omp target parallel for map(to: i) map(from: j) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for map(always,alloc: i) +// CHECK-NEXT: #pragma omp target parallel for map(always,alloc: i) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for nowait +// CHECK-NEXT: #pragma omp target parallel for nowait + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for depend(in : argc, arr[i:argc], arr1[:]) +// CHECK-NEXT: #pragma omp target parallel for depend(in : argc,arr[i:argc],arr1[:]) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } +#pragma omp target parallel for defaultmap(tofrom: scalar) +// CHECK-NEXT: #pragma omp target parallel for defaultmap(tofrom: scalar) + for (int i = 0; i < 2; ++i) {} + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + return (tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0])); +} + +#endif diff --git a/test/OpenMP/target_parallel_for_collapse_messages.cpp b/test/OpenMP/target_parallel_for_collapse_messages.cpp new file mode 100644 index 0000000000000..8cf502be0d9cc --- /dev/null +++ b/test/OpenMP/target_parallel_for_collapse_messages.cpp @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp target parallel for collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp target parallel for collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + #pragma omp target parallel for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for', but found only 1}} + // expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'collapse' clause}} + // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp target parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}} + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target parallel for collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} + #pragma omp target parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} + #pragma omp target parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'collapse' clause}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + #pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp target parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp target parallel for' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp target parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp target parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_default_messages.cpp b/test/OpenMP/target_parallel_for_default_messages.cpp new file mode 100644 index 0000000000000..c1f04f4f6e409 --- /dev/null +++ b/test/OpenMP/target_parallel_for_default_messages.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +int main(int argc, char **argv) { + int i; +#pragma omp target parallel for default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp target parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target parallel for default(none) + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp target parallel for default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_defaultmap_messages.cpp b/test/OpenMP/target_parallel_for_defaultmap_messages.cpp new file mode 100644 index 0000000000000..24973edd2bda8 --- /dev/null +++ b/test/OpenMP/target_parallel_for_defaultmap_messages.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +template <class T, typename S, int N, int ST> +T tmain(T argc, S **argv) { + int i; + #pragma omp target parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_depend_messages.cpp b/test/OpenMP/target_parallel_for_depend_messages.cpp new file mode 100644 index 0000000000000..d0e74f9cc6295 --- /dev/null +++ b/test/OpenMP/target_parallel_for_depend_messages.cpp @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + auto arr = x; // expected-error {{use of undeclared identifier 'x'}} + int i; + + #pragma omp target parallel for depend // expected-error {{expected '(' after 'depend'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (out: ) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[0]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : ) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : main) // expected-error {{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in : argv[ : argc][1 : argc - 1]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for depend(in : arr[0]) + for (i = 0; i < argc; ++i) foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_device_messages.cpp b/test/OpenMP/target_parallel_for_device_messages.cpp new file mode 100644 index 0000000000000..16a21ba4d662d --- /dev/null +++ b/test/OpenMP/target_parallel_for_device_messages.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for device // expected-error {{expected '(' after 'device'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (argc + argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (argc), device (argc+1) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'device' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_firstprivate_messages.cpp new file mode 100644 index 0000000000000..36bfe25e94682 --- /dev/null +++ b/test/OpenMP/target_parallel_for_firstprivate_messages.cpp @@ -0,0 +1,261 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp target parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) +#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}} + foo(); + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target parallel for firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp target parallel for'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel shared(xa) +#pragma omp target parallel for firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) +#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}} + foo(); + static int si; +#pragma omp target parallel for firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_if_messages.cpp b/test/OpenMP/target_parallel_for_if_messages.cpp new file mode 100644 index 0000000000000..01173c159d57f --- /dev/null +++ b/test/OpenMP/target_parallel_for_if_messages.cpp @@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + int i; + #pragma omp target parallel for if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'target' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'target' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp new file mode 100644 index 0000000000000..c001b7f0d1685 --- /dev/null +++ b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp @@ -0,0 +1,238 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + S2 &operator=(const S2 &); + const S2 &operator=(const S2 &) const; + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { + int a; + S4(); // expected-note 3 {{implicitly declared private here}} + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for lastprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target parallel for lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp target parallel for'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(i) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(xa) +#pragma omp target parallel for lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : xa) +#pragma omp target parallel for lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp target parallel for lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 2; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_linear_messages.cpp b/test/OpenMP/target_parallel_for_linear_messages.cpp new file mode 100644 index 0000000000000..36e897d5946e6 --- /dev/null +++ b/test/OpenMP/target_parallel_for_linear_messages.cpp @@ -0,0 +1,269 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +namespace X { +int x; +}; + +struct B { + static int ib; // expected-note {{'B::ib' declared here}} + static int bfoo() { return 8; } +}; + +int bfoo() { return 4; } + +int z; +const int C1 = 1; +const int C2 = 2; +void test_linear_colons() { + int B = 0; +#pragma omp target parallel for linear(B : bfoo()) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} +#pragma omp target parallel for linear(B::ib : B : bfoo()) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}} +#pragma omp target parallel for linear(B : ib) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} +#pragma omp target parallel for linear(z : B : ib) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for linear(B : B::bfoo()) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for linear(X::x : ::z) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for linear(B, ::z, X::x) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for linear(::z) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for linear(B::bfoo()) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for linear(B::ib, B : C1 + C2) + for (int i = 0; i < 10; ++i) + ; +} + +template <int L, class T, class N> +T test_template(T *arr, N num) { + N i; + T sum = (T)0; + T ind2 = -num * L; // expected-note {{'ind2' defined here}} +// expected-error@+1 {{argument of a linear clause should be of integral or pointer type}} +#pragma omp target parallel for linear(ind2 : L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template <int LEN> +int test_warn() { + int ind2 = 0; +// expected-warning@+1 {{zero linear step (ind2 should probably be const)}} +#pragma omp target parallel for linear(ind2 : LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return ind2; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} + +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target parallel for linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc : 5) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +// expected-error@+2 {{linear variable with incomplete type 'S1'}} +// expected-error@+1 {{const-qualified variable cannot be linear}} +#pragma omp target parallel for linear(a, b : B::ib) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for linear(v : i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp target parallel for linear(j) + for (int k = 0; k < argc; ++k) + ++k; + int v = 0; +#pragma omp target parallel for linear(v : j) + for (int k = 0; k < argc; ++k) { + ++k; + v += j; + } +#pragma omp target parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; +#pragma omp target parallel for linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +// expected-error@+2 {{linear variable with incomplete type 'S1'}} +// expected-error@+1 {{const-qualified variable cannot be linear}} +#pragma omp target parallel for linear(a, b) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +// expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}} +// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} +#pragma omp target parallel for linear(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(i : 4) + for (int k = 0; k < argc; ++k) { + ++k; + i += 4; + } + } +#pragma omp target parallel for linear(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; + + foomain<int, char>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} + return 0; +} + diff --git a/test/OpenMP/target_parallel_for_loop_messages.cpp b/test/OpenMP/target_parallel_for_loop_messages.cpp new file mode 100644 index 0000000000000..0e8eab10b5cb5 --- /dev/null +++ b/test/OpenMP/target_parallel_for_loop_messages.cpp @@ -0,0 +1,627 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s + +class S { + int a; + S() : a(0) {} + +public: + S(int v) : a(v) {} + S(const S &s) : a(s.a) {} +}; + +static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} +#pragma omp threadprivate(sii) +static int globalii; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; +#pragma omp target parallel for + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp target parallel for + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp target parallel for + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp target parallel for + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (int &ref = ii; ref < 10; ref++) { + } +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (int i; i < 10; i++) + c[i] = a[i]; + +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// Ok to skip parenthesises. +#pragma omp target parallel for + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for + for (int i = 0; i; i++) + c[i] = a[i]; + +// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} +#pragma omp target parallel for + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for + for (int i = 0; !!i; i++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for + for (int i = 0; i != 1; i++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for + for (int i = 0;; i++) + c[i] = a[i]; + +// Ok. +#pragma omp target parallel for + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +// Ok. +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +// Ok. +#pragma omp target parallel for + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp target parallel for + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +// Ok - step was converted to integer type. +#pragma omp target parallel for + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +// expected-warning@+3 {{relational comparison result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}} +#pragma omp target parallel for firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as linear}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be linear, predetermined as private}} +#pragma omp target parallel for linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target parallel for private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target parallel for lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be threadprivate or thread local, predetermined as private}} +#pragma omp target parallel for + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + + { +#pragma omp target parallel for + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + + { +#pragma omp target parallel for collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +// expected-error@+2 {{statement after '#pragma omp target parallel for' must be a for loop}} +#pragma omp target parallel for + for (auto &item : a) { + item = item + 1; + } + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp target parallel for + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template <class Iter> +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template <class Iter> +typename iterator_traits<Iter>::difference_type +distance(Iter first, Iter last) { return first - last; } +} +class Iter0 { +public: + Iter0() {} + Iter0(const Iter0 &) {} + Iter0 operator++() { return *this; } + Iter0 operator--() { return *this; } + bool operator<(Iter0 a) { return true; } +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} +int operator-(Iter0 a, Iter0 b) { return 0; } +class Iter1 { +public: + Iter1(float f = 0.0f, double d = 0.0) {} + Iter1(const Iter1 &) {} + Iter1 operator++() { return *this; } + Iter1 operator--() { return *this; } + bool operator<(Iter1 a) { return true; } + bool operator>=(Iter1 a) { return false; } +}; +class GoodIter { +public: + GoodIter() {} + GoodIter(const GoodIter &) {} + GoodIter(int fst, int snd) {} + GoodIter &operator=(const GoodIter &that) { return *this; } + GoodIter &operator=(const Iter0 &that) { return *this; } + GoodIter &operator+=(int x) { return *this; } + GoodIter &operator-=(int x) { return *this; } + explicit GoodIter(void *) {} + GoodIter operator++() { return *this; } + GoodIter operator--() { return *this; } + bool operator!() { return true; } + bool operator<(GoodIter a) { return true; } + bool operator<=(GoodIter a) { return true; } + bool operator>=(GoodIter a) { return false; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} +GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +GoodIter operator-(GoodIter a, int v) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} +GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} +GoodIter operator-(int v, GoodIter a) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}} +GoodIter operator+(int v, GoodIter a) { return GoodIter(); } + +int test_with_random_access_iterator() { + GoodIter begin, end; + Iter0 begin0, end0; +#pragma omp target parallel for + for (GoodIter I = begin; I < end; ++I) + ++I; +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp target parallel for + for (GoodIter I = begin; I >= end; --I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (GoodIter I(begin); I < end; ++I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (GoodIter I(nullptr); I < end; ++I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (GoodIter I(0); I < end; ++I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp target parallel for + for (begin = GoodIter(0); begin < end; ++begin) + ++begin; +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} +// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp target parallel for + for (begin = begin0; begin < end; ++begin) + ++begin; +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp target parallel for + for (begin = end; begin < end; ++begin) + ++begin; +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp target parallel for + for (GoodIter I = begin; I - I; ++I) + ++I; +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp target parallel for + for (GoodIter I = begin; begin < end; ++I) + ++I; +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp target parallel for + for (GoodIter I = begin; !I; ++I) + ++I; +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp target parallel for + for (GoodIter I = begin; I >= end; I = I - 1) + ++I; +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp target parallel for + for (GoodIter I = begin; I >= end; I = -I) + ++I; +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (GoodIter I = begin; I >= end; I = 2 + I) + ++I; +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp target parallel for + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; +// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}} +#pragma omp target parallel for + for (Iter0 I = begin0; I < end0; ++I) + ++I; +// Initializer is constructor without params. +// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (Iter0 I; I < end0; ++I) + ++I; + Iter1 begin1, end1; +// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp target parallel for + for (Iter1 I = begin1; I < end1; ++I) + ++I; +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}} +// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +// Initializer is constructor with all default params. +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template <typename IT, int ST> +class TC { +public: + int dotest_lt(IT begin, IT end) { +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp target parallel for + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template <typename IT, int ST = 0> +int dotest_gt(IT begin, IT end) { +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (IT I = begin; I >= end; I += ST) { + ++I; + } + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp target parallel for + for (IT I = begin; I < end; I += TC<int, ST>::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC<GoodIter, 100> t1; + TC<GoodIter, -100> t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} + dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp target parallel for + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + break; // OK in nested loop + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + if (c[i] > 10) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + + if (c[i] > 11) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + } + +#pragma omp target parallel for + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + c[i] = a[i] + b[i]; + if (c[i] > 10) { + if (c[i] < 20) { + break; // OK + } + } + } + } +} + +void test_loop_eh() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp target parallel for + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + try { + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + throw a[i]; + } + throw a[i]; + } catch (float f) { + if (f > 0.1) + throw a[i]; + return; // expected-error {{cannot return from OpenMP region}} + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + for (int j = 0; j < 10; j++) { + if (c[i] > 10) + throw c[i]; + } + } + if (c[9] > 10) + throw c[9]; // OK + +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp target parallel for lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp new file mode 100644 index 0000000000000..5223a2cc78ea8 --- /dev/null +++ b/test/OpenMP/target_parallel_for_map_messages.cpp @@ -0,0 +1,273 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; // expected-note 4 {{mappable type cannot contain static members}} + static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}} +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +typedef int from; + +template <typename T, int I> // expected-note {{declared here}} +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + T i, t[20]; + T &j = i; + T *k = &j; + T x; + T y; + T to, tofrom, always; + const T (&l)[5] = da; + + +#pragma omp target parallel for map // expected-error {{expected '(' after 'map'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom: t[:I]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(T) // expected-error {{'T' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S2::S2s) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to: to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(ca) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S2::S2s) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(e, g) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(da[:4]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k, j, l) // expected-note 2 {{used here}} +#pragma omp target parallel for map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +{ +#pragma omp target parallel for map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + for (i = 0; i < argc; ++i) foo(); +} + +#pragma omp target parallel for map(always, tofrom: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(always: x) // expected-error {{missing map type}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(always, tofrom: always, tofrom, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int *k = &j; + int x; + int y; + int to, tofrom, always; + const int (&l)[5] = da; + +#pragma omp target parallel for map // expected-error {{expected '(' after 'map'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to: to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(argv[1]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(ca) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S2::S2s) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(e, g) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(da[:4]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k, j, l) // expected-note {{used here}} +#pragma omp target parallel for map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +{ +#pragma omp target parallel for map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + for (i = 0; i < argc; ++i) foo(); +} + +#pragma omp target parallel for map(always, tofrom: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(always: x) // expected-error {{missing map type}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(always, tofrom: always, tofrom, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}} +} + diff --git a/test/OpenMP/target_parallel_for_messages.cpp b/test/OpenMP/target_parallel_for_messages.cpp new file mode 100644 index 0000000000000..173025c01ce76 --- /dev/null +++ b/test/OpenMP/target_parallel_for_messages.cpp @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 -o - %s + +void foo() { +} + +static int pvt; +#pragma omp threadprivate(pvt) + +#pragma omp target parallel for // expected-error {{unexpected OpenMP directive '#pragma omp target parallel for'}} + +int main(int argc, char **argv) { +#pragma omp target parallel for { // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for ( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for[ // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for] // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for } // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for + for (int i = 0; i < argc; ++i) + foo(); +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} +#pragma omp target parallel for unknown() + for (int i = 0; i < argc; ++i) + foo(); +L1: + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for + for (int i = 0; i < argc; ++i) { + goto L1; // expected-error {{use of undeclared label 'L1'}} + argc++; + } + + for (int i = 0; i < 10; ++i) { + switch (argc) { + case (0): +#pragma omp target parallel for + for (int i = 0; i < argc; ++i) { + foo(); + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + continue; + } + default: + break; + } + } +#pragma omp target parallel for default(none) + for (int i = 0; i < 10; ++i) + ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + + goto L2; // expected-error {{use of undeclared label 'L2'}} +#pragma omp target parallel for + for (int i = 0; i < argc; ++i) + L2: + foo(); +#pragma omp target parallel for + for (int i = 0; i < argc; ++i) { + return 1; // expected-error {{cannot return from OpenMP region}} + } + + [[]] // expected-error {{an attribute list cannot appear here}} +#pragma omp target parallel for + for (int n = 0; n < 100; ++n) { + } + +#pragma omp target parallel for copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target parallel for'}} + for (int n = 0; n < 100; ++n) {} + + return 0; +} + +void test_ordered() { +#pragma omp target parallel for ordered ordered // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}} + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/target_parallel_for_misc_messages.c b/test/OpenMP/target_parallel_for_misc_messages.c new file mode 100644 index 0000000000000..cfe83f1301075 --- /dev/null +++ b/test/OpenMP/target_parallel_for_misc_messages.c @@ -0,0 +1,314 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for'}} +#pragma omp target parallel for + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for'}} +#pragma omp target parallel for foo + +void test_no_clause() { + int i; +#pragma omp target parallel for + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp target parallel for' must be a for loop}} +#pragma omp target parallel for + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp target parallel for + for (i = 0; i < 16; ++i) { + if (i == 5) + goto L1; // expected-error {{use of undeclared label 'L1'}} + else if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + else if (i == 7) + goto L2; + else if (i == 8) { + L2: + x[i]++; + } + } + + if (x[0] == 0) + goto L2; // expected-error {{use of undeclared label 'L2'}} + else if (x[1] == 1) + goto L1; +} + +void test_invalid_clause() { + int i; +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} +#pragma omp target parallel for foo bar + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} +#pragma omp target parallel for; + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} +#pragma omp target parallel for private(x); + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} +#pragma omp target parallel for, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); + +void test_collapse() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for collapse + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for collapse( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for collapse() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for collapse(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for collapse(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for collapse 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +#pragma omp target parallel for collapse(4) + for (int i1 = 0; i1 < 16; ++i1) + for (int i2 = 0; i2 < 16; ++i2) + for (int i3 = 0; i3 < 16; ++i3) + for (int i4 = 0; i4 < 16; ++i4) + foo(); +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for collapse(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for collapse(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target parallel for collapse(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target parallel for collapse(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target parallel for collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +// expected-note@+1 {{defined as firstprivate}} +#pragma omp target parallel for collapse(2) firstprivate(i) + for (i = 0; i < 16; ++i) +// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+2 2 {{reduction variable must be shared}} +// expected-error@+1 {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +#pragma omp for reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; +} + +void test_private() { + int i; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for private( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for private(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for private(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for private() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for private(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target parallel for private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for lastprivate( + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for lastprivate(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for lastprivate() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for lastprivate(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target parallel for lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for firstprivate( + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for firstprivate(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for firstprivate() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for firstprivate(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target parallel for lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for lastprivate(x, y, z) firstprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_loop_messages() { + float a[100], b[100], c[100]; +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp target parallel for + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp target parallel for + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +} + diff --git a/test/OpenMP/target_parallel_for_nowait_messages.cpp b/test/OpenMP/target_parallel_for_nowait_messages.cpp new file mode 100644 index 0000000000000..06d22969c4a4c --- /dev/null +++ b/test/OpenMP/target_parallel_for_nowait_messages.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_num_threads_messages.cpp b/test/OpenMP/target_parallel_for_num_threads_messages.cpp new file mode 100644 index 0000000000000..915cfb1dfc9e0 --- /dev/null +++ b/test/OpenMP/target_parallel_for_num_threads_messages.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + T i; + #pragma omp target parallel for num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_ordered_messages.cpp b/test/OpenMP/target_parallel_for_ordered_messages.cpp new file mode 100644 index 0000000000000..36eb8371e0252 --- /dev/null +++ b/test/OpenMP/target_parallel_for_ordered_messages.cpp @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp target parallel for ordered + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered() // expected-error {{expected expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 2 {{expression is not an integral constant expression}} +// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp target parallel for ordered(argc + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +#pragma omp target parallel for ordered(ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for', but found only 1}} +// expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}} +// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +// expected-error@+1 2 {{expression is not an integral constant expression}} +#pragma omp target parallel for ordered(foobool(argc)), ordered(true), ordered(-5) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered(S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +// expected-error@+1 2 {{expression is not an integral constant expression}} +#pragma omp target parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered(1) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered(N) // expected-error {{argument to 'ordered' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}} + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target parallel for ordered + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for ordered() // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for ordered(4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'ordered' clause}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +#pragma omp target parallel for ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} expected-note {{as specified in 'ordered' clause}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}} +#pragma omp target parallel for ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +// expected-error@+3 {{expression is not an integral constant expression}} +// expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}} +// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +#pragma omp target parallel for ordered(foobool(argc)), ordered(true), ordered(-5) + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for ordered(S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +// expected-error@+1 {{expression is not an integral constant expression}} +#pragma omp target parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +// expected-error@+3 {{statement after '#pragma omp target parallel for' must be a for loop}} +// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target parallel for ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp target parallel for ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_private_messages.cpp b/test/OpenMP/target_parallel_for_private_messages.cpp new file mode 100644 index 0000000000000..1d6381a1d5d3e --- /dev/null +++ b/test/OpenMP/target_parallel_for_private_messages.cpp @@ -0,0 +1,231 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) { +#pragma omp target parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target parallel for private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target parallel for private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target parallel for private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int m; +#pragma omp target parallel for private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; + + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/target_parallel_for_proc_bind_messages.cpp b/test/OpenMP/target_parallel_for_proc_bind_messages.cpp new file mode 100644 index 0000000000000..eeb232aeca811 --- /dev/null +++ b/test/OpenMP/target_parallel_for_proc_bind_messages.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +int main(int argc, char **argv) { + int i; +#pragma omp target parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target parallel for proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp target parallel for proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + return 0; +} diff --git a/test/OpenMP/target_parallel_for_reduction_messages.cpp b/test/OpenMP/target_parallel_for_reduction_messages.cpp new file mode 100644 index 0000000000000..16697a98733b4 --- /dev/null +++ b/test/OpenMP/target_parallel_for_reduction_messages.cpp @@ -0,0 +1,313 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + int b; + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+(const S3 &arg1) { return arg1; } +}; +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 3 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + S4(const S4 &s4); + S4 &operator+(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} +#endif + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; +#pragma omp target parallel for reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; +#pragma omp target parallel for reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target parallel for reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + static int m; +#pragma omp target parallel for reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_schedule_messages.cpp b/test/OpenMP/target_parallel_for_schedule_messages.cpp new file mode 100644 index 0000000000000..075e1df7827c5 --- /dev/null +++ b/test/OpenMP/target_parallel_for_schedule_messages.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + #pragma omp target parallel for schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} + #pragma omp target parallel for schedule (guided argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}} + #pragma omp target parallel for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (guided, (ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} + #pragma omp target parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (dynamic, 1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target parallel for schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (dynamic, foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} + #pragma omp target parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp target parallel for' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp target parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp b/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp new file mode 100644 index 0000000000000..669cafeae1ea3 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp @@ -0,0 +1,203 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s + +struct B { + static int ib[20]; // expected-note 0 {{'B::ib' declared here}} + static constexpr int bfoo() { return 8; } +}; +namespace X { + B x; // expected-note {{'x' defined here}} +}; +constexpr int bfoo() { return 4; } + +int **z; +const int C1 = 1; +const int C2 = 2; +void test_aligned_colons(int *&rp) +{ + int *B = 0; + #pragma omp target parallel for simd aligned(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp target parallel for simd aligned(B::ib:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp target parallel for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp target parallel for simd aligned(z:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp target parallel for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}} + #pragma omp target parallel for simd aligned(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}} + #pragma omp target parallel for simd aligned(B,rp,::z: X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp target parallel for simd aligned(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp target parallel for simd aligned(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}} + #pragma omp target parallel for simd aligned(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +// expected-note@+1 {{'num' defined here}} +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; + // Negative number is passed as L. + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd aligned(arr:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp target parallel for simd aligned(num:4) + for (i = 0; i < num; ++i); + return T(); +} + +template<int LEN> int test_warn() { + int *ind2 = 0; + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd aligned(ind2:LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return 0; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; // expected-note {{'a' declared here}} +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 1 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; // expected-note 2 {{'h' defined here}} +#pragma omp threadprivate(h) + +template<class I, class C> int foomain(I argc, C **argv) { + I e(argc); + I g(argc); + int i; // expected-note {{declared here}} expected-note {{'i' defined here}} + // expected-note@+2 {{declared here}} + // expected-note@+1 {{reference to 'i' is not a constant expression}} + int &j = i; + #pragma omp target parallel for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned () // expected-error {{expected expression}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned(e, g) + for (I k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + #pragma omp target parallel for simd aligned(h) + for (I k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp target parallel for simd aligned(i) + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int *v = 0; + I i; + #pragma omp target parallel for simd aligned(v:16) + for (I k = 0; k < argc; ++k) { i = k; v += 2; } + } + float *f; + #pragma omp target parallel for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + int v = 0; + // expected-note@+2 {{initializer of 'j' is not a constant expression}} + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp target parallel for simd aligned(f:j) + for (I k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp target parallel for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + return 0; +} + +// expected-note@+1 2 {{'argc' defined here}} +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + test_warn<4>(); // ok + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + int i; + int &j = i; + #pragma omp target parallel for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp target parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp target parallel for simd aligned (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}} + #pragma omp target parallel for simd aligned (a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target parallel for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + #pragma omp target parallel for simd aligned(h) + for (int k = 0; k < argc; ++k) ++k; + int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} + foomain<int*,char>(pargc,argv); + return 0; +} + diff --git a/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_ast_print.cpp new file mode 100644 index 0000000000000..e25f93fbaefe9 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_ast_print.cpp @@ -0,0 +1,308 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target parallel for simd private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) + +template <class T, int N> +T tmain(T argc, T *argv) { + T b = argc, c, d, e, f, h; + T arr[N][10], arr1[N]; + T i, j; + T s; + static T a; +// CHECK: static T a; + static T g; + const T clen = 5; +// CHECK: T clen = 5; +#pragma omp threadprivate(g) +#pragma omp target parallel for simd schedule(dynamic) default(none) linear(a) + // CHECK: #pragma omp target parallel for simd schedule(dynamic) default(none) linear(a) + for (T i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (T i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp target parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + for (int j = 0; j < 2; ++j) + foo(); + // CHECK-NEXT: #pragma omp target parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: for (int j = 0; j < 2; ++j) + // CHECK-NEXT: foo(); + +#pragma omp target parallel for simd default(none), private(argc,b) firstprivate(argv) shared (d) if(parallel:argc > 0) num_threads(N) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:N][0:10]) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(N) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:N][0:10]) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if(N) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:N][:argc]) reduction(&& : h) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(N) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:N][:argc]) reduction(&&: h) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if(target:argc > 0) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(target: argc > 0) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if(parallel:argc > 0) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(parallel: argc > 0) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if(N) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(N) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(i) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(tofrom: i) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(arr1[0:10], i) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(tofrom: arr1[0:10],i) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(to: i) map(from: j) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(to: i) map(from: j) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(always,alloc: i) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(always,alloc: i) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd nowait + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd nowait + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd depend(in : argc, arr[i:argc], arr1[:]) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd depend(in : argc,arr[i:argc],arr1[:]) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd defaultmap(tofrom: scalar) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd defaultmap(tofrom: scalar) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd safelen(clen-1) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd safelen(clen - 1) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd simdlen(clen-1) + for (T i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd simdlen(clen - 1) + // CHECK-NEXT: for (T i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd aligned(arr1:N-1) + for (T i = 0; i < N; ++i) {} + // CHECK: #pragma omp target parallel for simd aligned(arr1: N - 1) + // CHECK-NEXT: for (T i = 0; i < N; ++i) { + // CHECK-NEXT: } + + return T(); +} + +int main(int argc, char **argv) { + int b = argc, c, d, e, f, h; + int arr[5][10], arr1[5]; + int i, j; + int s; + static int a; +// CHECK: static int a; + const int clen = 5; +// CHECK: int clen = 5; + static float g; +#pragma omp threadprivate(g) +#pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) + // CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; + +#pragma omp target parallel for simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (target: argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a:-5) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + foo(); + // CHECK: #pragma omp target parallel for simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: foo(); + +#pragma omp target parallel for simd default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(5) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:5][0:10]) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10]) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if (5) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:5][:argc]) reduction(&& : h) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: h) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if (target:argc > 0) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(target: argc > 0) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if (parallel:argc > 0) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(parallel: argc > 0) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd if (5) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd if(5) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(i) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(tofrom: i) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(arr1[0:10], i) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(tofrom: arr1[0:10],i) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(to: i) map(from: j) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(to: i) map(from: j) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd map(always,alloc: i) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd map(always,alloc: i) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd nowait + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd nowait + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd depend(in : argc, arr[i:argc], arr1[:]) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd depend(in : argc,arr[i:argc],arr1[:]) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd defaultmap(tofrom: scalar) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd defaultmap(tofrom: scalar) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd safelen(clen-1) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd safelen(clen - 1) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd simdlen(clen-1) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd simdlen(clen - 1) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + +#pragma omp target parallel for simd aligned(arr1:4) + for (int i = 0; i < 2; ++i) {} + // CHECK: #pragma omp target parallel for simd aligned(arr1: 4) + // CHECK-NEXT: for (int i = 0; i < 2; ++i) { + // CHECK-NEXT: } + + return (tmain<int, 5>(argc, &argc)); +} + +#endif diff --git a/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp new file mode 100644 index 0000000000000..ecf2d6e7889e9 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L + // expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + int j; // expected-note {{declared here}} + #pragma omp target parallel for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp target parallel for simd collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for simd', but found only 1}} +#if __cplusplus >= 201103L + // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + // expected-error@+3 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp target parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}} + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}} + return argc; +} + +int main(int argc, char **argv) { + int j; // expected-note {{declared here}} + #pragma omp target parallel for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} + #pragma omp target parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp target parallel for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#if __cplusplus >= 201103L + // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}} + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp target parallel for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp target parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_simd_default_messages.cpp b/test/OpenMP/target_parallel_for_simd_default_messages.cpp new file mode 100644 index 0000000000000..5d41cbcb457e1 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_default_messages.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +int main(int argc, char **argv) { + int i; +#pragma omp target parallel for simd default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp target parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target parallel for simd default(none) + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp target parallel for simd default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp b/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp new file mode 100644 index 0000000000000..e922e0a000b45 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +template <class T, typename S, int N, int ST> +T tmain(T argc, S **argv) { + int i; + #pragma omp target parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp new file mode 100644 index 0000000000000..0504cabd0f017 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + auto arr = x; // expected-error {{use of undeclared identifier 'x'}} + int i; + + #pragma omp target parallel for simd depend // expected-error {{expected '(' after 'depend'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (out: ) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[0]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : ) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : main) // expected-error {{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in : argv[ : argc][1 : argc - 1]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd depend(in : arr[0]) + for (i = 0; i < argc; ++i) foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_simd_device_messages.cpp b/test/OpenMP/target_parallel_for_simd_device_messages.cpp new file mode 100644 index 0000000000000..2c9d43f07b257 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_device_messages.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for simd device // expected-error {{expected '(' after 'device'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (argc + argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (argc), device (argc+1) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'device' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp new file mode 100644 index 0000000000000..9397314d87cc6 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp @@ -0,0 +1,261 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp target parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for simd firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) +#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}} + foo(); + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target parallel for simd firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd safelen(5) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel shared(xa) +#pragma omp target parallel for simd firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) +#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}} + foo(); + static int si; +#pragma omp target parallel for simd firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_simd_if_messages.cpp b/test/OpenMP/target_parallel_for_simd_if_messages.cpp new file mode 100644 index 0000000000000..b9e2891575b24 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_if_messages.cpp @@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + int i; + #pragma omp target parallel for simd if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for simd if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp new file mode 100644 index 0000000000000..51fc72464c9ab --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp @@ -0,0 +1,238 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + S2 &operator=(const S2 &); + const S2 &operator=(const S2 &) const; + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}} + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { + int a; + S4(); // expected-note 3 {{implicitly declared private here}} + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for simd lastprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for simd lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp target parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp target parallel for simd lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd safelen(5) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(i) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(xa) +#pragma omp target parallel for simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : xa) +#pragma omp target parallel for simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp target parallel for simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 2; + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp new file mode 100644 index 0000000000000..e17f15550e653 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp @@ -0,0 +1,269 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +namespace X { +int x; +}; + +struct B { + static int ib; // expected-note {{'B::ib' declared here}} + static int bfoo() { return 8; } +}; + +int bfoo() { return 4; } + +int z; +const int C1 = 1; +const int C2 = 2; +void test_linear_colons() { + int B = 0; +#pragma omp target parallel for simd linear(B : bfoo()) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} +#pragma omp target parallel for simd linear(B::ib : B : bfoo()) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}} +#pragma omp target parallel for simd linear(B : ib) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} +#pragma omp target parallel for simd linear(z : B : ib) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for simd linear(B : B::bfoo()) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for simd linear(X::x : ::z) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for simd linear(B, ::z, X::x) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for simd linear(::z) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for simd linear(B::bfoo()) + for (int i = 0; i < 10; ++i) + ; +#pragma omp target parallel for simd linear(B::ib, B : C1 + C2) + for (int i = 0; i < 10; ++i) + ; +} + +template <int L, class T, class N> +T test_template(T *arr, N num) { + N i; + T sum = (T)0; + T ind2 = -num * L; // expected-note {{'ind2' defined here}} +// expected-error@+1 {{argument of a linear clause should be of integral or pointer type}} +#pragma omp target parallel for simd linear(ind2 : L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template <int LEN> +int test_warn() { + int ind2 = 0; +// expected-warning@+1 {{zero linear step (ind2 should probably be const)}} +#pragma omp target parallel for simd linear(ind2 : LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return ind2; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} + +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target parallel for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc : 5) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +// expected-error@+2 {{linear variable with incomplete type 'S1'}} +// expected-error@+1 {{const-qualified variable cannot be linear}} +#pragma omp target parallel for simd linear(a, b : B::ib) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for simd linear(v : i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp target parallel for simd linear(j) + for (int k = 0; k < argc; ++k) + ++k; + int v = 0; +#pragma omp target parallel for simd linear(v : j) + for (int k = 0; k < argc; ++k) { + ++k; + v += j; + } +#pragma omp target parallel for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace C { +using A::x; +} + +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; +#pragma omp target parallel for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +// expected-error@+2 {{linear variable with incomplete type 'S1'}} +// expected-error@+1 {{const-qualified variable cannot be linear}} +#pragma omp target parallel for simd linear(a, b) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +// expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}} +// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} +#pragma omp target parallel for simd linear(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target parallel for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(i : 4) + for (int k = 0; k < argc; ++k) { + ++k; + i += 4; + } + } +#pragma omp target parallel for simd linear(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; + + foomain<int, char>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} + return 0; +} + diff --git a/test/OpenMP/target_parallel_for_simd_loop_messages.cpp b/test/OpenMP/target_parallel_for_simd_loop_messages.cpp new file mode 100644 index 0000000000000..c0dceeded4540 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_loop_messages.cpp @@ -0,0 +1,627 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s + +class S { + int a; + S() : a(0) {} + +public: + S(int v) : a(v) {} + S(const S &s) : a(s.a) {} +}; + +static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} +#pragma omp threadprivate(sii) +static int globalii; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; +#pragma omp target parallel for simd + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for simd + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for simd + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for simd + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp target parallel for simd + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp target parallel for simd + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp target parallel for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp target parallel for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (int &ref = ii; ref < 10; ref++) { + } +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (int i; i < 10; i++) + c[i] = a[i]; + +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// Ok to skip parenthesises. +#pragma omp target parallel for simd + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for simd + for (int i = 0; i; i++) + c[i] = a[i]; + +// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} +#pragma omp target parallel for simd + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for simd + for (int i = 0; !!i; i++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for simd + for (int i = 0; i != 1; i++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp target parallel for simd + for (int i = 0;; i++) + c[i] = a[i]; + +// Ok. +#pragma omp target parallel for simd + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +// Ok. +#pragma omp target parallel for simd + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +// Ok. +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +// Ok - step was converted to integer type. +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +// expected-warning@+3 {{relational comparison result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}} +#pragma omp target parallel for simd firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as linear}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be linear, predetermined as private}} +#pragma omp target parallel for simd linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target parallel for simd private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp target parallel for simd lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be threadprivate or thread local, predetermined as private}} +#pragma omp target parallel for simd + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + + { +#pragma omp target parallel for simd + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + + { +#pragma omp target parallel for simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +// expected-error@+2 {{statement after '#pragma omp target parallel for simd' must be a for loop}} +#pragma omp target parallel for simd + for (auto &item : a) { + item = item + 1; + } + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp target parallel for simd + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template <class Iter> +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template <class Iter> +typename iterator_traits<Iter>::difference_type +distance(Iter first, Iter last) { return first - last; } +} +class Iter0 { +public: + Iter0() {} + Iter0(const Iter0 &) {} + Iter0 operator++() { return *this; } + Iter0 operator--() { return *this; } + bool operator<(Iter0 a) { return true; } +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} +int operator-(Iter0 a, Iter0 b) { return 0; } +class Iter1 { +public: + Iter1(float f = 0.0f, double d = 0.0) {} + Iter1(const Iter1 &) {} + Iter1 operator++() { return *this; } + Iter1 operator--() { return *this; } + bool operator<(Iter1 a) { return true; } + bool operator>=(Iter1 a) { return false; } +}; +class GoodIter { +public: + GoodIter() {} + GoodIter(const GoodIter &) {} + GoodIter(int fst, int snd) {} + GoodIter &operator=(const GoodIter &that) { return *this; } + GoodIter &operator=(const Iter0 &that) { return *this; } + GoodIter &operator+=(int x) { return *this; } + GoodIter &operator-=(int x) { return *this; } + explicit GoodIter(void *) {} + GoodIter operator++() { return *this; } + GoodIter operator--() { return *this; } + bool operator!() { return true; } + bool operator<(GoodIter a) { return true; } + bool operator<=(GoodIter a) { return true; } + bool operator>=(GoodIter a) { return false; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} +GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +GoodIter operator-(GoodIter a, int v) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} +GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} +GoodIter operator-(int v, GoodIter a) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}} +GoodIter operator+(int v, GoodIter a) { return GoodIter(); } + +int test_with_random_access_iterator() { + GoodIter begin, end; + Iter0 begin0, end0; +#pragma omp target parallel for simd + for (GoodIter I = begin; I < end; ++I) + ++I; +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp target parallel for simd + for (GoodIter I = begin; I >= end; --I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (GoodIter I(begin); I < end; ++I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (GoodIter I(nullptr); I < end; ++I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (GoodIter I(0); I < end; ++I) + ++I; +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp target parallel for simd + for (begin = GoodIter(0); begin < end; ++begin) + ++begin; +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} +// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp target parallel for simd + for (begin = begin0; begin < end; ++begin) + ++begin; +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp target parallel for simd + for (begin = end; begin < end; ++begin) + ++begin; +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp target parallel for simd + for (GoodIter I = begin; I - I; ++I) + ++I; +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp target parallel for simd + for (GoodIter I = begin; begin < end; ++I) + ++I; +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp target parallel for simd + for (GoodIter I = begin; !I; ++I) + ++I; +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp target parallel for simd + for (GoodIter I = begin; I >= end; I = I - 1) + ++I; +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp target parallel for simd + for (GoodIter I = begin; I >= end; I = -I) + ++I; +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (GoodIter I = begin; I >= end; I = 2 + I) + ++I; +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp target parallel for simd + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; +// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}} +#pragma omp target parallel for simd + for (Iter0 I = begin0; I < end0; ++I) + ++I; +// Initializer is constructor without params. +// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (Iter0 I; I < end0; ++I) + ++I; + Iter1 begin1, end1; +// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp target parallel for simd + for (Iter1 I = begin1; I < end1; ++I) + ++I; +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}} +// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +// Initializer is constructor with all default params. +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp target parallel for simd + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template <typename IT, int ST> +class TC { +public: + int dotest_lt(IT begin, IT end) { +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp target parallel for simd + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template <typename IT, int ST = 0> +int dotest_gt(IT begin, IT end) { +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (IT I = begin; I >= end; I += ST) { + ++I; + } + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp target parallel for simd + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp target parallel for simd + for (IT I = begin; I < end; I += TC<int, ST>::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC<GoodIter, 100> t1; + TC<GoodIter, -100> t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} + dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp target parallel for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + break; // OK in nested loop + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + if (c[i] > 10) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + + if (c[i] > 11) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + } + +#pragma omp target parallel for simd + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + c[i] = a[i] + b[i]; + if (c[i] > 10) { + if (c[i] < 20) { + break; // OK + } + } + } + } +} + +void test_loop_eh() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp target parallel for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + try { + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + throw a[i]; + } + throw a[i]; + } catch (float f) { + if (f > 0.1) + throw a[i]; + return; // expected-error {{cannot return from OpenMP region}} + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + for (int j = 0; j < 10; j++) { + if (c[i] > 10) + throw c[i]; + } + } + if (c[9] > 10) + throw c[9]; // OK + +#pragma omp target parallel for simd + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp target parallel for simd lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp new file mode 100644 index 0000000000000..f44639e86cab2 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp @@ -0,0 +1,273 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; // expected-note 4 {{mappable type cannot contain static members}} + static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}} +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +typedef int from; + +template <typename T, int I> // expected-note {{declared here}} +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + T i, t[20]; + T &j = i; + T *k = &j; + T x; + T y; + T to, tofrom, always; + const T (&l)[5] = da; + + +#pragma omp target parallel for simd map // expected-error {{expected '(' after 'map'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom: t[:I]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(T) // expected-error {{'T' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S2::S2s) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to: to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(ca) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S2::S2s) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(e, g) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(da[:4]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k, j, l) // expected-note 2 {{used here}} +#pragma omp target parallel for simd map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +{ +#pragma omp target parallel for simd map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + for (i = 0; i < argc; ++i) foo(); +} + +#pragma omp target parallel for simd map(always, tofrom: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(always, tofrom: always, tofrom, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int *k = &j; + int x; + int y; + int to, tofrom, always; + const int (&l)[5] = da; + +#pragma omp target parallel for simd map // expected-error {{expected '(' after 'map'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to: to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(argc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(argv[1]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(ca) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S2::S2s) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(e, g) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(da) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(da[:4]) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k, j, l) // expected-note {{used here}} +#pragma omp target parallel for simd map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +{ +#pragma omp target parallel for simd map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(j) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + for (i = 0; i < argc; ++i) foo(); +} + +#pragma omp target parallel for simd map(always, tofrom: x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(always, tofrom: always, tofrom, x) + for (i = 0; i < argc; ++i) foo(); +#pragma omp target parallel for simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}} +} + diff --git a/test/OpenMP/target_parallel_for_simd_messages.cpp b/test/OpenMP/target_parallel_for_simd_messages.cpp new file mode 100644 index 0000000000000..0e1a0fea7e619 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_messages.cpp @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +static int pvt; +#pragma omp threadprivate(pvt) + +#pragma omp target parallel for simd // expected-error {{unexpected OpenMP directive '#pragma omp target parallel for simd'}} + +int main(int argc, char **argv) { +#pragma omp target parallel for simd { // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd ( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd[ // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd] // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd } // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd + for (int i = 0; i < argc; ++i) + foo(); +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +#pragma omp target parallel for simd unknown() + for (int i = 0; i < argc; ++i) + foo(); +L1: + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd + for (int i = 0; i < argc; ++i) { + goto L1; // expected-error {{use of undeclared label 'L1'}} + argc++; + } + + for (int i = 0; i < 10; ++i) { + switch (argc) { + case (0): +#pragma omp target parallel for simd + for (int i = 0; i < argc; ++i) { + foo(); + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + continue; + } + default: + break; + } + } +#pragma omp target parallel for simd default(none) + for (int i = 0; i < 10; ++i) + ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + + goto L2; // expected-error {{use of undeclared label 'L2'}} +#pragma omp target parallel for simd + for (int i = 0; i < argc; ++i) + L2: + foo(); +#pragma omp target parallel for simd + for (int i = 0; i < argc; ++i) { + return 1; // expected-error {{cannot return from OpenMP region}} + } + + [[]] // expected-error {{an attribute list cannot appear here}} +#pragma omp target parallel for simd + for (int n = 0; n < 100; ++n) { + } + +#pragma omp target parallel for simd copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target parallel for simd'}} + for (int n = 0; n < 100; ++n) {} + + return 0; +} + +void test_ordered() { +#pragma omp target parallel for simd ordered ordered // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}} + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/target_parallel_for_simd_misc_messages.c b/test/OpenMP/target_parallel_for_simd_misc_messages.c new file mode 100644 index 0000000000000..2adc6f85116e6 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_misc_messages.c @@ -0,0 +1,495 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for simd'}} +#pragma omp target parallel for simd + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for simd'}} +#pragma omp target parallel for simd foo + +void test_no_clause() { + int i; +#pragma omp target parallel for simd + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp target parallel for simd' must be a for loop}} +#pragma omp target parallel for simd + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp target parallel for simd + for (i = 0; i < 16; ++i) { + if (i == 5) + goto L1; // expected-error {{use of undeclared label 'L1'}} + else if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + else if (i == 7) + goto L2; + else if (i == 8) { + L2: + x[i]++; + } + } + + if (x[0] == 0) + goto L2; // expected-error {{use of undeclared label 'L2'}} + else if (x[1] == 1) + goto L1; +} + +void test_invalid_clause() { + int i; +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +#pragma omp target parallel for simd foo bar + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +#pragma omp target parallel for simd; + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +#pragma omp target parallel for simd private(x); + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +#pragma omp target parallel for simd, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); + +void test_collapse() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd collapse + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd collapse( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd collapse() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd collapse(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd collapse 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +#pragma omp target parallel for simd collapse(4) + for (int i1 = 0; i1 < 16; ++i1) + for (int i2 = 0; i2 < 16; ++i2) + for (int i3 = 0; i3 < 16; ++i3) + for (int i4 = 0; i4 < 16; ++i4) + foo(); +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp target parallel for simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd collapse(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +// expected-note@+1 {{defined as firstprivate}} +#pragma omp target parallel for simd collapse(2) firstprivate(i) + for (i = 0; i < 16; ++i) +// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+2 2 {{reduction variable must be shared}} +// expected-error@+1 {{region cannot be closely nested inside 'target parallel for simd' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +#pragma omp for reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; +} + +void test_private() { + int i; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd private( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for simd private(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for simd private(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd private() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd private(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for simd private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target parallel for simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd lastprivate() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target parallel for simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd firstprivate( + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for simd firstprivate(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp target parallel for simd firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd firstprivate() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd firstprivate(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp target parallel for simd firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp target parallel for simd lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd lastprivate(x, y, z) firstprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_loop_messages() { + float a[100], b[100], c[100]; +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp target parallel for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp target parallel for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +} + +void test_safelen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd safelen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd safelen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd safelen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd safelen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd simdlen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd simdlen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp target parallel for simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp target parallel for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} diff --git a/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp b/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp new file mode 100644 index 0000000000000..3c4b512048177 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait device (-10u) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp new file mode 100644 index 0000000000000..1076b86ea5e67 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + T i; + #pragma omp target parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; + #pragma omp target parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target parallel for simd num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp new file mode 100644 index 0000000000000..70a3b4ef62454 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp @@ -0,0 +1,122 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L + // expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + int j; // expected-note {{declared here}} +#pragma omp target parallel for simd ordered + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered() // expected-error {{expected expression}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 2 {{expression is not an integral constant expression}} +// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp target parallel for simd ordered(argc + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd ordered(ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for simd', but found only 1}} +#if __cplusplus >= 201103L + // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +// expected-error@+3 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}} +// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +// expected-error@+1 2 {{expression is not an integral constant expression}} +#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered(S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +// expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}} +// expected-error@+1 {{expression is not an integral constant expression}} +#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered(1) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered(N) // expected-error {{argument to 'ordered' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp target parallel for simd ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}} + return argc; +} + +int main(int argc, char **argv) { + int j; // expected-note {{declared here}} +#pragma omp target parallel for simd ordered + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for simd ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for simd ordered() // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for simd ordered(4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'ordered' clause}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +#pragma omp target parallel for simd ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} expected-note {{as specified in 'ordered' clause}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target parallel for simd ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#if __cplusplus >= 201103L + // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +// expected-error@+3 {{expression is not an integral constant expression}} +// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}} +// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5) + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp target parallel for simd ordered(S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +// expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}} +// expected-error@+1 {{expression is not an integral constant expression}} +#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +// expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}} +// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target parallel for simd ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp target parallel for simd ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_simd_private_messages.cpp b/test/OpenMP/target_parallel_for_simd_private_messages.cpp new file mode 100644 index 0000000000000..57262a58598c5 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_private_messages.cpp @@ -0,0 +1,231 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) { +#pragma omp target parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target parallel for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp target parallel for simd private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target parallel for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp target parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target parallel for simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp target parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int m; +#pragma omp target parallel for simd private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; + + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp b/test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp new file mode 100644 index 0000000000000..5bb6d92cd7e9e --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +int main(int argc, char **argv) { + int i; +#pragma omp target parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp target parallel for simd proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp target parallel for simd proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + return 0; +} diff --git a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp new file mode 100644 index 0000000000000..3999d38162843 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp @@ -0,0 +1,313 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + int b; + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+(const S3 &arg1) { return arg1; } +}; +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 3 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + S4(const S4 &s4); + S4 &operator+(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} +#endif + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; +#pragma omp target parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target parallel for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; +#pragma omp target parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp target parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp target parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp target parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + static int m; +#pragma omp target parallel for simd reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp new file mode 100644 index 0000000000000..f99010179dc30 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp @@ -0,0 +1,102 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp target parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp target parallel for simd safelen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd safelen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+6 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp target parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif + #pragma omp target parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd safelen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp target parallel for simd safelen (foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif + #pragma omp target parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp target parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_simd_schedule_messages.cpp b/test/OpenMP/target_parallel_for_simd_schedule_messages.cpp new file mode 100644 index 0000000000000..f0d86e952de6a --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_schedule_messages.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + #pragma omp target parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} + #pragma omp target parallel for simd schedule (guided argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (guided, (ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (dynamic, 1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp target parallel for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (dynamic, foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} + #pragma omp target parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp target parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp target parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp target parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp new file mode 100644 index 0000000000000..e51e67b6b45f2 --- /dev/null +++ b/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp @@ -0,0 +1,142 @@ +// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s + +void foo() { +} + +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp target parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 2 {{expression is not an integral constant expression}} +// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} +#pragma omp target parallel for simd simdlen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + + // expected-error@+6 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + + #pragma omp target parallel for simd simdlen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + + #pragma omp target parallel for simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a strictly positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen (2), safelen (4) // OK + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen (4), safelen (4) // OK + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + +#pragma omp target parallel for simd simdlen (8), safelen (4) // expected-error{{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + + return argc; +} + +int main(int argc, char **argv) { +#pragma omp target parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +#pragma omp target parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif +// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'simdlen' clause}} +// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif +#pragma omp target parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +// expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}} +// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} +#pragma omp target parallel for simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + +#pragma omp target parallel for simd simdlen (2), safelen (4) // OK + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen (4), safelen (4) // OK + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + +#pragma omp target parallel for simd simdlen (8), safelen (4) // expected-error{{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/target_parallel_if_messages.cpp b/test/OpenMP/target_parallel_if_messages.cpp new file mode 100644 index 0000000000000..e22eb8150af65 --- /dev/null +++ b/test/OpenMP/target_parallel_if_messages.cpp @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp target parallel if // expected-error {{expected '(' after 'if'}} + foo(); + #pragma omp target parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel if (argc > 0 ? argv[1] : argv[2]) + foo(); + #pragma omp target parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause}} + foo(); + #pragma omp target parallel if (S) // expected-error {{'S' does not refer to a value}} + foo(); + #pragma omp target parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(argc) + foo(); + #pragma omp target parallel if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(target : argc) + foo(); + #pragma omp target parallel if(parallel : argc) + foo(); + #pragma omp target parallel if(target : argc) if(parallel : argc) + foo(); + #pragma omp target parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel'}} + foo(); + #pragma omp target parallel if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'target' name modifier}} + foo(); + #pragma omp target parallel if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}} + foo(); + #pragma omp target parallel if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + #pragma omp target parallel if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp target parallel if // expected-error {{expected '(' after 'if'}} + foo(); + #pragma omp target parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel if (argc > 0 ? argv[1] : argv[2]) + foo(); + #pragma omp target parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause}} + foo(); + #pragma omp target parallel if (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel if(parallel : argc) + foo(); + #pragma omp target parallel if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel'}} + foo(); + #pragma omp target parallel if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'target' name modifier}} + foo(); + #pragma omp target parallel if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}} + foo(); + #pragma omp target parallel if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + #pragma omp target parallel if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp new file mode 100644 index 0000000000000..ff20567185bf5 --- /dev/null +++ b/test/OpenMP/target_parallel_map_messages.cpp @@ -0,0 +1,272 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; // expected-note 4 {{mappable type cannot contain static members}} + static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}} +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +typedef int from; + +template <typename T, int I> // expected-note {{declared here}} +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + T i, t[20]; + T &j = i; + T *k = &j; + T x; + T y; + T to, tofrom, always; + const T (&l)[5] = da; + + +#pragma omp target parallel map // expected-error {{expected '(' after 'map'}} + foo(); +#pragma omp target parallel map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + foo(); +#pragma omp target parallel map() // expected-error {{expected expression}} + foo(); +#pragma omp target parallel map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + foo(); +#pragma omp target parallel map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + foo(); +#pragma omp target parallel map(to:) // expected-error {{expected expression}} + foo(); +#pragma omp target parallel map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + foo(); +#pragma omp target parallel map(x) + foo(); +#pragma omp target parallel map(tofrom: t[:I]) + foo(); +#pragma omp target parallel map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}} + foo(); +#pragma omp target parallel map(T) // expected-error {{'T' does not refer to a value}} + foo(); +#pragma omp target parallel map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} + foo(); +#pragma omp target parallel map(S2::S2s) + foo(); +#pragma omp target parallel map(S2::S2sc) + foo(); +#pragma omp target parallel map(x) + foo(); +#pragma omp target parallel map(to: x) + foo(); +#pragma omp target parallel map(to: to) + foo(); +#pragma omp target parallel map(to) + foo(); +#pragma omp target parallel map(to, x) + foo(); +#pragma omp target parallel map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} + foo(); +#pragma omp target parallel map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} + foo(); +#pragma omp target parallel map(argc) + foo(); +#pragma omp target parallel map(S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} + foo(); +#pragma omp target parallel map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} + foo(); +#pragma omp target parallel map(ca) + foo(); +#pragma omp target parallel map(da) + foo(); +#pragma omp target parallel map(S2::S2s) + foo(); +#pragma omp target parallel map(S2::S2sc) + foo(); +#pragma omp target parallel map(e, g) + foo(); +#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + foo(); +#pragma omp target parallel map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} + foo(); +#pragma omp target parallel map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}} + foo(); +#pragma omp target parallel map(da) + foo(); +#pragma omp target parallel map(da[:4]) + foo(); +#pragma omp target data map(k, j, l) // expected-note 2 {{used here}} +#pragma omp target parallel map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} + foo(); +#pragma omp target parallel map(j) + foo(); +#pragma omp target parallel map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} + foo(); +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +{ +#pragma omp target parallel map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} + foo(); +#pragma omp target parallel map(j) + foo(); +#pragma omp target parallel map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + foo(); +} + +#pragma omp target parallel map(always, tofrom: x) + foo(); +#pragma omp target parallel map(always: x) // expected-error {{missing map type}} + foo(); +#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + foo(); +#pragma omp target parallel map(always, tofrom: always, tofrom, x) + foo(); +#pragma omp target parallel map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + foo(); + + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + int *k = &j; + int x; + int y; + int to, tofrom, always; + const int (&l)[5] = da; +#pragma omp target parallel map // expected-error {{expected '(' after 'map'}} + foo(); +#pragma omp target parallel map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} + foo(); +#pragma omp target parallel map() // expected-error {{expected expression}} + foo(); +#pragma omp target parallel map(alloc) // expected-error {{use of undeclared identifier 'alloc'}} + foo(); +#pragma omp target parallel map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}} + foo(); +#pragma omp target parallel map(to:) // expected-error {{expected expression}} + foo(); +#pragma omp target parallel map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + foo(); +#pragma omp target parallel map(x) + foo(); +#pragma omp target parallel map(to: x) + foo(); +#pragma omp target parallel map(to: to) + foo(); +#pragma omp target parallel map(to) + foo(); +#pragma omp target parallel map(to, x) + foo(); +#pragma omp target parallel map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} + foo(); +#pragma omp target parallel map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + foo(); +#pragma omp target parallel map(argc) + foo(); +#pragma omp target parallel map(S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} + foo(); +#pragma omp target parallel map(argv[1]) + foo(); +#pragma omp target parallel map(ba) // expected-error 2 {{type 'S2' is not mappable to target}} + foo(); +#pragma omp target parallel map(ca) + foo(); +#pragma omp target parallel map(da) + foo(); +#pragma omp target parallel map(S2::S2s) + foo(); +#pragma omp target parallel map(S2::S2sc) + foo(); +#pragma omp target parallel map(e, g) + foo(); +#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} + foo(); +#pragma omp target parallel map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} + foo(); +#pragma omp target parallel map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} + foo(); +#pragma omp target parallel map(da) + foo(); +#pragma omp target parallel map(da[:4]) + foo(); +#pragma omp target data map(k, j, l) // expected-note {{used here}} +#pragma omp target parallel map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + foo(); +#pragma omp target parallel map(j) + foo(); +#pragma omp target parallel map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}} + foo(); +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +{ +#pragma omp target parallel map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} + foo(); +#pragma omp target parallel map(j) + foo(); +#pragma omp target parallel map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} + foo(); +} + +#pragma omp target parallel map(always, tofrom: x) + foo(); +#pragma omp target parallel map(always: x) // expected-error {{missing map type}} + foo(); +#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} + foo(); +#pragma omp target parallel map(always, tofrom: always, tofrom, x) + foo(); +#pragma omp target parallel map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + foo(); + + return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}} +} + diff --git a/test/OpenMP/target_parallel_messages.cpp b/test/OpenMP/target_parallel_messages.cpp new file mode 100644 index 0000000000000..b6763d8f09e03 --- /dev/null +++ b/test/OpenMP/target_parallel_messages.cpp @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s +// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s +// CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd' + +void foo() { +} + +static int pvt; +#pragma omp threadprivate(pvt) + +#pragma omp target parallel // expected-error {{unexpected OpenMP directive '#pragma omp target parallel'}} + +int main(int argc, char **argv) { + #pragma omp target parallel { // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel ( // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel [ // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel ] // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel ) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel } // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel + foo(); + // expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + #pragma omp target parallel unknown() + foo(); + L1: + foo(); + #pragma omp target parallel + ; + #pragma omp target parallel + { + goto L1; // expected-error {{use of undeclared label 'L1'}} + argc++; + } + + for (int i = 0; i < 10; ++i) { + switch(argc) { + case (0): + #pragma omp target parallel + { + foo(); + break; // expected-error {{'break' statement not in loop or switch statement}} + continue; // expected-error {{'continue' statement not in loop statement}} + } + default: + break; + } + } + + goto L2; // expected-error {{use of undeclared label 'L2'}} + #pragma omp target parallel + L2: + foo(); + #pragma omp target parallel + { + return 1; // expected-error {{cannot return from OpenMP region}} + } + + [[]] // expected-error {{an attribute list cannot appear here}} + #pragma omp target parallel + for (int n = 0; n < 100; ++n) {} + + #pragma omp target parallel copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target parallel'}} + foo(); + + return 0; +} + diff --git a/test/OpenMP/target_parallel_nowait_messages.cpp b/test/OpenMP/target_parallel_nowait_messages.cpp new file mode 100644 index 0000000000000..91e26f20819f6 --- /dev/null +++ b/test/OpenMP/target_parallel_nowait_messages.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo() { +} + +int main(int argc, char **argv) { + #pragma omp target parallel nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel nowait device (-10u) + foo(); + #pragma omp target parallel nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_parallel_num_threads_messages.cpp b/test/OpenMP/target_parallel_num_threads_messages.cpp new file mode 100644 index 0000000000000..95797caf29622 --- /dev/null +++ b/test/OpenMP/target_parallel_num_threads_messages.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +#define redef_num_threads(a, b) num_threads(a) + +template <class T, typename S, int N> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + #pragma omp target parallel num_threads // expected-error {{expected '(' after 'num_threads'}} + foo(); + #pragma omp target parallel num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel num_threads () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + #pragma omp target parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + foo(); + #pragma omp target parallel num_threads (S) // expected-error {{'S' does not refer to a value}} + foo(); + #pragma omp target parallel num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + #pragma omp target parallel num_threads (argc) + foo(); + #pragma omp target parallel num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + foo(); + #pragma omp target parallel redef_num_threads (argc, argc) + foo(); + + return argc; +} + +int main(int argc, char **argv) { + #pragma omp target parallel num_threads // expected-error {{expected '(' after 'num_threads'}} + foo(); + #pragma omp target parallel num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel num_threads () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); + #pragma omp target parallel num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} + foo(); + #pragma omp target parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} + foo(); + #pragma omp target parallel num_threads (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target parallel num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + #pragma omp target parallel num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}} + foo(); + #pragma omp target parallel redef_num_threads (argc, argc) + foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/target_parallel_private_messages.cpp b/test/OpenMP/target_parallel_private_messages.cpp new file mode 100644 index 0000000000000..fabd37d4b3950 --- /dev/null +++ b/test/OpenMP/target_parallel_private_messages.cpp @@ -0,0 +1,222 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} expected-note 1 {{forward declaration of 'S1'}} expected-note {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + static float S2s; // expected-note {{static data member is predetermined as shared}} expected-note 1 {{static data member is predetermined as shared}} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}} + +int threadvar; +#pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} expected-note 1 {{defined as threadprivate or thread local}} + +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} expected-note 1 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} expected-note 1 {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} expected-note 1 {{defined as threadprivate or thread local}} expected-note 2 {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C, class D, class E> +int foomain(I argc, C **argv) { + const I d = 5; // expected-note {{constant variable is predetermined as shared}} + const I da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}} + D e(4); + E g[] = {5, 6}; + I i; + I &j = i; +#pragma omp target parallel private // expected-error {{expected '(' after 'private'}} +{} +#pragma omp target parallel private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target parallel private() // expected-error {{expected expression}} +{} +#pragma omp target parallel private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target parallel private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target parallel private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +{} +#pragma omp target parallel private(argc argv) // expected-error {{expected ',' or ')' in 'private' clause}} +{} +#pragma omp target parallel private(argc) +{} +#pragma omp target parallel private(S1) // expected-error {{'S1' does not refer to a value}} +{} +#pragma omp target parallel private(a, b) // expected-error {{private variable with incomplete type 'S1'}} +{} +#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}} +{} +#pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}} +{} +#pragma omp target parallel private(ba) +{} +#pragma omp target parallel private(ca) // expected-error {{shared variable cannot be private}} +{} +#pragma omp target parallel private(da) // expected-error {{shared variable cannot be private}} +{} +#pragma omp target parallel private(S2::S2s) // expected-error {{shared variable cannot be private}} +{} +#pragma omp target parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} +{} + #pragma omp target parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + {} + #pragma omp target parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} + foo(); + #pragma omp target parallel firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} + foo(); + #pragma omp target parallel private(i) + {} + #pragma omp target parallel private(j) + foo(); + #pragma omp parallel firstprivate(i) + for (int k = 0; k < 10; ++k) { + #pragma omp target parallel private(i) + foo(); + } + static int m; + #pragma omp target parallel private(m) // OK + foo(); +#pragma omp target parallel private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +{} +#pragma omp target parallel private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp parallel + { + int v = 0; + int i; + } +#pragma omp target parallel shared(i) +{} +#pragma omp target parallel private(i) +{} +#pragma omp target parallel private(j) +{} +#pragma omp target parallel private(i) +{} + static int si; +#pragma omp target parallel private(si) // OK + {} + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp target parallel private(a) + {} +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g[] = {5, 6}; + int i; + int &j = i; +#pragma omp target parallel private // expected-error {{expected '(' after 'private'}} +{} +#pragma omp target parallel private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target parallel private() // expected-error {{expected expression}} +{} +#pragma omp target parallel private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target parallel private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target parallel private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +{} +#pragma omp target parallel private(argc argv) // expected-error {{expected ',' or ')' in 'private' clause}} +{} +#pragma omp target parallel private(argc) +{} +#pragma omp target parallel private(S1) // expected-error {{'S1' does not refer to a value}} +{} +#pragma omp target parallel private(a, b) // expected-error {{private variable with incomplete type 'S1'}} +{} +#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}} +{} +#pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}} +{} +#pragma omp target parallel private(ba) +{} +#pragma omp target parallel private(ca) // expected-error {{shared variable cannot be private}} +{} +#pragma omp target parallel private(da) // expected-error {{shared variable cannot be private}} +{} +#pragma omp target parallel private(S2::S2s) // expected-error {{shared variable cannot be private}} +{} +#pragma omp target parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} +{} + #pragma omp target parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} + {} + #pragma omp target parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} + foo(); + #pragma omp target parallel firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} + foo(); + #pragma omp target parallel private(i) + {} + #pragma omp target parallel private(j) + foo(); + #pragma omp parallel firstprivate(i) + for (int k = 0; k < 10; ++k) { + #pragma omp target parallel private(i) + foo(); + } + static int m; + #pragma omp target parallel private(m) // OK + foo(); +#pragma omp target parallel private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +{} +#pragma omp target parallel private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}} +#pragma omp parallel + { + int i; + } +#pragma omp target parallel shared(i) +{} +#pragma omp target parallel private(i) +{} +#pragma omp target parallel private(j) +{} +#pragma omp target parallel private(i) +{} + static int si; +#pragma omp target parallel private(si) // OK + {} + return foomain<int, char, S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char, S4, S5>' requested here}} +} + diff --git a/test/OpenMP/target_parallel_proc_bind_messages.cpp b/test/OpenMP/target_parallel_proc_bind_messages.cpp new file mode 100644 index 0000000000000..56292ad437032 --- /dev/null +++ b/test/OpenMP/target_parallel_proc_bind_messages.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s + +void foo(); + +int main(int argc, char **argv) { + #pragma omp target parallel proc_bind // expected-error {{expected '(' after 'proc_bind'}} + foo(); + #pragma omp target parallel proc_bind ( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel proc_bind () // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + foo(); + #pragma omp target parallel proc_bind (master // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel proc_bind (close), proc_bind(spread) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'proc_bind' clause}} + foo(); + #pragma omp target parallel proc_bind (x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + foo(); + + #pragma omp target parallel proc_bind(master) + ++argc; + + #pragma omp target parallel proc_bind(close) + foo(); + #pragma omp target parallel proc_bind(spread) + ++argc; + return 0; +} diff --git a/test/OpenMP/target_parallel_reduction_messages.cpp b/test/OpenMP/target_parallel_reduction_messages.cpp new file mode 100644 index 0000000000000..c9434e76245b9 --- /dev/null +++ b/test/OpenMP/target_parallel_reduction_messages.cpp @@ -0,0 +1,263 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + int b; + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+(const S3 &arg1) { return arg1; } +}; +int operator+(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 3 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + S4(const S4 &s4); + S4 &operator+(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} +#endif + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; +#pragma omp target parallel reduction // expected-error {{expected '(' after 'reduction'}} + foo(); +#pragma omp target parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); +#pragma omp target parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + foo(); +#pragma omp target parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target parallel reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + foo(); +#pragma omp target parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} + foo(); +#pragma omp target parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} + foo(); +#pragma omp target parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} + foo(); +#pragma omp target parallel reduction(&& : argc) + foo(); +#pragma omp target parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}} + foo(); +#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} + foo(); +#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + foo(); +#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + foo(); +#pragma omp target parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + foo(); +#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + foo(); +#pragma omp target parallel reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} + foo(); +#pragma omp target parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp parallel private(k) +#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} + foo(); +#pragma omp target parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel shared(i) + foo(); +#pragma omp parallel reduction(min : i) +#pragma omp target parallel reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target parallel +#pragma omp for private(fl) + for (int i = 0; i < 10; ++i) + {} +#pragma omp target parallel reduction(+ : fl) + foo(); +#pragma omp target parallel +#pragma omp for reduction(- : fl) + for (int i = 0; i < 10; ++i) + {} +#pragma omp target parallel reduction(+ : fl) + foo(); + + return T(); +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; +#pragma omp target parallel reduction // expected-error {{expected '(' after 'reduction'}} + foo(); +#pragma omp target parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} + foo(); +#pragma omp target parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + foo(); +#pragma omp target parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target parallel reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + foo(); +#pragma omp target parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} + foo(); +#pragma omp target parallel reduction(~ : argc) // expected-error {{expected unqualified-id}} + foo(); +#pragma omp target parallel reduction(&& : argc) + foo(); +#pragma omp target parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} + foo(); +#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} + foo(); +#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} + foo(); +#pragma omp target parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + foo(); +#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} + foo(); +#pragma omp target parallel reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} + foo(); +#pragma omp target parallel reduction(+ : o) // expected-error {{no viable overloaded '='}} + foo(); +#pragma omp target parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp parallel private(k) +#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + foo(); +#pragma omp target parallel reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} + foo(); +#pragma omp target parallel shared(i) + foo(); +#pragma omp parallel reduction(min : i) +#pragma omp target parallel reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target parallel +#pragma omp for private(fl) + for (int i = 0; i < 10; ++i) + {} +#pragma omp target parallel reduction(+ : fl) + foo(); +#pragma omp target parallel +#pragma omp for reduction(- : fl) + for (int i = 0; i < 10; ++i) + {} +#pragma omp target parallel reduction(+ : fl) + foo(); + static int m; +#pragma omp target parallel reduction(+ : m) // OK + m++; + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/target_parallel_shared_messages.cpp b/test/OpenMP/target_parallel_shared_messages.cpp new file mode 100644 index 0000000000000..302a09239d341 --- /dev/null +++ b/test/OpenMP/target_parallel_shared_messages.cpp @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + #pragma omp target parallel shared // expected-error {{expected '(' after 'shared'}} + foo(); + #pragma omp target parallel shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel shared () // expected-error {{expected expression}} + foo(); + #pragma omp target parallel shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target parallel shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + foo(); + #pragma omp target parallel shared (argc) + foo(); + #pragma omp target parallel shared (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target parallel shared (a, b, c, d, f) + foo(); + #pragma omp target parallel shared (argv[1]) // expected-error {{expected variable name}} + foo(); + #pragma omp target parallel shared(ba) + foo(); + #pragma omp target parallel shared(ca) + foo(); + #pragma omp target parallel shared(da) + foo(); + #pragma omp target parallel shared(e, g) + foo(); + #pragma omp target parallel shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}} + foo(); + #pragma omp target parallel private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} + foo(); + #pragma omp target parallel firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} + foo(); + #pragma omp target parallel private(i) + foo(); + #pragma omp target parallel shared(i) + foo(); + #pragma omp target parallel shared(j) + foo(); + #pragma omp target parallel firstprivate(i) + foo(); + #pragma omp target parallel shared(i) + foo(); + #pragma omp target parallel shared(j) + foo(); + + return 0; +} diff --git a/test/OpenMP/target_private_codegen.cpp b/test/OpenMP/target_private_codegen.cpp new file mode 100644 index 0000000000000..5c738ee5930f9 --- /dev/null +++ b/test/OpenMP/target_private_codegen.cpp @@ -0,0 +1,264 @@ +// Only test codegen on target side, as private clause does not require any action on the host side +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 + +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +template<typename tx, typename ty> +struct TT{ + tx X; + ty Y; +}; + +// TCHECK: [[TT:%.+]] = type { i64, i8 } +// TCHECK: [[S1:%.+]] = type { double } + +int foo(int n) { + int a = 0; + short aa = 0; + float b[10]; + float bn[n]; + double c[5][10]; + double cn[5][n]; + TT<long long, char> d; + + #pragma omp target private(a) + { + } + + // TCHECK: define void @__omp_offloading_{{.+}}() + // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}, + // TCHECK-NOT: store {{.+}}, {{.+}} [[A]], + // TCHECK: ret void + +#pragma omp target private(a) + { + a = 1; + } + + // TCHECK: define void @__omp_offloading_{{.+}}() + // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]], + // TCHECK: ret void + + #pragma omp target private(a, aa) + { + a = 1; + aa = 1; + } + + // TCHECK: define void @__omp_offloading_{{.+}}() + // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]], + // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A2]], + // TCHECK: ret void + + #pragma omp target private(a, b, bn, c, cn, d) + { + a = 1; + b[2] = 1.0; + bn[3] = 1.0; + c[1][2] = 1.0; + cn[1][3] = 1.0; + d.X = 1; + d.Y = 1; + } + // make sure that private variables are generated in all cases and that we use those instances for operations inside the + // target region + // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]], i{{[0-9]+}} [[VLA3:%.+]]) + // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[VLA_ADDR4:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[B:%.+]] = alloca [10 x float], + // TCHECK: [[SSTACK:%.+]] = alloca i8*, + // TCHECK: [[C:%.+]] = alloca [5 x [10 x double]], + // TCHECK: [[D:%.+]] = alloca [[TT]], + // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: store i{{[0-9]+}} [[VLA3]], i{{[0-9]+}}* [[VLA_ADDR4]], + // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: [[VLA_ADDR_REF4:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR4]], + // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave() + // TCHECK: store i8* [[RET_STACK]], i8** [[SSTACK]], + // TCHECK: [[VLA5:%.+]] = alloca float, i{{[0-9]+}} [[VLA_ADDR_REF]], + // TCHECK: [[VLA6_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF2]], [[VLA_ADDR_REF4]] + // TCHECK: [[VLA6:%.+]] = alloca double, i{{[0-9]+}} [[VLA6_SIZE]], + + // a = 1 + // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]], + + // b[2] = 1.0 + // TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x float], [10 x float]* [[B]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // TCHECK: store float 1.0{{.*}}, float* [[B_GEP]], + + // bn[3] = 1.0 + // TCHECK: [[BN_GEP:%.+]] = getelementptr inbounds float, float* [[VLA5]], i{{[0-9]+}} 3 + // TCHECK: store float 1.0{{.*}}, float* [[BN_GEP]], + + // c[1][2] = 1.0 + // TCHECK: [[C_GEP1:%.+]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[C]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // TCHECK: [[C_GEP2:%.+]] = getelementptr inbounds [10 x double], [10 x double]* [[C_GEP1]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // TCHECK: store double 1.0{{.*}}, double* [[C_GEP2]], + + // cn[1][3] = 1.0 + // TCHECK: [[CN_IND:%.+]] = mul{{.+}} i{{[0-9]+}} 1, [[VLA_ADDR_REF4]] + // TCHECK: [[CN_GEP_IND:%.+]] = getelementptr inbounds double, double* [[VLA6]], i{{[0-9]+}} [[CN_IND]] + // TCHECK: [[CN_GEP_3:%.+]] = getelementptr inbounds double, double* [[CN_GEP_IND]], i{{[0-9]+}} 3 + // TCHECK: store double 1.0{{.*}}, double* [[CN_GEP_3]], + + // d.X = 1 + // [[X_FIELD:%.+]] = getelementptr inbounds [[TT]] [[TT]]* [[D]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // store i{{[0-9]+}} 1, i{{[0-9]+}}* [[X_FIELD]], + + // d.Y = 1 + // [[Y_FIELD:%.+]] = getelementptr inbounds [[TT]] [[TT]]* [[D]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // store i{{[0-9]+}} 1, i{{[0-9]+}}* [[Y_FIELD]], + + // finish + // [[RELOAD_SSTACK:%.+]] = load i8*, i8** [[SSTACK]], + // call ovid @llvm.stackrestore(i8* [[RELOAD_SSTACK]]) + // ret void + + return a; +} + + +template<typename tx> +tx ftemplate(int n) { + tx a = 0; + short aa = 0; + tx b[10]; + +#pragma omp target private(a,aa,b) + { + a = 1; + aa = 1; + b[2] = 1; + } + + return a; +} + +static +int fstatic(int n) { + int a = 0; + short aa = 0; + char aaa = 0; + int b[10]; + +#pragma omp target private(a,aa,aaa,b) + { + a = 1; + aa = 1; + aaa = 1; + b[2] = 1; + } + + return a; +} + +// TCHECK: define void @__omp_offloading_{{.+}}() +// TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[A3:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[B:%.+]] = alloca [10 x i{{[0-9]+}}], +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]], +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A2]], +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A3]], +// TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x i{{[0-9]+}}], [10 x i{{[0-9]+}}]* [[B]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[B_GEP]], +// TCHECK: ret void + +struct S1 { + double a; + + int r1(int n){ + int b = n+1; + short int c[2][n]; + +#pragma omp target private(b,c) + { + this->a = (double)b + 1.5; + c[1][1] = ++a; + } + + return c[1][1] + (int)b; + } + + // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]]) + // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*, + // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[B:%.+]] = alloca i{{[0-9]+}}, + // TCHECK: [[SSTACK:%.+]] = alloca i8*, + // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]], + // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]], + // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]], + // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]], + // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave() + // TCHECK: store i8* [[RET_STACK:%.+]], i8** [[SSTACK]], + + // this->a = (double)b + 1.5; + // TCHECK: [[VLA_IND:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF]], [[VLA_ADDR_REF2]] + // TCHECK: [[VLA3:%.+]] = alloca i{{[0-9]+}}, i{{[0-9]+}} [[VLA_IND]], + // TCHECK: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B]], + // TCHECK: [[B_CONV:%.+]] = sitofp i{{[0-9]+}} [[B_VAL]] to double + // TCHECK: [[NEW_A_VAL:%.+]] = fadd double [[B_CONV]], 1.5{{.+}}+00 + // TCHECK: [[A_FIELD:%.+]] = getelementptr inbounds [[S1]], [[S1]]* [[TH_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // TCHECK: store double [[NEW_A_VAL]], double* [[A_FIELD]], + + // c[1][1] = ++a; + // TCHECK: [[A_FIELD4:%.+]] = getelementptr inbounds [[S1]], [[S1]]* [[TH_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // TCHECK: [[A_FIELD4_VAL:%.+]] = load double, double* [[A_FIELD4]], + // TCHECK: [[A_FIELD_INC:%.+]] = fadd double [[A_FIELD4_VAL]], 1.0{{.+}}+00 + // TCHECK: store double [[A_FIELD_INC]], double* [[A_FIELD4]], + // TCHECK: [[A_FIELD_INC_CONV:%.+]] = fptosi double [[A_FIELD_INC]] to i{{[0-9]+}} + // TCHECK: [[C_IND:%.+]] = mul{{.+}} i{{[0-9]+}} 1, [[VLA_ADDR_REF2]] + // TCHECK: [[C_1_REF:%.+]] = getelementptr inbounds i{{[0-9]+}}, i{{[0-9]+}}* [[VLA3]], i{{[0-9]+}} [[C_IND]] + // TCHECK: [[C_1_1_REF:%.+]] = getelementptr inbounds i{{[0-9]+}}, i{{[0-9]+}}* [[C_1_REF]], i{{[0-9]+}} 1 + // TCHECK: store i{{[0-9]+}} [[A_FIELD_INC_CONV]], i{{[0-9]+}}* [[C_1_1_REF]], + + // finish + // TCHECK: [[RELOAD_SSTACK:%.+]] = load i8*, i8** [[SSTACK]], + // TCHECK: call void @llvm.stackrestore(i8* [[RELOAD_SSTACK]]) + // TCHECK: ret void +}; + + +int bar(int n){ + int a = 0; + a += foo(n); + S1 S; + a += S.r1(n); + a += fstatic(n); + a += ftemplate<int>(n); + + return a; +} + +// template +// TCHECK: define void @__omp_offloading_{{.+}}() +// TCHECK: [[A:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}}, +// TCHECK: [[B:%.+]] = alloca [10 x i{{[0-9]+}}], +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]], +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A2]], +// TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x i{{[0-9]+}}], [10 x i{{[0-9]+}}]* [[B]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[B_GEP]], +// TCHECK: ret void + +#endif diff --git a/test/OpenMP/target_private_messages.cpp b/test/OpenMP/target_private_messages.cpp new file mode 100644 index 0000000000000..a093a87056272 --- /dev/null +++ b/test/OpenMP/target_private_messages.cpp @@ -0,0 +1,198 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) { +#pragma omp target private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp target private // expected-error {{expected '(' after 'private'}} +{} +#pragma omp target private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target private() // expected-error {{expected expression}} +{} +#pragma omp target private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +{} +#pragma omp target private(argc) +{} +#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}} +{} +#pragma omp target private(a, b) // expected-error {{private variable with incomplete type 'S1'}} +{} +#pragma omp target private(argv[1]) // expected-error {{expected variable name}} +{} +#pragma omp target private(e, g) +{} +#pragma omp target private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +{} +#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}} +#pragma omp parallel + { + int v = 0; + int i; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target private(j) +{} +#pragma omp target private(i) + {} + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp target private(a) + {} +} + +namespace A { +double x; +#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} +} +namespace B { +using A::x; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); + int i; + int &j = i; +#pragma omp target private // expected-error {{expected '(' after 'private'}} +{} +#pragma omp target private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target private() // expected-error {{expected expression}} +{} +#pragma omp target private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +{} +#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +{} +#pragma omp target private(argc) +{} +#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}} +{} +#pragma omp target private(a, b) // expected-error {{private variable with incomplete type 'S1'}} +{} +#pragma omp target private(argv[1]) // expected-error {{expected variable name}} +{} +#pragma omp target private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} +{} +#pragma omp target private(h) // expected-error {{threadprivate or thread local variable cannot be private}} +{} +#pragma omp target private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}} +{} +#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}} +#pragma omp parallel + { + int i; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp target private(j) +{} +#pragma omp target private(i) + {} + static int si; +#pragma omp target private(si) // OK + {} +#pragma omp target map(i) private(i) // expected-error {{private variable cannot be in a map clause in '#pragma omp target' directive}} + {} + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} +} + diff --git a/test/OpenMP/target_update_ast_print.cpp b/test/OpenMP/target_update_ast_print.cpp new file mode 100644 index 0000000000000..3a98f54a0770f --- /dev/null +++ b/test/OpenMP/target_update_ast_print.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <class T, class U> +T foo(T targ, U uarg) { + static T a; + U b; + int l; +#pragma omp target update to(a) if(l>5) device(l) nowait depend(inout:l) + +#pragma omp target update from(b) if(l<5) device(l-1) nowait depend(inout:l) + return a + targ + (T)b; +} +// CHECK: static int a; +// CHECK-NEXT: float b; +// CHECK-NEXT: int l; +// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l) +// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l) +// CHECK: static char a; +// CHECK-NEXT: float b; +// CHECK-NEXT: int l; +// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l) +// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l) +// CHECK: static T a; +// CHECK-NEXT: U b; +// CHECK-NEXT: int l; +// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l) +// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l) + +int main(int argc, char **argv) { + static int a; + int n; + float f; + +// CHECK: static int a; +// CHECK-NEXT: int n; +// CHECK-NEXT: float f; +#pragma omp target update to(a) if(f>0.0) device(n) nowait depend(in:n) +// CHECK-NEXT: #pragma omp target update to(a) if(f > 0.) device(n) nowait depend(in : n) +#pragma omp target update from(f) if(f<0.0) device(n+1) nowait depend(in:n) +// CHECK-NEXT: #pragma omp target update from(f) if(f < 0.) device(n + 1) nowait depend(in : n) + return foo(argc, f) + foo(argv[0][0], f) + a; +} + +#endif diff --git a/test/OpenMP/target_update_codegen.cpp b/test/OpenMP/target_update_codegen.cpp new file mode 100644 index 0000000000000..f74ed49975374 --- /dev/null +++ b/test/OpenMP/target_update_codegen.cpp @@ -0,0 +1,245 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +///==========================================================================/// +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +#ifdef CK1 + +// CK1: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; +}; + +ST<int> gb; +double gc[100]; + +// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800] +// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34] + +// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4] +// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33] + +// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 34] + +// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24] +// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17] + +// CK1-LABEL: _Z3fooi +void foo(int arg) { + int la; + float lb[arg]; + + // Region 00 + // CK1-DAG: call void @__tgt_target_data_update(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}}) + // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]] + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target update if(1+3-5) device(arg) from(gc) + {++arg;} + + // Region 01 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target update to(la) if(1+3-4) + {++arg;} + + // Region 02 + // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + // CK1: [[IFTHEN]] + // CK1-DAG: call void @__tgt_target_data_update(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8* + // CK1: br label %[[IFEND:[^,]+]] + + // CK1: [[IFELSE]] + // CK1: br label %[[IFEND]] + // CK1: [[IFEND]] + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + #pragma omp target update to(arg) if(arg) device(4) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 03 + // CK1-DAG: call void @__tgt_target_data_update(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] + // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] + // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]] + // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8* + // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8* + // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4 + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1-NOT: __tgt_target_data_end + #pragma omp target update from(lb) + {++arg;} + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + {++arg;} + + // Region 04 + // CK1-DAG: call void @__tgt_target_data_update(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}}) + // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + + // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]] + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]] + + + // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 + // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]] + // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] + // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8* + // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0 + // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), + + // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK1-NOT: __tgt_target_data_end + #pragma omp target update to(gb.b[:3]) + {++arg;} +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +#ifdef CK2 + +// CK2: [[ST:%.+]] = type { i32, double* } +template <typename T> +struct ST { + T a; + double *b; + + T foo(T arg) { + // Region 00 + #pragma omp target update from(b[1:3]) if(a>123) device(arg) + {arg++;} + return arg; + } +}; + +// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24] +// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 34, i32 18] + +// CK2-LABEL: _Z3bari +int bar(int arg){ + ST<int> A; + return A.foo(arg); +} + +// Region 00 +// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] +// CK2: [[IFTHEN]] +// CK2-DAG: call void @__tgt_target_data_update(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}}) +// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}}, +// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] +// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + +// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 +// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]] +// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]] +// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8* +// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8* +// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + + +// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1 +// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]] +// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]] +// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8* +// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8* +// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1 +// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]], +// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1 + +// CK2: br label %[[IFEND:[^,]+]] + +// CK2: [[IFELSE]] +// CK2: br label %[[IFEND]] +// CK2: [[IFEND]] +// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +#ifdef CK3 + +// CK3-LABEL: no_target_devices +void no_target_devices(int arg) { + // CK3-NOT: tgt_target_data_update + // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK3: ret + #pragma omp target update to(arg) if(arg) device(4) + {++arg;} +} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 +// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 + +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64 +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32 +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32 +#ifdef CK4 + +// CK4-LABEL: device_side_scan +void device_side_scan(int arg) { + // CK4: tgt_target_data_update + // CK4: %{{.+}} = add nsw i32 %{{[^,]+}}, 1 + // CK4: ret + // TCK4-NOT: tgt_target_data_update + #pragma omp target update from(arg) if(arg) device(4) + {++arg;} +} +#endif +#endif diff --git a/test/OpenMP/target_update_depend_messages.cpp b/test/OpenMP/target_update_depend_messages.cpp new file mode 100644 index 0000000000000..fe3325d80fe47 --- /dev/null +++ b/test/OpenMP/target_update_depend_messages.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +template <class T, class S, class R> +int tmain(T argc, S **argv, R *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + char *arr; + int i, z; + + #pragma omp depend target update to(z) // expected-error{{expected an OpenMP directive}} + #pragma omp depend(out:argc) target update to(z) // expected-error{{expected an OpenMP directive}} + #pragma omp target depend(in:argc) update to(z) // expected-error{{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error{{unexpected OpenMP clause 'to' in directive '#pragma omp target'}} + {} + + #pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}} + #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + #pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}} + #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + #pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : argv[0]) + #pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}} + #pragma omp target update to(z) depend(in : tmain) // expected-error {{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + #pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + #pragma omp target update to(z) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + #pragma omp target update to(z) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp target update to(z) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + #pragma omp target update to(z) depend(in : argv[ : argc][1 : argc - 1]) + #pragma omp target update to(z) depend(in : arr[0]) + + return 0; +} + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + auto arr = x; // expected-error {{use of undeclared identifier 'x'}} + int z; + + #pragma omp depend target update to(z) // expected-error{{expected an OpenMP directive}} + #pragma omp depend(out:argc) target update to(z) // expected-error{{expected an OpenMP directive}} + #pragma omp target depend(in:argc) update to(z) // expected-error{{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error{{unexpected OpenMP clause 'to' in directive '#pragma omp target'}} + {} + + #pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}} + #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + #pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}} + #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + #pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : argv[0]) + #pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}} + #pragma omp target update to(z) depend(in : main) // expected-error {{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + #pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + #pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + #pragma omp target update to(z) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + #pragma omp target update to(z) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp target update to(z) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + #pragma omp target update to(z) depend(in : argv[ : argc][1 : argc - 1]) + #pragma omp target update to(z) depend(in : arr[0]) + + return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain<int, char, char>' requested here}} +} diff --git a/test/OpenMP/target_update_device_messages.cpp b/test/OpenMP/target_update_device_messages.cpp new file mode 100644 index 0000000000000..37112755805cc --- /dev/null +++ b/test/OpenMP/target_update_device_messages.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} + +template <class T, class S> +int tmain(T argc, S **argv) { + int i; +#pragma omp target update to(i) device // expected-error {{expected '(' after 'device'}} +#pragma omp target update to(i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(i) device () // expected-error {{expected expression}} +#pragma omp target update to(i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} +#pragma omp target update from(i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} +#pragma omp target update from(i) device (argc + argc) +#pragma omp target update from(i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} +#pragma omp target update from(i) device (S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target update from(i) device (3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp target update from(i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} +} + +int main(int argc, char **argv) { + int j; +#pragma omp target update to(j) device // expected-error {{expected '(' after 'device'}} +#pragma omp target update from(j) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(j) device () // expected-error {{expected expression}} +#pragma omp target update from(j) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(j) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} +#pragma omp target update from(j) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} +#pragma omp target update to(j) device (argc + argc) +#pragma omp target update from(j) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}} +#pragma omp target update to(j) device (S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target update from(j) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}} +#pragma omp target update to(j) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + + return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}} +} diff --git a/test/OpenMP/target_update_from_messages.cpp b/test/OpenMP/target_update_from_messages.cpp new file mode 100644 index 0000000000000..6aff083b6a487 --- /dev/null +++ b/test/OpenMP/target_update_from_messages.cpp @@ -0,0 +1,176 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; // expected-note 4 {{mappable type cannot contain static members}} + static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}} +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; +struct S6 { + int ii; + int aa[30]; + float xx; + double *pp; +}; +struct S7 { + int i; + int a[50]; + float x; + S6 s6[5]; + double *p; + unsigned bfa : 4; +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +typedef int to; + +template <typename T, int I> // expected-note {{declared here}} +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + T i, t[20]; + T &j = i; + T *k = &j; + T x; + T y; + T from; + const T (&l)[5] = da; + T *m; + S7 s7; + +#pragma omp target update from // expected-error {{expected '(' after 'from'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(x) +#pragma omp target update from(t[:I]) +#pragma omp target update from(T) // expected-error {{'T' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update from(S2::S2s) +#pragma omp target update from(S2::S2sc) +#pragma omp target update from(from) +#pragma omp target update from(y x) // expected-error {{expected ',' or ')' in 'from' clause}} +#pragma omp target update from(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update from(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target update from(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(h) // expected-error {{threadprivate variables are not allowed in 'from' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(k), to(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}} +#pragma omp target update from(t), from(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}} +#pragma omp target update from(da) +#pragma omp target update from(da[:4]) + +#pragma omp target update from(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update from(x, c[:]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update from(x, (m+1)[2]) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update from(s7.i, s7.a[:3]) +#pragma omp target update from(s7.s6[1].aa[0:5]) +#pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update from(s7.p[:10]) +#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}} +#pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target data map(to: s7.i) + { +#pragma omp target update from(s7.x) + } + + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i, t[20]; + int &j = i; + int *k = &j; + int x; + int y; + int from; + const int (&l)[5] = da; + int *m; + S7 s7; + +#pragma omp target update from // expected-error {{expected '(' after 'from'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(x) +#pragma omp target update from(t[:i]) +#pragma omp target update from(S2::S2s) +#pragma omp target update from(S2::S2sc) +#pragma omp target update from(from) +#pragma omp target update from(y x) // expected-error {{expected ',' or ')' in 'from' clause}} +#pragma omp target update from(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target update from(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(h) // expected-error {{threadprivate variables are not allowed in 'from' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update from(k), to(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}} +#pragma omp target update from(t), from(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}} +#pragma omp target update from(da) +#pragma omp target update from(da[:4]) + +#pragma omp target update from(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update from(x, c[:]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update from(x, (m+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update from(s7.i, s7.a[:3]) +#pragma omp target update from(s7.s6[1].aa[0:5]) +#pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update from(s7.p[:10]) +#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}} +#pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target data map(to: s7.i) + { +#pragma omp target update from(s7.x) + } + + return tmain<int, 3>(argc)+tmain<to, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}} +} + diff --git a/test/OpenMP/target_update_if_messages.cpp b/test/OpenMP/target_update_if_messages.cpp new file mode 100644 index 0000000000000..97715e072422a --- /dev/null +++ b/test/OpenMP/target_update_if_messages.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + int n; +#pragma omp target update to(n) if // expected-error {{expected '(' after 'if'}} +#pragma omp target update from(n) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(n) if () // expected-error {{expected expression}} +#pragma omp target update from(n) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(n) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} +#pragma omp target update from(n) if (argc > 0 ? argv[1] : argv[2]) +#pragma omp target update to(n) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} +#pragma omp target update from(n) if (S) // expected-error {{'S' does not refer to a value}} +#pragma omp target update to(n) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update from(n) if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(n) if(argc) +#pragma omp target update from(n) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(n) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update from(n) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(n) if(target update : argc) +#pragma omp target update from(n) if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} +#pragma omp target update to(n) if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} +#pragma omp target update from(n) if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + return 0; +} + +int main(int argc, char **argv) { + int m; +#pragma omp target update to(m) if // expected-error {{expected '(' after 'if'}} +#pragma omp target update from(m) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(m) if () // expected-error {{expected expression}} +#pragma omp target update from(m) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(m) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} +#pragma omp target update from(m) if (argc > 0 ? argv[1] : argv[2]) +#pragma omp target update to(m) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}} +#pragma omp target update from(m) if (S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target update to(m) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update from(m) if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(m) if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update from(m) if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(m) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update from(m) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(m) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update from(m) if(target update : argc) +#pragma omp target update to(m) if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}} +#pragma omp target update from(m) if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}} +#pragma omp target update to(m) if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + return tmain(argc, argv); +} diff --git a/test/OpenMP/target_update_messages.cpp b/test/OpenMP/target_update_messages.cpp new file mode 100644 index 0000000000000..73f1eeca8efec --- /dev/null +++ b/test/OpenMP/target_update_messages.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // Aexpected-note {{declared here}} + +template <class T, class S> // Aexpected-note {{declared here}} +int tmain(T argc, S **argv) { + int n; + return 0; +} + +int main(int argc, char **argv) { + int m; + #pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update to(m) { // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(m) ( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(m) [ // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(m) ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(m) ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + + #pragma omp target update from(m) // OK + { + foo(); + } + return tmain(argc, argv); +} diff --git a/test/OpenMP/target_update_nowait_messages.cpp b/test/OpenMP/target_update_nowait_messages.cpp new file mode 100644 index 0000000000000..19bc58ea467e6 --- /dev/null +++ b/test/OpenMP/target_update_nowait_messages.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +int main(int argc, char **argv) { + int i; + + #pragma omp nowait target update to(i) // expected-error {{expected an OpenMP directive}} + #pragma omp target nowait update to(i) // expected-error {{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error {{unexpected OpenMP clause 'to' in directive '#pragma omp target'}} + {} + #pragma omp target update nowait() to(i) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + #pragma omp target update to(i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(i) nowait device (-10u) + #pragma omp target update to(i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} + #pragma omp target update to(i) nowait nowait // expected-error {{directive '#pragma omp target update' cannot contain more than one 'nowait' clause}} + #pragma omp target update nowait to(i) nowait // expected-error {{directive '#pragma omp target update' cannot contain more than one 'nowait' clause}} + return 0; +} diff --git a/test/OpenMP/target_update_to_messages.cpp b/test/OpenMP/target_update_to_messages.cpp new file mode 100644 index 0000000000000..641d0bd949a2c --- /dev/null +++ b/test/OpenMP/target_update_to_messages.cpp @@ -0,0 +1,175 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } + static float S2s; // expected-note 4 {{mappable type cannot contain static members}} + static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}} +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; +struct S6 { + int ii; + int aa[30]; + float xx; + double *pp; +}; +struct S7 { + int i; + int a[50]; + float x; + S6 s6[5]; + double *p; + unsigned bfa : 4; +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +typedef int from; + +template <typename T, int I> // expected-note {{declared here}} +T tmain(T argc) { + const T d = 5; + const T da[5] = { 0 }; + S4 e(4); + S5 g(5); + T *m; + T i, t[20]; + T &j = i; + T *k = &j; + T x; + T y; + T to; + const T (&l)[5] = da; + S7 s7; + +#pragma omp target update to // expected-error {{expected '(' after 'to'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(x) +#pragma omp target update to(t[:I]) +#pragma omp target update to(T) // expected-error {{'T' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update to(S2::S2s) +#pragma omp target update to(S2::S2sc) +#pragma omp target update to(to) +#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}} +#pragma omp target update to(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(k), from(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}} +#pragma omp target update to(t), to(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}} +#pragma omp target update to(da) +#pragma omp target update to(da[:4]) + +#pragma omp target update to(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update to(x, c[:]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update to(x, (m+1)[2]) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update to(s7.i, s7.a[:3]) +#pragma omp target update to(s7.s6[1].aa[0:5]) +#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update to(s7.p[:10]) +#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}} +#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target data map(to: s7.i) + { +#pragma omp target update to(s7.x) + } + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i, t[20]; + int &j = i; + int *k = &j; + int x; + int y; + int to; + const int (&l)[5] = da; + S7 s7; + int *m; + +#pragma omp target update to // expected-error {{expected '(' after 'to'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(x) +#pragma omp target update to(t[:i]) +#pragma omp target update to(S2::S2s) +#pragma omp target update to(S2::S2sc) +#pragma omp target update to(to) +#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}} +#pragma omp target update to(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} +#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} +#pragma omp target update to(k), from(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}} +#pragma omp target update to(t), to(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}} +#pragma omp target update to(da) +#pragma omp target update to(da[:4]) + +#pragma omp target update to(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update to(x, c[:]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update to(x, (m+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target update to(s7.i, s7.a[:3]) +#pragma omp target update to(s7.s6[1].aa[0:5]) +#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update to(s7.p[:10]) +#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}} +#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target data map(to: s7.i) + { +#pragma omp target update to(s7.x) + } + + return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}} +} + diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp index 723139b081832..37e5833dec5e5 100644 --- a/test/OpenMP/task_ast_print.cpp +++ b/test/OpenMP/task_ast_print.cpp @@ -8,6 +8,57 @@ void foo() {} +struct S1 { + S1(): a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp task private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp task private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp task private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp task private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp task private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp task private(this->a) private(this->a) + template <class T> struct S { operator T() { return T(); } @@ -98,4 +149,7 @@ int main(int argc, char **argv) { return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); } +extern template int S<int>::TS; +extern template long S<long>::TS; + #endif diff --git a/test/OpenMP/task_codegen.cpp b/test/OpenMP/task_codegen.cpp index 23dc014aad3b1..08c9ce33d8e8e 100644 --- a/test/OpenMP/task_codegen.cpp +++ b/test/OpenMP/task_codegen.cpp @@ -9,7 +9,7 @@ // CHECK-DAG: [[IDENT_T:%.+]] = type { i32, i32, i32, i32, i8* } // CHECK-DAG: [[STRUCT_SHAREDS:%.+]] = type { i8*, [2 x [[STRUCT_S:%.+]]]* } // CHECK-DAG: [[STRUCT_SHAREDS1:%.+]] = type { [2 x [[STRUCT_S:%.+]]]* } -// CHECK-DAG: [[KMP_TASK_T:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* } +// CHECK-DAG: [[KMP_TASK_T:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}} } // CHECK-DAG: [[KMP_DEPEND_INFO:%.+]] = type { i64, i64, i8 } struct S { int a; @@ -30,15 +30,16 @@ int main() { // CHECK: store i8* [[B]], i8** [[B_REF]] // CHECK: [[S_REF:%.+]] = getelementptr inbounds [[STRUCT_SHAREDS]], [[STRUCT_SHAREDS]]* [[CAPTURES]], i32 0, i32 1 // CHECK: store [2 x [[STRUCT_S]]]* [[S]], [2 x [[STRUCT_S]]]** [[S_REF]] -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 1, i64 32, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY1:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 33, i64 40, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY1:@.+]] to i32 (i32, i8*)*)) // CHECK: [[SHAREDS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR:%.+]], i32 0, i32 0 // CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_PTR]] // CHECK: [[BITCAST:%.+]] = bitcast [[STRUCT_SHAREDS]]* [[CAPTURES]] to i8* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[BITCAST]], i64 16, i32 8, i1 false) -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[PRIORITY_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 4 +// CHECK: [[PRIORITY:%.+]] = bitcast %union{{.+}}* [[PRIORITY_REF_PTR]] to i32* +// CHECK: store i32 {{.+}}, i32* [[PRIORITY]] // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) -#pragma omp task shared(a, b, s) +#pragma omp task shared(a, b, s) priority(b) { a = 15; b = a; @@ -46,13 +47,11 @@ int main() { } // CHECK: [[S_REF:%.+]] = getelementptr inbounds [[STRUCT_SHAREDS1]], [[STRUCT_SHAREDS1]]* [[CAPTURES:%.+]], i32 0, i32 0 // CHECK: store [2 x [[STRUCT_S]]]* [[S]], [2 x [[STRUCT_S]]]** [[S_REF]] -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 8, +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 8, // CHECK: [[SHAREDS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR:%.+]], i32 0, i32 0 // CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_PTR]] // CHECK: [[BITCAST:%.+]] = bitcast [[STRUCT_SHAREDS1]]* [[CAPTURES]] to i8* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[BITCAST]], i64 8, i32 8, i1 false) -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] // CHECK: [[DEP:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES:%.*]], i64 0, i64 0 // CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 0 // CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64* [[T0]] @@ -100,17 +99,13 @@ int main() { a = 15; s[1].a = 10; } -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*)) -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*)) // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) #pragma omp task untied { a = 1; } -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 32, i64 1, -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1, // CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i64 0, i64 0 // CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 0 // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 @@ -120,15 +115,15 @@ int main() { // CHECK: store i64 4, i64* // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 // CHECK: store i8 3, i8* +// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]] +// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64 // CHECK: [[IDX1:%.+]] = mul nsw i64 4, [[A_VAL]] // CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 [[IDX2]] // CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]] // CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64 -// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 [[IDX2]] // CHECK: [[IDX1:%.+]] = mul nsw i64 9, [[A_VAL]] // CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] -// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]] -// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64 // CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]] // CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1 // CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64 @@ -149,9 +144,7 @@ int main() { { a = 1; } -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 32, i64 1, -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 40, i64 1, // CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 0 // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 // CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64* @@ -173,12 +166,12 @@ int main() { // CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 3 // CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}}, // CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64 +// CHECK: [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1 +// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}}, +// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64 // CHECK: [[SUB:%.+]] = add nsw i64 -1, [[NEW_A_VAL_I64]] // CHECK: [[IDX1:%.+]] = mul nsw i64 [[SUB]], [[A_VAL]] // CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] -// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}}, -// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64 -// CHECK: [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1 // CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]] // CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1 // CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64 @@ -199,17 +192,13 @@ int main() { { a = 2; } -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*)) -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*)) // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) #pragma omp task final(true) { a = 2; } -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY4:@.+]] to i32 (i32, i8*)*)) -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.*}}, i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY4:@.+]] to i32 (i32, i8*)*)) // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) const bool flag = false; #pragma omp task final(flag) @@ -220,9 +209,7 @@ int main() { // CHECK: [[CMP:%.+]] = icmp ne i8 [[B_VAL]], 0 // CHECK: [[FINAL:%.+]] = select i1 [[CMP]], i32 2, i32 0 // CHECK: [[FLAGS:%.+]] = or i32 [[FINAL]], 1 -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 [[FLAGS]], i64 32, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY5:@.+]] to i32 (i32, i8*)*)) -// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3 -// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]] +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 [[FLAGS]], i64 40, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY5:@.+]] to i32 (i32, i8*)*)) // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) int c __attribute__((aligned(128))); #pragma omp task final(b) shared(c) @@ -230,6 +217,17 @@ int main() { a = 4; c = 5; } +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY6:@.+]] to i32 (i32, i8*)*)) +// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) +#pragma omp task untied + { + S s1; +#pragma omp task + a = 4; +#pragma omp taskyield + s1 = S(); +#pragma omp taskwait + } return a; } // CHECK: define internal i32 [[TASK_ENTRY1]](i32, [[KMP_TASK_T]]{{.*}}* noalias) @@ -240,16 +238,41 @@ int main() { // CHECK: store i32 10, i32* %{{.+}} // CHECK: define internal i32 [[TASK_ENTRY2]](i32, [[KMP_TASK_T]]{{.*}}* noalias) -// CHECK: store i32 1, i32* [[A_PTR:@.+]] +// CHECK: store i32 1, i32* [[A_PTR]] // CHECK: define internal i32 [[TASK_ENTRY3]](i32, [[KMP_TASK_T]]{{.*}}* noalias) -// CHECK: store i32 2, i32* [[A_PTR:@.+]] +// CHECK: store i32 2, i32* [[A_PTR]] // CHECK: define internal i32 [[TASK_ENTRY4]](i32, [[KMP_TASK_T]]{{.*}}* noalias) -// CHECK: store i32 3, i32* [[A_PTR:@.+]] +// CHECK: store i32 3, i32* [[A_PTR]] // CHECK: define internal i32 [[TASK_ENTRY5]](i32, [[KMP_TASK_T]]{{.*}}* noalias) -// CHECK: store i32 4, i32* [[A_PTR:@.+]] +// CHECK: store i32 4, i32* [[A_PTR]] // CHECK: store i32 5, i32* [[C_PTR:%.+]], align 128 + +// CHECK: define internal i32 +// CHECK: store i32 4, i32* [[A_PTR]] + +// CHECK: define internal i32 [[TASK_ENTRY6]](i32, [[KMP_TASK_T]]{{.*}}* noalias) +// CHECK: switch i32 %{{.+}}, label +// CHECK: load i32*, i32** % +// CHECK: store i32 1, i32* % +// CHECK: call i32 @__kmpc_omp_task(% + +// CHECK: call i8* @__kmpc_omp_task_alloc( +// CHECK: call i32 @__kmpc_omp_task(% +// CHECK: load i32*, i32** % +// CHECK: store i32 2, i32* % +// CHECK: call i32 @__kmpc_omp_task(% + +// CHECK: call i32 @__kmpc_omp_taskyield(% +// CHECK: load i32*, i32** % +// CHECK: store i32 3, i32* % +// CHECK: call i32 @__kmpc_omp_task(% + +// CHECK: call i32 @__kmpc_omp_taskwait(% +// CHECK: load i32*, i32** % +// CHECK: store i32 4, i32* % +// CHECK: call i32 @__kmpc_omp_task(% #endif diff --git a/test/OpenMP/task_firstprivate_codegen.cpp b/test/OpenMP/task_firstprivate_codegen.cpp index e2244140d1e14..0d8e1c4afe4e5 100644 --- a/test/OpenMP/task_firstprivate_codegen.cpp +++ b/test/OpenMP/task_firstprivate_codegen.cpp @@ -24,10 +24,10 @@ struct S { volatile double g; -// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* } +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}} } // CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } // CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}} // CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } // CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } @@ -58,18 +58,16 @@ int main() { // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 // LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 -// LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_ADDR_REF]] -// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_REF]] +// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]] // LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 -// LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR_REF]] -// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] +// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]] // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) @@ -104,18 +102,16 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 // BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 - // BLOCKS: [[G_REF:%.+]] = load double*, double** [[G_ADDR_REF]] - // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_REF]] + // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]] // BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 - // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR_REF]] - // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]] // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // BLOCKS: ret @@ -180,20 +176,22 @@ int main() { // CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], // CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], -// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[T_VAR:%.+]] = load i32, i32* [[T_VAR_ADDR]], +// CHECK: store i32 [[T_VAR]], i32* [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 // CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]], -// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 // CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]], -// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 -// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 5 +// CHECK: [[SIVAR_VAL:%.+]] = load i32, i32* [[SIVAR]], +// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_REF]], // Allocate task. // Returns struct kmp_task_t { // [[KMP_TASK_T]] task_data; // [[KMP_TASK_MAIN_TY]] privates; // }; -// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 72, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 80, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* // Fill kmp_task_t->shareds by copying from original capture argument. @@ -211,7 +209,7 @@ int main() { // Constructors for s_arr and var. // s_arr; // CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 // CHECK: load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[S_ARR_ADDR_REF]], // CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]], // CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 @@ -221,14 +219,13 @@ int main() { // var; // CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 -// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4 // CHECK: [[VAR_REF:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[VAR_ADDR_REF]], // CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]], [[S_DOUBLE_TY]]* {{.*}}[[VAR_REF]], // t_var; // CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 -// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1 -// CHECK: [[T_VAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[T_VAR_ADDR_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1 // CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_REF]], // CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], @@ -239,14 +236,14 @@ int main() { // sivar; // CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4 -// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4 -// CHECK: [[SIVAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[SIVAR_ADDR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 5 // CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_REF]], // CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]], // Provide pointer to destructor function, which will destroy private variables at the end of the task. // CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 -// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]], +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], // Start task. // CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]]) @@ -347,7 +344,7 @@ int main() { // [[KMP_TASK_T_TY]] task_data; // [[KMP_TASK_TMAIN_TY]] privates; // }; -// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* // Fill kmp_task_t->shareds by copying from original capture argument. @@ -391,7 +388,8 @@ int main() { // Provide pointer to destructor function, which will destroy private variables at the end of the task. // CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 -// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]], +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], // Start task. // CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]]) @@ -422,11 +420,11 @@ int main() { // CHECK: ret void // CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) - -// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, -// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, -// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, -// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp index ef5f3856430a3..11d8c5789879a 100644 --- a/test/OpenMP/task_firstprivate_messages.cpp +++ b/test/OpenMP/task_firstprivate_messages.cpp @@ -7,6 +7,17 @@ bool foobool(int argc) { return argc; } +template <typename T> +struct S { + T b; + S(T a, T c) { +#pragma omp task default(none) firstprivate(a, b) + a = b = c; // expected-error {{variable 'c' must have explicitly specified data sharing attributes}} + } +}; + +S<int> s(3, 4); // expected-note {{in instantiation of member function 'S<int>::S' requested here}} + struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/task_if_codegen.cpp b/test/OpenMP/task_if_codegen.cpp index 5992be02a84a9..4226dceda86e9 100644 --- a/test/OpenMP/task_if_codegen.cpp +++ b/test/OpenMP/task_if_codegen.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // REQUIRES: x86-registered-target // expected-no-diagnostics #ifndef HEADER @@ -63,11 +63,11 @@ int tmain(T Arg) { // CHECK-LABEL: @main int main() { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN7:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN7:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) #pragma omp task if (true) fn7(); -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN8:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN8:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: call void @__kmpc_omp_task_begin_if0(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]], i8* [[ORIG_TASK_PTR]]) // CHECK: call i32 [[CAP_FN8]](i32 [[GTID]], %{{.+}}* [[TASK_PTR]]) @@ -75,7 +75,7 @@ int main() { #pragma omp task if (false) fn8(); -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN9:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN9:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] @@ -89,7 +89,7 @@ int main() { // CHECK: [[OMP_END]] #pragma omp task if (Arg) fn9(); -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN10:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN10:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] @@ -126,7 +126,7 @@ int main() { // CHECK-LABEL: define {{.+}} @{{.+}}tmain // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN1:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN1:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) // CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc( @@ -135,7 +135,7 @@ int main() { // CHECK: call i32 [[CAP_FN2:@.+]](i32 [[GTID]], %{{.+}}* [[TASK_PTR]]) // CHECK: call void @__kmpc_omp_task_complete_if0(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]], i8* [[ORIG_TASK_PTR]]) -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN3:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN3:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] @@ -148,7 +148,7 @@ int main() { // CHECK: br label %[[OMP_END]] // CHECK: [[OMP_END]] -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN4:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN4:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] @@ -162,7 +162,7 @@ int main() { // CHECK: br label %[[OMP_END]] // CHECK: [[OMP_END]] -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN5:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN5:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] @@ -176,7 +176,7 @@ int main() { // CHECK: br label %[[OMP_END]] // CHECK: [[OMP_END]] -// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN6:[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN6:[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp index 64bf8a40f025d..f42a37ae1daad 100644 --- a/test/OpenMP/task_messages.cpp +++ b/test/OpenMP/task_messages.cpp @@ -60,11 +60,10 @@ int foo() { // expected-error@+1 2 {{calling a private constructor of class 'S'}} #pragma omp parallel shared(a, b) ++a, ++b; -// expected-note@+1 3 {{defined as reduction}} +// expected-note@+1 2 {{defined as reduction}} #pragma omp parallel reduction(+ : r) -// expected-error@+1 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}} +// expected-error@+1 2 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}} #pragma omp task firstprivate(r) - // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}} ++r; // expected-note@+1 2 {{defined as reduction}} #pragma omp parallel reduction(+ : r) @@ -77,12 +76,11 @@ int foo() { // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}} ++r; #pragma omp parallel -// expected-note@+1 3 {{defined as reduction}} +// expected-note@+1 2 {{defined as reduction}} #pragma omp for reduction(+ : r) for (int i = 0; i < 10; ++i) -// expected-error@+1 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}} +// expected-error@+1 2 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}} #pragma omp task firstprivate(r) - // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}} ++r; #pragma omp parallel // expected-note@+1 2 {{defined as reduction}} diff --git a/test/OpenMP/task_private_codegen.cpp b/test/OpenMP/task_private_codegen.cpp index 1455fd11a91d9..97155a73f1bd0 100644 --- a/test/OpenMP/task_private_codegen.cpp +++ b/test/OpenMP/task_private_codegen.cpp @@ -24,7 +24,7 @@ struct S { volatile double g; -// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* } +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}} } // CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } // CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 } // CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] @@ -56,10 +56,8 @@ int main() { // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 -// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 -// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // LAMBDA: ret #pragma omp task private(g, sivar) @@ -94,10 +92,8 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 - // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 - // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // BLOCKS: ret #pragma omp task private(g, sivar) @@ -162,7 +158,7 @@ int main() { // [[KMP_TASK_T_TY]] task_data; // [[KMP_TASK_MAIN_TY]] privates; // }; -// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* // CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 @@ -186,7 +182,8 @@ int main() { // Provide pointer to destructor function, which will destroy private variables at the end of the task. // CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 -// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]], +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], // Start task. // CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]]) @@ -275,7 +272,7 @@ int main() { // [[KMP_TASK_T_TY]] task_data; // [[KMP_TASK_TMAIN_TY]] privates; // }; -// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* // CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 @@ -299,7 +296,8 @@ int main() { // Provide pointer to destructor function, which will destroy private variables at the end of the task. // CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 -// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]], +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], // Start task. // CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]]) @@ -331,10 +329,11 @@ int main() { // CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) -// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, -// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, -// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, -// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) diff --git a/test/OpenMP/taskgroup_codegen.cpp b/test/OpenMP/taskgroup_codegen.cpp index d1bc2aafc7b4b..0f6e81b3ba0b7 100644 --- a/test/OpenMP/taskgroup_codegen.cpp +++ b/test/OpenMP/taskgroup_codegen.cpp @@ -32,6 +32,7 @@ int main() { foo(); // CHECK-NOT: call {{.*}}void @__kmpc_taskgroup // CHECK-NOT: call {{.*}}void @__kmpc_end_taskgroup +// CHECK: ret return a; } diff --git a/test/OpenMP/taskloop_codegen.cpp b/test/OpenMP/taskloop_codegen.cpp new file mode 100644 index 0000000000000..e585fcec10d5d --- /dev/null +++ b/test/OpenMP/taskloop_codegen.cpp @@ -0,0 +1,192 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +#ifndef HEADER +#define HEADER + +// CHECK-LABEL: @main +int main(int argc, char **argv) { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]]) +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 9, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 0, i64 0, i8* null) +#pragma omp taskloop priority(argc) + for (int i = 0; i < 10; ++i) + ; +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 9, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[GRAINSIZE:%.+]] = zext i32 %{{.+}} to i64 +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 1, i64 [[GRAINSIZE]], i8* null) +#pragma omp taskloop nogroup grainsize(argc) + for (int i = 0; i < 10; ++i) + ; +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0 +// CHECK: [[IF_INT:%.+]] = sext i1 [[IF]] to i32 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 %{{.+}}, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 4, i8* null) + int i; +#pragma omp taskloop if(argc) shared(argc, argv) collapse(2) num_tasks(4) + for (i = 0; i < argc; ++i) + for (int j = argc; j < argv[argc][argc]; ++j) + ; +} + +// CHECK: define internal i32 [[TASK1]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32 +// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]], +// CHECK: br label +// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]], +// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64 +// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], +// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]] +// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}} +// CHECK: load i32, i32* % +// CHECK: store i32 % +// CHECK: load i32, i32* % +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: br label % +// CHECK: ret i32 0 + +// CHECK: define internal i32 [[TASK2]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32 +// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]], +// CHECK: br label +// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]], +// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64 +// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], +// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]] +// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}} +// CHECK: load i32, i32* % +// CHECK: store i32 % +// CHECK: load i32, i32* % +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: br label % +// CHECK: ret i32 0 + +// CHECK: define internal i32 [[TASK3]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: store i64 [[LB_VAL]], i64* [[CNT:%.+]], +// CHECK: br label +// CHECK: ret i32 0 + +// CHECK-LABEL: @_ZN1SC2Ei +struct S { + int a; + S(int c) { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]]) +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 %{{.+}}, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64 +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 [[NUM_TASKS]], i8* null) +#pragma omp taskloop shared(c) num_tasks(a) + for (a = 0; a < c; ++a) + ; + } +} s(1); + +// CHECK: define internal i32 [[TASK4]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32 +// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]], +// CHECK: br label +// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]], +// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64 +// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], +// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]] +// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}} +// CHECK: load i32, i32* % +// CHECK: store i32 % +// CHECK: load i32, i32* % +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: br label % +// CHECK: ret i32 0 + +#endif diff --git a/test/OpenMP/taskloop_collapse_messages.cpp b/test/OpenMP/taskloop_collapse_messages.cpp index f33da11f5ed96..1a5620e77db0a 100644 --- a/test/OpenMP/taskloop_collapse_messages.cpp +++ b/test/OpenMP/taskloop_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp taskloop', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp taskloop collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} #pragma omp taskloop collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} - #pragma omp taskloop collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp taskloop collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp taskloop collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp taskloop collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp taskloop' must be a for loop}} diff --git a/test/OpenMP/taskloop_firstprivate_codegen.cpp b/test/OpenMP/taskloop_firstprivate_codegen.cpp new file mode 100644 index 0000000000000..822a5c687dc76 --- /dev/null +++ b/test/OpenMP/taskloop_firstprivate_codegen.cpp @@ -0,0 +1,511 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +// It doesn't pass on win32. +// REQUIRES: shell +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S(const S &s, T t = T()) : f(s.f + t) {} + operator T() { return T(); } + ~S() {} +}; + +volatile double g; + +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 } +// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } +// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}} +// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] } +// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] } +template <typename T> +T tmain() { + S<T> ttt; + S<T> test(ttt); + T t_var __attribute__((aligned(128))) = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp taskloop firstprivate(t_var, vec, s_arr, s_arr, var, var) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global double + // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 +// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]] +// LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] + +// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]] +// LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + +// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) +// LAMBDA: ret +#pragma omp taskloop firstprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] + // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + + // LAMBDA: store double* %{{.+}}, double** %{{.+}}, + // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: call void [[INNER_LAMBDA]](% + // LAMBDA: ret + [&]() { + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global double + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 + // BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 + // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]] + // BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] + + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]] + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) + // BLOCKS: ret +#pragma omp taskloop firstprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // BLOCKS: define {{.+}} void {{@.+}}(i8* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store double 2.0{{.+}}, double* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: ret + + // BLOCKS: store double* %{{.+}}, double** %{{.+}}, + // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}}, + // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + ^{ + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#else + S<double> ttt; + S<double> test(ttt); + int t_var = 0; + int vec[] = {1, 2}; + S<double> s_arr[] = {1, 2}; + S<double> var(3); +#pragma omp taskloop firstprivate(var, t_var, s_arr, vec, s_arr, var, sivar) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + sivar = 33; + } + return tmain<int>(); +#endif +} + +// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0, +// CHECK: define i{{[0-9]+}} @main() +// CHECK: alloca [[S_DOUBLE_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]], + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]], +// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 5 +// CHECK: [[SIVAR_VAL:%.+]] = load i32, i32* [[SIVAR]], +// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T]] task_data; +// [[KMP_TASK_MAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// Also copy address of private copy to the corresponding shareds reference. +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_MAIN_TY]]* + +// Constructors for s_arr and var. +// s_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 +// CHECK: load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[S_ARR_ADDR_REF]], +// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]], +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[VAR_REF:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[VAR_ADDR_REF]], +// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]], [[S_DOUBLE_TY]]* {{.*}}[[VAR_REF]], + +// t_var; +// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_ADDR_REF]], +// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], + +// vec; +// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( + +// sivar; +// CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 5 +// CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_ADDR_REF]], +// CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]], + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) + +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, +// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4 +// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}}, +// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias) + +// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, +// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, +// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], + +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) + +// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] +// CHECK-DAG: [[PRIV_SIVAR]] + +// CHECK: ret + +// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2 +// CHECK: br i1 % + +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i32 1 +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: alloca [[S_INT_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128 +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]], + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_TMAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_TMAIN_TY]]* + +// t_var; +// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[T_VAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[T_VAR_ADDR_REF]], +// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_REF]], align 128 +// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], align 128 + +// vec; +// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]], +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]], + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*)) + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]** +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]], +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}}, +// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] + +// CHECK: ret + +// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2 +// CHECK: br i1 % + +// CHECK: phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i32 1 +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3 +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +#endif +#else +// ARRAY-LABEL: array_func +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &) {} + ~St() {} +}; + +void array_func(int n, float a[n], St s[2]) { +// ARRAY: call i8* @__kmpc_omp_task_alloc( +// ARRAY: call void @__kmpc_taskloop( +// ARRAY: store float** %{{.+}}, float*** %{{.+}}, +// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}}, +#pragma omp taskloop firstprivate(a, s) + for (int i = 0; i < 10; ++i) + ; +} +#endif + diff --git a/test/OpenMP/taskloop_firstprivate_messages.cpp b/test/OpenMP/taskloop_firstprivate_messages.cpp index e2e87e4697a5d..fe22311f650cd 100644 --- a/test/OpenMP/taskloop_firstprivate_messages.cpp +++ b/test/OpenMP/taskloop_firstprivate_messages.cpp @@ -295,9 +295,9 @@ int main(int argc, char **argv) { #pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}} for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}} foo(); -#pragma omp parallel reduction(+ : i) -#pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}} - for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}} +#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}} +#pragma omp taskloop firstprivate(i) //expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}} + for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}} foo(); #pragma omp parallel #pragma omp taskloop firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} diff --git a/test/OpenMP/taskloop_lastprivate_codegen.cpp b/test/OpenMP/taskloop_lastprivate_codegen.cpp new file mode 100644 index 0000000000000..8414b6f963f98 --- /dev/null +++ b/test/OpenMP/taskloop_lastprivate_codegen.cpp @@ -0,0 +1,519 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +// It doesn't pass on win32. +// REQUIRES: shell +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S(const S &s, T t = T()) : f(s.f + t) {} + operator T() { return T(); } + ~S() {} +}; + +volatile double g; + +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 } +// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } +// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* } +// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] } +// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] } +template <typename T> +T tmain() { + S<T> ttt; + S<T> test; + T t_var __attribute__((aligned(128))) = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp taskloop lastprivate(t_var, vec, s_arr, s_arr, var, var) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global double + // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + +// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) +// LAMBDA: ret +#pragma omp taskloop lastprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] + // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + + // LAMBDA: store double* %{{.+}}, double** %{{.+}}, + // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: call void [[INNER_LAMBDA]](% + // LAMBDA: icmp ne i32 %{{.+}}, 0 + // LAMBDA: br i1 + // LAMBDA: load double, double* % + // LAMBDA: store volatile double % + // LAMBDA: load i32, i32* % + // LAMBDA: store i32 % + // LAMBDA: ret + [&]() { + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global double + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) + // BLOCKS: ret +#pragma omp taskloop lastprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // BLOCKS: define {{.+}} void {{@.+}}(i8* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store double 2.0{{.+}}, double* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: ret + + // BLOCKS: store double* %{{.+}}, double** %{{.+}}, + // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}}, + // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + // BLOCKS: icmp ne i32 %{{.+}}, 0 + // BLOCKS: br i1 + // BLOCKS: load double, double* % + // BLOCKS: store volatile double % + // BLOCKS: load i32, i32* % + // BLOCKS: store i32 % + ^{ + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#else + S<double> ttt; + S<double> test; + int t_var = 0; + int vec[] = {1, 2}; + S<double> s_arr[] = {1, 2}; + S<double> var(3); +#pragma omp taskloop lastprivate(var, t_var, s_arr, vec, s_arr, var, sivar) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + sivar = 33; + } + return tmain<int>(); +#endif +} + +// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0, +// CHECK: define i{{[0-9]+}} @main() +// CHECK: alloca [[S_DOUBLE_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]]) + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T]] task_data; +// [[KMP_TASK_MAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// Also copy address of private copy to the corresponding shareds reference. +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + +// Constructors for s_arr and var. +// s_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]]) +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) + +// t_var; +// vec; +// sivar; + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) + +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, +// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4 +// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}}, +// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias) + +// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, +// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, +// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], + +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) + +// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] +// CHECK-DAG: [[PRIV_SIVAR]] + +// CHECK: icmp ne i32 %{{.+}}, 0 +// CHECK-NEXT: br i1 +// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8* +// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* % +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK-NEXT: br i1 +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: br label +// CHECK: ret + +// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: alloca [[S_INT_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128 +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_TMAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + +// t_var; +// vec; + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]]) +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*)) + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]** +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]], +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}}, +// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] + +// CHECK: icmp ne i32 %{{.+}}, 0 +// CHECK-NEXT: br i1 +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* % +// CHECK: phi [[S_INT_TY]]* +// CHECK: phi [[S_INT_TY]]* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK-NEXT: br i1 +// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8* +// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: br label +// CHECK: ret + +// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3 +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +#endif +#else +// ARRAY-LABEL: array_func +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &) {} + ~St() {} +}; + +void array_func(int n, float a[n], St s[2]) { +// ARRAY: call i8* @__kmpc_omp_task_alloc( +// ARRAY: call void @__kmpc_taskloop( +// ARRAY: store float** %{{.+}}, float*** %{{.+}}, +// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}}, +// ARRAY: icmp ne i32 %{{.+}}, 0 +// ARRAY: store float* %{{.+}}, float** %{{.+}}, +// ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}}, +#pragma omp taskloop lastprivate(a, s) + for (int i = 0; i < 10; ++i) + ; +} +#endif + diff --git a/test/OpenMP/taskloop_loop_messages.cpp b/test/OpenMP/taskloop_loop_messages.cpp index 02518e572f3af..291cbdbe718c9 100644 --- a/test/OpenMP/taskloop_loop_messages.cpp +++ b/test/OpenMP/taskloop_loop_messages.cpp @@ -427,12 +427,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -483,7 +483,7 @@ int test_with_random_access_iterator() { #pragma omp taskloop for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp taskloop diff --git a/test/OpenMP/taskloop_private_codegen.cpp b/test/OpenMP/taskloop_private_codegen.cpp new file mode 100644 index 0000000000000..38b20c579393b --- /dev/null +++ b/test/OpenMP/taskloop_private_codegen.cpp @@ -0,0 +1,420 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +// It doesn't pass on win32. Investigating. +// REQUIRES: shell + +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + operator T() { return T(); } + ~S() {} +}; + +volatile double g; + +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 } +// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 } +// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] +// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i8 } +// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] } +// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] } +template <typename T> +T tmain() { + S<T> test; + T t_var __attribute__((aligned(128))) = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp taskloop private(t_var, vec, s_arr, s_arr, var, var) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global double + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) +// LAMBDA: ret +#pragma omp taskloop private(g, sivar) + for (int i = 0; i < 10; ++i) { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] + // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SIVAR_REF]] + + // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 2; + // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: call void [[INNER_LAMBDA]](% + // LAMBDA: ret + [&]() { + g = 2; + sivar = 3; + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global double + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) + // BLOCKS: ret +#pragma omp taskloop private(g, sivar) + for (int i = 0; i < 10; ++i) { + // BLOCKS: define {{.+}} void {{@.+}}(i8* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store double 2.0{{.+}}, double* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: ret + + // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 3; + // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 3, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + ^{ + g = 2; + sivar = 4; + }(); + } + }(); + return 0; +#else + S<double> test; + int t_var = 0; + int vec[] = {1, 2}; + S<double> s_arr[] = {1, 2}; + S<double> var(3); +#pragma omp taskloop private(var, t_var, s_arr, vec, s_arr, var, sivar) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + sivar = 8; + } +#pragma omp task + g+=1; + return tmain<int>(); +#endif +} + +// CHECK: define i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]]) + +// Do not store original variables in capture struct. +// CHECK-NOT: getelementptr inbounds [[CAP_MAIN_TY]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_MAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* + +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// Also copy address of private copy to the corresponding shareds reference. +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%.+]]) +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF:%.+]]) + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) +// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* + +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, +// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias) + +// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, +// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, +// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] +// CHECK_DAG: [[PRIV_SIVAR]] + +// CHECK: ret + +// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) + +// Do not store original variables in capture struct. +// CHECK-NOT: getelementptr inbounds [[CAP_TMAIN_TY]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_TMAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* + +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%.+]]) +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF:%.+]]) + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*)) + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]** +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]], +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}}, +// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) + +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] + +// CHECK: ret + +// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3 +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +#endif +#else +// ARRAY-LABEL: array_func +struct St { + int a, b; + St() : a(0), b(0) {} + St &operator=(const St &) { return *this; }; + ~St() {} +}; + +void array_func(int n, float a[n], St s[2]) { +// ARRAY: call i8* @__kmpc_omp_task_alloc( +// ARRAY: call void @__kmpc_taskloop( +// ARRAY: store float** %{{.+}}, float*** %{{.+}}, +// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}}, +#pragma omp taskloop private(a, s) + for (int i = 0; i < 10; ++i) + ; +} +#endif + diff --git a/test/OpenMP/taskloop_private_messages.cpp b/test/OpenMP/taskloop_private_messages.cpp index 3d00d3f252b38..367d59da69597 100644 --- a/test/OpenMP/taskloop_private_messages.cpp +++ b/test/OpenMP/taskloop_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp taskloop private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp taskloop private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp taskloop private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp taskloop private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp taskloop private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp taskloop private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -126,6 +174,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp taskloop private // expected-error {{expected '(' after 'private'}} @@ -190,6 +240,8 @@ int main(int argc, char **argv) { for(int k = 0; k < argc; ++k) si = k + 1; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/taskloop_simd_aligned_messages.cpp b/test/OpenMP/taskloop_simd_aligned_messages.cpp index b62af044c60f1..b45f44fe1cf8b 100644 --- a/test/OpenMP/taskloop_simd_aligned_messages.cpp +++ b/test/OpenMP/taskloop_simd_aligned_messages.cpp @@ -196,6 +196,7 @@ int main(int argc, char **argv) { #pragma omp taskloop simd aligned(h) for (int k = 0; k < argc; ++k) ++k; int *pargc = &argc; + // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}} foomain<int*,char>(pargc,argv); return 0; } diff --git a/test/OpenMP/taskloop_simd_codegen.cpp b/test/OpenMP/taskloop_simd_codegen.cpp new file mode 100644 index 0000000000000..dc60009ff2bd1 --- /dev/null +++ b/test/OpenMP/taskloop_simd_codegen.cpp @@ -0,0 +1,203 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +#ifndef HEADER +#define HEADER + +// CHECK-LABEL: @main +int main(int argc, char **argv) { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]]) +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 9, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 0, i64 0, i8* null) +#pragma omp taskloop simd priority(argc) + for (int i = 0; i < 10; ++i) + ; +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 9, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[GRAINSIZE:%.+]] = zext i32 %{{.+}} to i64 +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 1, i64 [[GRAINSIZE]], i8* null) +#pragma omp taskloop simd nogroup grainsize(argc) simdlen(4) + for (int i = 0; i < 10; ++i) + ; +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0 +// CHECK: [[IF_INT:%.+]] = sext i1 [[IF]] to i32 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 %{{.+}}, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 4, i8* null) + int i; +#pragma omp taskloop simd if(argc) shared(argc, argv) collapse(2) num_tasks(4) safelen(32) + for (i = 0; i < argc; ++i) + for (int j = argc; j < argv[argc][argc]; ++j) + ; +} + +// CHECK: define internal i32 [[TASK1]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32 +// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]], +// CHECK: br label +// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP1:!.+]] +// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64 +// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]] +// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]] +// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}} +// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]] +// CHECK: store i32 %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]] +// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]] +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]] +// CHECK: br label %{{.*}}!llvm.loop [[LOOP1]] +// CHECK: ret i32 0 + +// CHECK: define internal i32 [[TASK2]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32 +// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]], +// CHECK: br label +// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP2:!.+]] +// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64 +// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]] +// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]] +// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}} +// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]] +// CHECK: store i32 %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]] +// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]] +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]] +// CHECK: br label %{{.*}}!llvm.loop [[LOOP2]] +// CHECK: ret i32 0 + +// CHECK: define internal i32 [[TASK3]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: store i64 [[LB_VAL]], i64* [[CNT:%.+]], +// CHECK: br label +// CHECK-NOT: !llvm.mem.parallel_loop_access +// CHECK: br label %{{.*}}!llvm.loop +// CHECK: ret i32 0 + +// CHECK-LABEL: @_ZN1SC2Ei +struct S { + int a; + S(int c) { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]]) +// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*)) +// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* +// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0 +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5 +// CHECK: store i64 0, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6 +// CHECK: store i64 %{{.+}}, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7 +// CHECK: store i64 1, i64* [[ST]], +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64 +// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 [[NUM_TASKS]], i8* null) +#pragma omp taskloop simd shared(c) num_tasks(a) simdlen(64) safelen(8) + for (a = 0; a < c; ++a) + ; + } +} s(1); + +// CHECK: define internal i32 [[TASK4]]( +// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5 +// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]], +// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6 +// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]], +// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7 +// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]], +// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]], +// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]], +// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]], +// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]], +// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]], +// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], +// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32 +// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]], +// CHECK: br label +// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]], +// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64 +// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], +// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]] +// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}} +// CHECK: load i32, i32* % +// CHECK-NOT: !llvm.mem.parallel_loop_access +// CHECK: store i32 % +// CHECK-NOT: !llvm.mem.parallel_loop_access +// CHECK: load i32, i32* % +// CHECK-NOT: !llvm.mem.parallel_loop_access +// CHECK: add nsw i32 %{{.+}}, 1 +// CHECK: store i32 %{{.+}}, i32* % +// CHECK-NOT: !llvm.mem.parallel_loop_access +// CHECK: br label %{{.*}}!llvm.loop +// CHECK: ret i32 0 + +// CHECK: !{!"llvm.loop.vectorize.enable", i1 true} +// CHECK: !{!"llvm.loop.vectorize.width", i32 4} +// CHECK: !{!"llvm.loop.vectorize.width", i32 32} +// CHECK: !{!"llvm.loop.vectorize.width", i32 64} + +#endif diff --git a/test/OpenMP/taskloop_simd_collapse_messages.cpp b/test/OpenMP/taskloop_simd_collapse_messages.cpp index d178c0834d626..e4ce0c1df41ab 100644 --- a/test/OpenMP/taskloop_simd_collapse_messages.cpp +++ b/test/OpenMP/taskloop_simd_collapse_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp taskloop simd', but found only 1}} - // expected-error@+3 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}} - // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}} + // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp taskloop simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd collapse (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd collapse (1) @@ -59,16 +71,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} #pragma omp taskloop simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} expected-note {{as specified in 'collapse' clause}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} - #pragma omp taskloop simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp taskloop simd collapse (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}} // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp taskloop simd collapse (foobool(argc)), collapse (true), collapse (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp taskloop simd collapse (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp taskloop simd' must be a for loop}} diff --git a/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp b/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp new file mode 100644 index 0000000000000..0b87ddd9acb12 --- /dev/null +++ b/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp @@ -0,0 +1,511 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +// It doesn't pass on win32. +// REQUIRES: shell +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S(const S &s, T t = T()) : f(s.f + t) {} + operator T() { return T(); } + ~S() {} +}; + +volatile double g; + +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 } +// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } +// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}} +// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] } +// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] } +template <typename T> +T tmain() { + S<T> ttt; + S<T> test(ttt); + T t_var __attribute__((aligned(128))) = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp taskloop simd firstprivate(t_var, vec, s_arr, s_arr, var, var) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global double + // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 +// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]] +// LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] + +// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]] +// LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + +// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) +// LAMBDA: ret +#pragma omp taskloop simd firstprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] + // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + + // LAMBDA: store double* %{{.+}}, double** %{{.+}}, + // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: call void [[INNER_LAMBDA]](% + // LAMBDA: ret + [&]() { + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global double + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 + // BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 + // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]] + // BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] + + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]] + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) + // BLOCKS: ret +#pragma omp taskloop simd firstprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // BLOCKS: define {{.+}} void {{@.+}}(i8* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store double 2.0{{.+}}, double* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: ret + + // BLOCKS: store double* %{{.+}}, double** %{{.+}}, + // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}}, + // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + ^{ + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#else + S<double> ttt; + S<double> test(ttt); + int t_var = 0; + int vec[] = {1, 2}; + S<double> s_arr[] = {1, 2}; + S<double> var(3); +#pragma omp taskloop simd firstprivate(var, t_var, s_arr, vec, s_arr, var, sivar) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + sivar = 33; + } + return tmain<int>(); +#endif +} + +// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0, +// CHECK: define i{{[0-9]+}} @main() +// CHECK: alloca [[S_DOUBLE_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]], + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]], +// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 5 +// CHECK: [[SIVAR_VAL:%.+]] = load i32, i32* [[SIVAR]], +// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T]] task_data; +// [[KMP_TASK_MAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// Also copy address of private copy to the corresponding shareds reference. +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_MAIN_TY]]* + +// Constructors for s_arr and var. +// s_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 +// CHECK: load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[S_ARR_ADDR_REF]], +// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]], +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[VAR_REF:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[VAR_ADDR_REF]], +// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]], [[S_DOUBLE_TY]]* {{.*}}[[VAR_REF]], + +// t_var; +// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_ADDR_REF]], +// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], + +// vec; +// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( + +// sivar; +// CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 5 +// CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_ADDR_REF]], +// CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]], + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) + +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, +// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4 +// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}}, +// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias) + +// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, +// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, +// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], + +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) + +// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] +// CHECK-DAG: [[PRIV_SIVAR]] + +// CHECK: ret + +// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2 +// CHECK: br i1 % + +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i32 1 +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: alloca [[S_INT_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128 +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]], + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_TMAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_TMAIN_TY]]* + +// t_var; +// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[T_VAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[T_VAR_ADDR_REF]], +// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_REF]], align 128 +// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], align 128 + +// vec; +// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]], +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]], + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*)) + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]** +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]], +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}}, +// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] + +// CHECK: ret + +// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2 +// CHECK: br i1 % + +// CHECK: phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* +// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i32 1 +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3 +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +#endif +#else +// ARRAY-LABEL: array_func +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &) {} + ~St() {} +}; + +void array_func(int n, float a[n], St s[2]) { +// ARRAY: call i8* @__kmpc_omp_task_alloc( +// ARRAY: call void @__kmpc_taskloop( +// ARRAY: store float** %{{.+}}, float*** %{{.+}}, +// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}}, +#pragma omp taskloop simd firstprivate(a, s) + for (int i = 0; i < 10; ++i) + ; +} +#endif + diff --git a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp index 83946695204b8..18cefc1beeb25 100644 --- a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp +++ b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp @@ -295,9 +295,9 @@ int main(int argc, char **argv) { #pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}} for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}} foo(); -#pragma omp parallel reduction(+ : i) -#pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}} - for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}} +#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}} +#pragma omp taskloop simd firstprivate(i) // expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}} + for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}} foo(); #pragma omp parallel #pragma omp taskloop simd firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} diff --git a/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp b/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp new file mode 100644 index 0000000000000..e3562a8f0c62d --- /dev/null +++ b/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp @@ -0,0 +1,519 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +// It doesn't pass on win32. +// REQUIRES: shell +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S(const S &s, T t = T()) : f(s.f + t) {} + operator T() { return T(); } + ~S() {} +}; + +volatile double g; + +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 } +// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } +// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* } +// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] } +// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] } +template <typename T> +T tmain() { + S<T> ttt; + S<T> test; + T t_var __attribute__((aligned(128))) = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp taskloop simd lastprivate(t_var, vec, s_arr, s_arr, var, var) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global double + // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + +// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) +// LAMBDA: ret +#pragma omp taskloop simd lastprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] + // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + + // LAMBDA: store double* %{{.+}}, double** %{{.+}}, + // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: call void [[INNER_LAMBDA]](% + // LAMBDA: icmp ne i32 %{{.+}}, 0 + // LAMBDA: br i1 + // LAMBDA: load double, double* % + // LAMBDA: store volatile double % + // LAMBDA: load i32, i32* % + // LAMBDA: store i32 % + // LAMBDA: ret + [&]() { + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global double + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) + // BLOCKS: ret +#pragma omp taskloop simd lastprivate(g, sivar) + for (int i = 0; i < 10; ++i) { + // BLOCKS: define {{.+}} void {{@.+}}(i8* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store double 2.0{{.+}}, double* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: ret + + // BLOCKS: store double* %{{.+}}, double** %{{.+}}, + // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}}, + // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 11; + // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + // BLOCKS: icmp ne i32 %{{.+}}, 0 + // BLOCKS: br i1 + // BLOCKS: load double, double* % + // BLOCKS: store volatile double % + // BLOCKS: load i32, i32* % + // BLOCKS: store i32 % + ^{ + g = 2; + sivar = 22; + }(); + } + }(); + return 0; +#else + S<double> ttt; + S<double> test; + int t_var = 0; + int vec[] = {1, 2}; + S<double> s_arr[] = {1, 2}; + S<double> var(3); +#pragma omp taskloop simd lastprivate(var, t_var, s_arr, vec, s_arr, var, sivar) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + sivar = 33; + } + return tmain<int>(); +#endif +} + +// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0, +// CHECK: define i{{[0-9]+}} @main() +// CHECK: alloca [[S_DOUBLE_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]]) + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T]] task_data; +// [[KMP_TASK_MAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// Also copy address of private copy to the corresponding shareds reference. +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + +// Constructors for s_arr and var. +// s_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]]) +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) + +// t_var; +// vec; +// sivar; + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) + +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, +// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4 +// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}}, +// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias) + +// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, +// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, +// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], + +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) + +// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] +// CHECK-DAG: [[PRIV_SIVAR]] + +// CHECK: icmp ne i32 %{{.+}}, 0 +// CHECK-NEXT: br i1 +// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8* +// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* % +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK-NEXT: br i1 +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: br label +// CHECK: ret + +// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: alloca [[S_INT_TY]], +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128 +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) + +// Store original variables in capture struct. +// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]], +// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]], +// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]], +// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_TMAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* + +// Fill kmp_task_t->shareds by copying from original capture argument. +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], +// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false) + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + +// t_var; +// vec; + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]]) +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*)) + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]** +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]], +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}}, +// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] + +// CHECK: icmp ne i32 %{{.+}}, 0 +// CHECK-NEXT: br i1 +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: bitcast [2 x i32]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* % +// CHECK: phi [[S_INT_TY]]* +// CHECK: phi [[S_INT_TY]]* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK-NEXT: br i1 +// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8* +// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* % +// CHECK: br label +// CHECK: ret + +// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8 +// CHECK: load i32, i32* % +// CHECK: store i32 %{{.+}}, i32* % +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3 +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +#endif +#else +// ARRAY-LABEL: array_func +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &) {} + ~St() {} +}; + +void array_func(int n, float a[n], St s[2]) { +// ARRAY: call i8* @__kmpc_omp_task_alloc( +// ARRAY: call void @__kmpc_taskloop( +// ARRAY: store float** %{{.+}}, float*** %{{.+}}, +// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}}, +// ARRAY: icmp ne i32 %{{.+}}, 0 +// ARRAY: store float* %{{.+}}, float** %{{.+}}, +// ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}}, +#pragma omp taskloop simd lastprivate(a, s) + for (int i = 0; i < 10; ++i) + ; +} +#endif + diff --git a/test/OpenMP/taskloop_simd_loop_messages.cpp b/test/OpenMP/taskloop_simd_loop_messages.cpp index 47318721102fd..3326e6ff61cd8 100644 --- a/test/OpenMP/taskloop_simd_loop_messages.cpp +++ b/test/OpenMP/taskloop_simd_loop_messages.cpp @@ -428,12 +428,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -484,7 +484,7 @@ int test_with_random_access_iterator() { #pragma omp taskloop simd for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp taskloop simd diff --git a/test/OpenMP/taskloop_simd_private_codegen.cpp b/test/OpenMP/taskloop_simd_private_codegen.cpp new file mode 100644 index 0000000000000..557601e9c93e4 --- /dev/null +++ b/test/OpenMP/taskloop_simd_private_codegen.cpp @@ -0,0 +1,420 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s +// expected-no-diagnostics +// REQUIRES: x86-registered-target +// It doesn't pass on win32. Investigating. +// REQUIRES: shell + +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + operator T() { return T(); } + ~S() {} +}; + +volatile double g; + +// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 } +// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 } +// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32] +// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i8 } +// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] } +// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] } +template <typename T> +T tmain() { + S<T> test; + T t_var __attribute__((aligned(128))) = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp taskloop simd private(t_var, vec, s_arr, s_arr, var, var) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global double + // LAMBDA-LABEL: @main + // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) +// LAMBDA: ret +#pragma omp taskloop simd private(g, sivar) + for (int i = 0; i < 10; ++i) { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] + // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SIVAR_REF]] + + // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 2; + // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: call void [[INNER_LAMBDA]](% + // LAMBDA: ret + [&]() { + g = 2; + sivar = 3; + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global double + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null) + // BLOCKS: ret +#pragma omp taskloop simd private(g, sivar) + for (int i = 0; i < 10; ++i) { + // BLOCKS: define {{.+}} void {{@.+}}(i8* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store double 2.0{{.+}}, double* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: ret + + // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias) + g = 1; + sivar = 3; + // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 3, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + ^{ + g = 2; + sivar = 4; + }(); + } + }(); + return 0; +#else + S<double> test; + int t_var = 0; + int vec[] = {1, 2}; + S<double> s_arr[] = {1, 2}; + S<double> var(3); +#pragma omp taskloop simd private(var, t_var, s_arr, vec, s_arr, var, sivar) + for (int i = 0; i < 10; ++i) { + vec[0] = t_var; + s_arr[0] = var; + sivar = 8; + } +#pragma omp task + g+=1; + return tmain<int>(); +#endif +} + +// CHECK: define i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]]) + +// Do not store original variables in capture struct. +// CHECK-NOT: getelementptr inbounds [[CAP_MAIN_TY]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_MAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* + +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// Also copy address of private copy to the corresponding shareds reference. +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%.+]]) +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF:%.+]]) + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*)) +// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* + +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, +// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias) + +// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, +// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, +// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) +// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] +// CHECK_DAG: [[PRIV_SIVAR]] + +// CHECK: ret + +// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_DOUBLE_TY]]* +// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_DOUBLE_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1 +// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, +// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32], +// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]]) + +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) + +// Do not store original variables in capture struct. +// CHECK-NOT: getelementptr inbounds [[CAP_TMAIN_TY]], + +// Allocate task. +// Returns struct kmp_task_t { +// [[KMP_TASK_T_TY]] task_data; +// [[KMP_TASK_TMAIN_TY]] privates; +// }; +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]* + +// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + +// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + +// Constructors for s_arr and var. +// a_arr; +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%.+]]) +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1 +// CHECK: icmp eq +// CHECK: br i1 + +// var; +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF:%.+]]) + +// Provide pointer to destructor function, which will destroy private variables at the end of the task. +// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)** +// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]], + +// Start task. +// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*)) + +// No destructors must be called for private copies of s_arr and var. +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: ret +// + +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias) +// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]** +// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0 +// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}}, +// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]], +// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, +// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]], +// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2 +// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}}, +// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]], +// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3 +// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}}, +// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]], +// CHECK: ret void + +// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) + +// CHECK: alloca i32*, +// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, +// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, +// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, +// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) +// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], +// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], +// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]], + +// Privates actually are used. +// CHECK-DAG: [[PRIV_VAR]] +// CHECK-DAG: [[PRIV_T_VAR]] +// CHECK-DAG: [[PRIV_S_ARR]] +// CHECK-DAG: [[PRIV_VEC]] + +// CHECK: ret + +// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32) +// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2 +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2 +// CHECK: br label % + +// CHECK: phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1 +// CHECK: icmp eq [[S_INT_TY]]* % +// CHECK: br i1 % + +// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3 +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias) +// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]]) +// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0 +// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2 +// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1 +// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]]) +// CHECK: icmp eq +// CHECK: br i1 +// CHECK: ret i32 + +#endif +#else +// ARRAY-LABEL: array_func +struct St { + int a, b; + St() : a(0), b(0) {} + St &operator=(const St &) { return *this; }; + ~St() {} +}; + +void array_func(int n, float a[n], St s[2]) { +// ARRAY: call i8* @__kmpc_omp_task_alloc( +// ARRAY: call void @__kmpc_taskloop( +// ARRAY: store float** %{{.+}}, float*** %{{.+}}, +// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}}, +#pragma omp taskloop simd private(a, s) + for (int i = 0; i < 10; ++i) + ; +} +#endif + diff --git a/test/OpenMP/taskloop_simd_private_messages.cpp b/test/OpenMP/taskloop_simd_private_messages.cpp index 4a9b08a7e9e29..ba9e8da17e205 100644 --- a/test/OpenMP/taskloop_simd_private_messages.cpp +++ b/test/OpenMP/taskloop_simd_private_messages.cpp @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp taskloop simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp taskloop simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp taskloop simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp taskloop simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp taskloop simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp taskloop simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -126,6 +174,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp taskloop simd private // expected-error {{expected '(' after 'private'}} @@ -190,6 +240,8 @@ int main(int argc, char **argv) { for(int k = 0; k < argc; ++k) si = k + 1; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } diff --git a/test/OpenMP/taskloop_simd_safelen_messages.cpp b/test/OpenMP/taskloop_simd_safelen_messages.cpp index 3182c8af80fa3..729f31407bfaa 100644 --- a/test/OpenMP/taskloop_simd_safelen_messages.cpp +++ b/test/OpenMP/taskloop_simd_safelen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd safelen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}} - // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}} + // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp taskloop simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd safelen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd safelen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp taskloop simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp taskloop simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp taskloop simd safelen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}} // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp taskloop simd safelen (foobool(argc)), safelen (true), safelen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp taskloop simd safelen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp taskloop simd' must be a for loop}} diff --git a/test/OpenMP/taskloop_simd_simdlen_messages.cpp b/test/OpenMP/taskloop_simd_simdlen_messages.cpp index ba3f20e23cfe1..79655ba9c275b 100644 --- a/test/OpenMP/taskloop_simd_simdlen_messages.cpp +++ b/test/OpenMP/taskloop_simd_simdlen_messages.cpp @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s void foo() { } +#if __cplusplus >= 201103L +// expected-note@+2 4 {{declared here}} +#endif bool foobool(int argc) { return argc; } @@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd simdlen ((ST > 0) ? 1 + ST : 2) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+3 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}} - // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} - // expected-error@+1 2 {{expression is not an integral constant expression}} + // expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} + // expected-error@+4 2 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif #pragma omp taskloop simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd simdlen (S) // expected-error {{'S' does not refer to a value}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - // expected-error@+1 2 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 2 {{expression is not an integral constant expression}} +#else + // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp taskloop simd simdlen (4) @@ -57,16 +69,27 @@ int main(int argc, char **argv) { for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp taskloop simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - #pragma omp taskloop simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + // expected-error@+4 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif + #pragma omp taskloop simd simdlen (foobool(1) > 0 ? 1 : 2) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+6 {{expression is not an integral constant expression}} +#if __cplusplus >= 201103L + // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}} +#endif // expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}} // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} #pragma omp taskloop simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; #pragma omp taskloop simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; - // expected-error@+1 {{expression is not an integral constant expression}} +#if __cplusplus <= 199711L + // expected-error@+4 {{expression is not an integral constant expression}} +#else + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}} +#endif #pragma omp taskloop simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error@+3 {{statement after '#pragma omp taskloop simd' must be a for loop}} diff --git a/test/OpenMP/teams_ast_print.cpp b/test/OpenMP/teams_ast_print.cpp index 292586ae530d9..f3d577cafcd35 100644 --- a/test/OpenMP/teams_ast_print.cpp +++ b/test/OpenMP/teams_ast_print.cpp @@ -109,4 +109,6 @@ int main (int argc, char **argv) { return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); } +extern template int S<int>::TS; +extern template long S<long>::TS; #endif diff --git a/test/OpenMP/teams_codegen.cpp b/test/OpenMP/teams_codegen.cpp new file mode 100644 index 0000000000000..8aaa206abc3b4 --- /dev/null +++ b/test/OpenMP/teams_codegen.cpp @@ -0,0 +1,353 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER +// Test host codegen. +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +#ifdef CK1 + +int Gbla; +long long Gblb; +int &Gblc = Gbla; + +// CK1-LABEL: teams_argument_global_local +int teams_argument_global_local(int a){ + int comp = 1; + + int la = 23; + float lc = 25.0; + + // CK1: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0) + // CK1: call void @{{.+}}(i{{64|32}} %{{.+}}) + #pragma omp target + #pragma omp teams + { + ++comp; + } + + // CK1: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0) + // CK1: call void @{{.+}}(i{{64|32}} %{{.+}}) + #pragma omp target + {{{ + #pragma omp teams + { + ++comp; + } + }}} + + // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 0) + // CK1-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]], + + // CK1: call void @{{.+}}(i{{64|32}} %{{.+}}) + #pragma omp target + #pragma omp teams num_teams(la) + { + ++comp; + } + + // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 [[NT:%[^,]+]]) + // CK1-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]], + + // CK1: call void @{{.+}}(i{{64|32}} %{{.+}}) + #pragma omp target + #pragma omp teams thread_limit(la) + { + ++comp; + } + + // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]]) + + // CK1-DAG: [[NT]] = add nsw i32 [[NTA:%[^,]+]], [[NTB:%[^,]+]] + // CK1-DAG: [[NTA]] = load i32, i32* @Gbla, + // CK1-DAG: [[NTB]] = load i32, i32* %{{.+}}, + + // CK1-DAG: [[TL]] = trunc i64 [[TLA:%[^,]+]] to i32 + // CK1-DAG: [[TLA]] = add nsw i64 [[TLB:%[^,]+]], [[TLC:%[^,]+]] + // CK1-DAG: [[TLC]] = fptosi float [[TLD:%[^,]+]] to i64 + // CK1-DAG: [[TLD]] = load float, float* %{{.+}}, + // CK1-DAG: [[TLB]] = load i64, i64* @Gblb, + + // CK1: call void @{{.+}}(i{{.+}} {{.+}}, i{{.+}} {{.+}}, i{{.+}} {{.+}}, i{{.+}} {{.+}}, i{{.+}} {{.+}}) + #pragma omp target + #pragma omp teams num_teams(Gbla+a) thread_limit(Gblb+(long long)lc) + { + ++comp; + } + + // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 {{.+}}, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]]) + + // CK1-DAG: [[NT]] = add nsw i32 [[NTA:%[^,]+]], 1 + // CK1-DAG: [[NTA]] = load i32, i32* @Gbla, + + // CK1-DAG: [[TL]] = add nsw i32 [[TLA:%[^,]+]], 2 + // CK1-DAG: [[TLA]] = load i32, i32* @Gbla, + + // CK1: call void @{{.+}}(i{{.+}} {{.+}} + #pragma omp target + #pragma omp teams num_teams(Gblc+1) thread_limit(Gblc+2) + { + comp += Gblc; + } + + return comp; +} + +#endif // CK1 + +// Test host codegen. +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +#ifdef CK2 + +// CK2-DAG: [[SSI:%.+]] = type { i32, float } +// CK2-DAG: [[SSL:%.+]] = type { i64, float } +template <typename T> +struct SS{ + T a; + float b; +}; + +SS<int> Gbla; +SS<long long> Gblb; + +// CK2-LABEL: teams_template_arg +int teams_template_arg(void) { + int comp = 1; + + SS<int> la; + SS<long long> lb; + + // CK2-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]]) + + // CK2-DAG: [[NT]] = load i32, i32* getelementptr inbounds ([[SSI]], [[SSI]]* @Gbla, i32 0, i32 0) + + // CK2-DAG: [[TL]] = trunc i64 [[TLA:%[^,]+]] to i32 + // CK2-DAG: [[TLA]] = fptosi float [[TLB:%[^,]+]] to i64 + // CK2-DAG: [[TLB]] = load float, float* [[TLC:%[^,]+]], + // CK2-DAG: [[TLC]] = getelementptr inbounds [[SSI]], [[SSI]]* %{{.+}}, i32 0, i32 1 + + // CK2: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}}, {{.+}} {{.+}}) + #pragma omp target + #pragma omp teams num_teams(Gbla.a) thread_limit((long long)la.b) + { + ++comp; + } + + // CK2-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]]) + + // CK2-DAG: [[TL]] = trunc i64 [[TLD:%[^,]+]] to i32 + // CK2-DAG: [[TLD]] = load i64, i64* getelementptr inbounds ([[SSL]], [[SSL]]* @Gblb, i32 0, i32 0), + + // CK2-DAG: [[NT]] = trunc i64 [[NTA:%[^,]+]] to i32 + // CK2-DAG: [[NTA]] = fptosi float [[NTB:%[^,]+]] to i64 + // CK2-DAG: [[NTB]] = load float, float* [[NTC:%[^,]+]], + // CK2-DAG: [[NTC]] = getelementptr inbounds [[SSL]], [[SSL]]* %{{.+}}, i32 0, i32 1 + + // CK2: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}}, {{.+}} {{.+}}) + #pragma omp target + #pragma omp teams num_teams((long long)lb.b) thread_limit(Gblb.a) + { + ++comp; + } + return comp; +} +#endif // CK2 + +// Test host codegen. +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64 +// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32 +#ifdef CK3 + +// CK3: [[SSI:%.+]] = type { i32, float } +// CK3-LABEL: teams_template_struct + +template <typename T, int X, long long Y> +struct SS{ + T a; + float b; + + int foo(void) { + int comp = 1; + + // CK3-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 123) + + // CK3-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]], + // CK3-DAG: [[NTA]] = getelementptr inbounds [[SSI]], [[SSI]]* [[NTB:%[^,]+]], i32 0, i32 0 + // CK3-DAG: [[NTB]] = load [[SSI]]*, [[SSI]]** %{{.+}}, + + // CK3: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}}) + #pragma omp target + #pragma omp teams num_teams(a) thread_limit(X) + { + ++comp; + } + + // CK3-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 456, i32 [[TL:%[^,]+]]) + + // CK3-DAG: [[TL]] = add nsw i32 [[TLA:%[^,]+]], 123 + // CK3-DAG: [[TLA]] = fptosi float [[TLB:%[^,]+]] to i32 + // CK3-DAG: [[TLB]] = load float, float* [[TLC:%[^,]+]], + // CK3-DAG: [[TLC]] = getelementptr inbounds [[SSI]], [[SSI]]* [[THIS:%[^,]+]], i32 0, i32 1 + + // CK3: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}}) + #pragma omp target + #pragma omp teams num_teams(Y) thread_limit((int)b+X) + { + ++comp; + } + return comp; + } +}; + +int teams_template_struct(void) { + SS<int, 123, 456> V; + return V.foo(); + +} +#endif // CK3 + +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 + +#ifdef CK4 + +// CK4-DAG: %ident_t = type { i32, i32, i32, i32, i8* } +// CK4-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" +// CK4-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) } +// CK4-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;main;[[@LINE+14]];9;;\00" +// CK4-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;tmain;[[@LINE+7]];9;;\00" + +template <typename T> +int tmain(T argc) { +#pragma omp target +#pragma omp teams + argc = 0; + return 0; +} + +int main (int argc, char **argv) { +#pragma omp target +#pragma omp teams + argc = 0; + return tmain(argv); +} + +// CK4: define {{.*}}void @{{[^,]+}}(i{{.+}} %[[ARGC:.+]]) +// CK4: [[ARGCADDR:%.+]] = alloca i{{.+}} +// CK4: store i{{.+}} %[[ARGC]], i{{.+}}* [[ARGCADDR]] +// CK4-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32* +// CK4-64: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* {{.+}} to void (i32*, i32*, ...)*), i32* [[CONV]]) +// CK4-32: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* {{.+}} to void (i32*, i32*, ...)*), i32* [[ARGCADDR]]) +// CK4: ret void +// CK4-NEXT: } + +// CK4: define {{.*}}void @{{[^,]+}}(i8** [[ARGC1:%.+]]) +// CK4: [[ARGCADDR1:%.+]] = alloca i8** +// CK4: store i8** [[ARGC1]], i8*** [[ARGCADDR1]] +// CK4: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8***)* {{.+}} to void (i32*, i32*, ...)*), i8*** [[ARGCADDR1]]) + + +#endif // CK4 + +// Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 +// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 +// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 + +// expected-no-diagnostics +#ifdef CK5 + +// CK5-DAG: %ident_t = type { i32, i32, i32, i32, i8* } +// CK5-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" +// CK5-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) } +// CK5-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;main;[[@LINE+14]];9;;\00" +// CK5-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;tmain;[[@LINE+7]];9;;\00" + +template <typename T> +int tmain(T argc) { + int a = 10; + int b = 5; +#pragma omp target +#pragma omp teams num_teams(a) thread_limit(b) + { + argc = 0; + } + return 0; +} + +int main (int argc, char **argv) { + int a = 20; + int b = 5; +#pragma omp target +#pragma omp teams num_teams(a) thread_limit(b) + { + argc = 0; + } + return tmain(argv); +} + +// CK5: define {{.*}}void @{{[^,]+}}(i{{.+}} [[AP:%.+]], i{{.+}} [[BP:%.+]], i{{.+}} [[ARGC:.+]]) +// CK5: [[AADDR:%.+]] = alloca i{{.+}} +// CK5: [[BADDR:%.+]] = alloca i{{.+}} +// CK5: [[ARGCADDR:%.+]] = alloca i{{.+}} +// CK5: [[GBL_TH_NUM:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEF_LOC_0]]) +// CK5: store i{{.+}} [[AP]], i{{.+}}* [[AADDR]] +// CK5: store i{{.+}} [[BP]], i{{.+}}* [[BADDR]] +// CK5: store i{{.+}} [[ARGC]], i{{.+}}* [[ARGCADDR]] +// CK5-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32* +// CK5-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32* +// CK5-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32* +// CK5-64: [[ACONVVAL:%.+]] = load i32, i32* [[ACONV]] +// CK5-64: [[BCONVVAL:%.+]] = load i32, i32* [[BCONV]] +// CK5-32: [[ACONVVAL:%.+]] = load i32, i32* [[AADDR]] +// CK5-32: [[BCONVVAL:%.+]] = load i32, i32* [[BADDR]] +// CK5: {{.+}} = call i32 @__kmpc_push_num_teams(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TH_NUM]], i32 [[ACONVVAL]], i32 [[BCONVVAL]]) +// CK5-64: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[CONV]]) +// CK5-32: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[ARGCADDR]]) + +// CK5: define {{.*}}void @{{[^,]+}}(i{{.+}} [[AP:%.+]], i{{.+}} [[BP:%.+]], i{{.+}}** [[ARGC:%.+]]) +// CK5: [[AADDR:%.+]] = alloca i{{.+}} +// CK5: [[BADDR:%.+]] = alloca i{{.+}} +// CK5: [[ARGCADDR:%.+]] = alloca i{{.+}}** +// CK5: [[GBL_TH_NUM:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEF_LOC_0]]) +// CK5: store i{{.+}} [[AP]], i{{.+}}* [[AADDR]] +// CK5: store i{{.+}} [[BP]], i{{.+}}* [[BADDR]] +// CK5: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]] +// CK5-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32* +// CK5-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32* +// CK5-64: [[ACONVVAL:%.+]] = load i32, i32* [[ACONV]] +// CK5-64: [[BCONVVAL:%.+]] = load i32, i32* [[BCONV]] +// CK5-64: {{.+}} = call i32 @__kmpc_push_num_teams(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TH_NUM]], i32 [[ACONVVAL]], i32 [[BCONVVAL]]) +// CK5-32: [[A_VAL:%.+]] = load i32, i32* [[AADDR]] +// CK5-32: [[B_VAL:%.+]] = load i32, i32* [[BADDR]] +// CK5-32: {{.+}} = call i32 @__kmpc_push_num_teams(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TH_NUM]], i32 [[A_VAL]], i32 [[B_VAL]]) +// CK5: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i{{.+}})* @.omp_outlined.{{.+}} to void (i32*, i32*, ...)*), i{{.+}}*** [[ARGCADDR]]) +// CK5: ret void +// CK5-NEXT: } + +#endif // CK5 +#endif diff --git a/test/OpenMP/teams_firstprivate_codegen.cpp b/test/OpenMP/teams_firstprivate_codegen.cpp new file mode 100644 index 0000000000000..3248bfeebd91f --- /dev/null +++ b/test/OpenMP/teams_firstprivate_codegen.cpp @@ -0,0 +1,283 @@ +// Test host codegen. +// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64 +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64 +// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32 +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32 + +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 + +// RUN: %clang_cc1 -DARRAY -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-64 +// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-64 +// RUN: %clang_cc1 -DARRAY -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-32 +// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER +#ifndef ARRAY +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &st) : a(st.a + st.b), b(0) {} + ~St() {} +}; + +volatile int g __attribute__((aligned(128))) = 1212; + +template <class T> +struct S { + T f; + S(T a) : f(a + g) {} + S() : f(g) {} + S(const S &s, St t = St()) : f(s.f + t.a) {} + operator T() { return T(); } + ~S() {} +}; + +// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } + +template <typename T> +T tmain() { + S<T> test; + T t_var __attribute__((aligned(128))) = T(); + T vec[] __attribute__((aligned(128))) = {1, 2}; + S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; + S<T> var __attribute__((aligned(128))) (3); + #pragma omp target + #pragma omp teams firstprivate(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } +#pragma omp target +#pragma omp teams firstprivate(t_var) + {} + return T(); +} + +int main() { + static int sivar; +#ifdef LAMBDA + // LAMBDA-LABEL: @main + // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* {{.+}}, {{.+}}) + #pragma omp target + #pragma omp teams firstprivate(g, sivar) + { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[G_IN:%.+]], i{{64|32}} {{.*}}[[SIVAR_IN:%.+]]) + // LAMBDA: store i{{[0-9]+}}* [[G_IN]], i{{[0-9]+}}** [[G_ADDR:%.+]], + // LAMBDA: store i{{[0-9]+}} [[SIVAR_IN]], i{{[0-9]+}}* [[SIVAR_ADDR:%.+]], + // LAMBDA: [[G_ADDR_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_ADDR]], + // LAMBDA-64: [[SIVAR_CONV:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32* + // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_ADDR_VAL]], + // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_LOCAL:%.+]], + g = 1; + sivar = 2; + // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_LOCAL]], + // LAMBDA-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_CONV]], + // LAMBDA-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_ADDR]], + // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G_LOCAL]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA-64: store i{{[0-9]+}}* [[SIVAR_CONV]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] + // LAMBDA-32: store i{{[0-9]+}}* [[SIVAR_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] + // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + sivar = 4; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] + }(); + } + }(); + return 0; +#else + S<float> test; + int t_var = 0; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> var(3); + #pragma omp target + #pragma omp teams firstprivate(t_var, vec, s_arr, var, sivar) + { + vec[0] = t_var; + s_arr[0] = var; + sivar = 2; + } + #pragma omp target + #pragma omp teams firstprivate(t_var) + {} + return tmain<int>(); +#endif +} + +// CHECK: define internal {{.*}}void [[OMP_OFFLOADING:@.+]]( +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i{{32|64}}, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[OMP_OUTLINED:@.+]] to void +// CHECK: ret +// +// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i{{32|64}} {{.*}}%{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, i{{32|64}} {{.*}}[[SIVAR:%.+]]) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % +// CHECK-64: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_PRIV]] to i32* +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** % +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// CHECK-64: [[SIVAR7_CONV:%.+]] = bitcast i64* [[SIVAR7_PRIV]] to i32* +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]] to [[S_FLOAT_TY]]* +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) + +// CHECK-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_CONV]], +// CHECK-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]], + +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: ret void + +// CHECK: define internal {{.*}}void [[OMP_OFFLOADING_1:@.+]]( +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}})* [[OMP_OUTLINED_1:@.+]] to void +// CHECK: ret + +// CHECK: define internal {{.*}}void [[OMP_OUTLINED_1]](i{{[0-9]+}}* noalias {{%.+}}, i{{[0-9]+}}* noalias {{%.+}}, i{{32|64}} {{.*}}[[T_VAR:%.+]]) +// CHECK: [[T_VAR_LOC:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}} [[T_VAR]], i{{[0-9]+}}* [[T_VAR_LOC]], +// CHECK: ret + +// CHECK: define internal {{.*}}void [[OMP_OFFLOADING_2:@.+]](i{{[0-9]+}}* {{.+}} {{%.+}}, [2 x i32]* {{.+}} {{%.+}}, [2 x [[S_INT_TY]]]* {{.+}} {{%.+}}, [[S_INT_TY]]* {{.+}} {{%.+}}) +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_2:@.+]] to void +// CHECK: ret + +// +// CHECK: define internal {{.*}}void [[OMP_OUTLINED_2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128 +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], align 128 +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % + +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], align 128 +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], align 128 +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], i{{[0-9]+}} {{[0-9]+}}, i{{[0-9]+}} 128, +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_REF]] to [[S_INT_TY]]* +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: ret void + +// CHECK: define internal {{.*}}void [[OMP_OFFLOADING_3:@.+]]( +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_3:@.+]] to void +// CHECK: ret + +// CHECK: define internal {{.*}}void [[OMP_OUTLINED_3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) [[T_VAR:%.+]]) +// CHECK: [[T_VAR_LOC:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[T_VAR]], i{{[0-9]+}}** [[T_VAR_ADDR:%.+]], +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]], +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_LOC]], +// CHECK: ret + +#else +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &) { } + ~St() {} + void St_func(St s[2], int n, long double vla1[n]) { + double vla2[n][n] __attribute__((aligned(128))); + a = b; + #pragma omp target + #pragma omp teams firstprivate(s, vla1, vla2) + vla1[b] = vla2[1][n - 1] = a = b; + } +}; + +void array_func(float a[3], St s[2], int n, long double vla1[n]) { + double vla2[n][n] __attribute__((aligned(128))); +// ARRAY: call {{.+}} @__kmpc_fork_teams( +// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*, +// ARRAY-64-DAG: [[PRIV_VLA1:%.+]] = alloca ppc_fp128*, +// ARRAY-32-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*, +// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float*, +// ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*, +// ARRAY-DAG: store float* %{{.+}}, float** [[PRIV_A]], +// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], +// ARRAY-64-DAG: store ppc_fp128* %{{.+}}, ppc_fp128** [[PRIV_VLA1]], +// ARRAY-32-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], +// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]], +// ARRAY: call i8* @llvm.stacksave() +// ARRAY: [[SIZE:%.+]] = mul nuw i{{[0-9]+}} %{{.+}}, 8 +// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* %{{.+}}, i8* %{{.+}}, i{{[0-9]+}} [[SIZE]], i32 128, i1 false) + #pragma omp target + #pragma omp teams firstprivate(a, s, vla1, vla2) + s[0].St_func(s, n, vla1); + ; +} + +// ARRAY: @__kmpc_fork_teams( +// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*, +// ARRAY-64-DAG: [[PRIV_VLA1:%.+]] = alloca ppc_fp128*, +// ARRAY-32-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*, +// ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*, +// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], +// ARRAY-64-DAG: store ppc_fp128* %{{.+}}, ppc_fp128** [[PRIV_VLA1]], +// ARRAY-32-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], +// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]], +// ARRAY: call i8* @llvm.stacksave() +// ARRAY: [[SIZE:%.+]] = mul nuw i{{[0-9]+}} %{{.+}}, 8 +// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* %{{.+}}, i8* %{{.+}}, i{{[0-9]+}} [[SIZE]], i32 128, i1 false) +#endif +#endif diff --git a/test/OpenMP/teams_private_codegen.cpp b/test/OpenMP/teams_private_codegen.cpp new file mode 100644 index 0000000000000..1ba010fa5c3cc --- /dev/null +++ b/test/OpenMP/teams_private_codegen.cpp @@ -0,0 +1,298 @@ +// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64 +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64 +// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32 +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32 + +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + operator T() { return T(); } + ~S() {} +}; + +volatile int g __attribute__((aligned(128))) = 1212; + +struct SS { + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp target +#pragma omp teams private(a, b, c) +#ifdef LAMBDA + [&]() { + ++this->a, --b, (this)->c /= 1; + }(); +#else + ++this->a, --b, c /= 1; +#endif + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp target +#pragma omp teams private(a) +#ifdef LAMBDA + [&]() { + [&]() { + ++this->a; + }(); + }(); +#else + ++(this)->a; +#endif + } +}; + +// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 +// LAMBDA: [[CAP_0_TY:%.+]] = type { [[SS_TY]]*, i{{[0-9]+}}*, +// LAMBDA: [[CAP_1_TY:%.+]] = type { i{{[0-9]+}}*, i{{[0-9]+}}* } +// CHECK: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK: [[SST_TY:%.+]] = type { i{{[0-9]+}} } +template <typename T> +T tmain() { + S<T> test; + SST<T> sst; + T t_var __attribute__((aligned(128))) = T(); + T vec[] __attribute__((aligned(128))) = {1, 2}; + S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; + S<T> var __attribute__((aligned(128))) (3); +#pragma omp target +#pragma omp teams private(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { + static int sivar; + SS ss(sivar); +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA: define {{.+}} @main() + // LAMBDA: alloca [[SS_TY]], + // LAMBDA: alloca [[CAP_TY:%.+]], + + // LAMBDA: call{{.*}} [[ST_CONSTR_INIT:@.+]]([[SS_TY]]* + // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]* + + // lambda and target region in main + // LAMBDA: define {{.+}} [[OUTER_LAMBDA]]([[CAP_TY]]* {{.+}}) + // LAMBDA: call void @[[OMP_OFFLOADING:.+]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}} {{.+}} + + // target region in struct constructor + // LAMBDA: define{{.*}} void [[ST_CONSTR:@.+]]([[SS_TY]]* %this, + // LAMBDA: call void [[OMP_OFFLOADING_1:@.+]]([[SS_TY]] + + // offloading function in struct constructor + // LAMBDA: define{{.*}} void [[OMP_OFFLOADING_1]]([[SS_TY]] + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[OMP_OUTLINED:@.+]] to void + + // outlined teams region in struct constructor + // LAMBDA: define{{.*}} void [[OMP_OUTLINED]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}}, [[SS_TY]]* + // LAMBDA: [[THIS_ADDR:%.+]] = alloca [[SS_TY]]*, + // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[THIS_REF:%.+]] = load [[SS_TY]]*, [[SS_TY]]** [[THIS_ADDR]], + // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[A_TMP_REF:%.+]], + // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[C_TMP_REF:%.+]], + // LAMBDA: [[CAP_THIS_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store [[SS_TY]]* [[THIS_REF]], [[SS_TY]]** [[CAP_THIS_REF]], + // LAMBDA: [[CAP_A_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[A_TMP_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[A_TMP_REF]], + // LAMBDA: store i{{[0-9]+}}* [[A_TMP_VAL]], i{{[0-9]+}}** [[CAP_A_REF]], + // LAMBDA: [[CAP_B_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // LAMBDA: store i{{[0-9]+}}* [[B_PRIV]], i{{[0-9]+}}** [[CAP_B_REF]], + // LAMBDA: [[CAP_C_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // LAMBDA: [[C_TMP_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_TMP_REF]], + // LAMBDA: store i{{[0-9]+}}* [[C_TMP_VAL]], i{{[0-9]+}}** [[CAP_C_REF]], + // call void [[INNER_LAMBDA_CONSTR:@.+]]([[CAP_0_TY]]* + + // inner lambda in struct constructor + // define{{.*}} void [[INNER_LAMBDA_CONSTR]]([[CAP_0_TY]]* + // LAMBDA: [[CAP_A_REF_1:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[A_REF_FROM_CAP:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[CAP_A_REF_1]], + // LAMBDA: [[A_VAL_FROM_CAP:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_REF_FROM_CAP]], + // LAMBDA: [[A_INC_VAL:%.+]] = add {{.+}} i{{[0-9]+}} [[A_VAL_FROM_CAP]], 1 + // LAMBDA: store i{{[0-9]+}} [[A_INC_VAL]], i{{[0-9]+}}* [[A_REF_FROM_CAP]], + + // LAMBDA: [[CAP_B_REF_1:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // LAMBDA: [[B_REF_FROM_CAP:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[CAP_B_REF_1]], + // LAMBDA: [[B_VAL_FROM_CAP:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_REF_FROM_CAP]], + // LAMBDA: [[B_DEC_VAL:%.+]] = add {{.+}} i{{[0-9]+}} [[B_VAL_FROM_CAP]], -1 + // LAMBDA: store i{{[0-9]+}} [[B_DEC_VAL]], i{{[0-9]+}}* [[B_REF_FROM_CAP]], + + // LAMBDA: [[CAP_C_REF_1:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 + // LAMBDA: [[C_REF_FROM_CAP:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[CAP_C_REF_1]], + // LAMBDA: [[C_VAL_FROM_CAP:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_REF_FROM_CAP]], + // LAMBDA: [[C_DEC_VAL:%.+]] = sdiv{{.*}} i{{[0-9]+}} [[C_VAL_FROM_CAP]], 1 + // LAMBDA: store i{{[0-9]+}} [[C_DEC_VAL]], i{{[0-9]+}}* [[C_REF_FROM_CAP]], + // ret + + [&]() { +#pragma omp target +#pragma omp teams private(g, sivar) + { + // LAMBDA: define{{.+}} @[[OMP_OFFLOADING]](i{{[0-9]+}}* {{.+}} [[G_IN:%.+]], i{{[0-9]+}} [[SIVAR_IN:%.+]] + // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_1:@.+]] to void + + // LAMBDA: define {{.+}} [[OMP_OUTLINED_1]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}} + // LAMBDA: [[G_LOC_OUTER:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_LOC_OUTER:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_LOC_OUTER]] + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_LOC_OUTER]] + // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@[^(]+]]([[CAP_1_TY]]* + // LAMBDA: ret + g = 1; + sivar = 2; + [&]() { + // LAMBDA: define {{.+}} [[INNER_LAMBDA]]([[CAP_1_TY]]* {{.+}}) + g = 2; + sivar = 4; + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* + }(); + } + }(); + return 0; +#else + S<float> test; + int t_var = 0; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> var(3); +#pragma omp target +#pragma omp teams private(t_var, vec, s_arr, var, sivar) + { + vec[0] = t_var; + s_arr[0] = var; + sivar = 3; + } + return tmain<int>(); +#endif +} + +// CHECK: define{{.*}} i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: [[OFF_IN:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* {{%.+}}, +// CHECK: call void @[[OMP_OFFLOADING:.+]](i{{[0-9]+}} [[OFF_IN]] +// CHECK: = call{{.*}} i{{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret + +// target region in main function +// CHECK: define{{.+}} @[[OMP_OFFLOADING]](i{{[0-9]+}} +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void + +// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: {{.+}}: +// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]* +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]]) +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: ret void + +// template tmain +// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call void [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, i{{[0-9]+}}{{.*}} 3) +// CHECK: call void [[OMP_OFFLOADING_TMAIN:@.+]]() + +// target in SS constructor +// CHECK: define{{.+}} [[OMP_OFFLOADING_SS:@.+]]([[SS_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[OMP_OUTLINED_SS:@.+]] to void + +// CHECK: define{{.*}} void [[OMP_OUTLINED_SS]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}}, [[SS_TY]]* +// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[A_REF:%.+]], +// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[C_REF:%.+]], +// CHECK: [[A_REF_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[A_REF]] +// CHECK: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_REF_VAL]] +// CHECK: [[A_INC:%.+]] = add{{.*}} i{{[0-9]+}} [[A_VAL]], 1 +// CHECK: store i{{[0-9]+}} [[A_INC]], i{{[0-9]+}}* [[A_REF_VAL]], +// CHECK: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]] +// CHECK: [[B_DEC:%.+]] = add{{.*}} i{{[0-9]+}} [[B_VAL]], -1 +// CHECK: store i{{[0-9]+}} [[B_DEC]], i{{[0-9]+}}* [[B_PRIV]], +// CHECK: [[C_REF_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_REF]] +// CHECK: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_REF_VAL]] +// CHECK: [[C_DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 +// CHECK: store i{{[0-9]+}} [[C_DIV]], i{{[0-9]+}}* [[C_REF_VAL]], +// CHECK: ret + +// target in tmain template +// CHECK: define{{.+}} [[OMP_OFFLOADING_TMAIN]]() +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_TMAIN:@.+]] to void + +// CHECK: define{{.*}} void [[OMP_OUTLINED_TMAIN]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128 +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], align 128 +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: {{.+}}: +// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]]) +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: ret + +// SST constructor +// CHECK: define{{.+}} [[SST_CONST:@.+]]([[SST_TY]]* {{.+}}) +// CHECK: call void [[OMP_OFFLOADING_SST:@.+]]([[SST_TY]]* {{.+}}) + +// target in SST constructor +// CHECK: define{{.+}} [[OMP_OFFLOADING_SST]]([[SST_TY]]* {{.+}}) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SST_TY]]*)* [[OMP_OUTLINED_SST:@.+]] to void + +// CHECK: define{{.+}} [[OMP_OUTLINED_SST]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* noalias %{{.+}}, [[SST_TY]]* {{.+}}) +// CHECK: [[A_PRIV_1:%.+]] = alloca i{{[0-9]+}}, +// CHECK: store i{{[0-9]+}}* [[A_PRIV_1]], i{{[0-9]+}}** [[A_REF_1:%.+]], +// CHECK: [[A_REF_VAL_1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[A_REF_1]] +// CHECK: [[A_VAL_1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_REF_VAL_1]] +// CHECK: [[A_INC_1:%.+]] = add{{.*}} i{{[0-9]+}} [[A_VAL_1]], 1 +// CHECK: store i{{[0-9]+}} [[A_INC_1]], i{{[0-9]+}}* [[A_REF_VAL_1]], +// CHECK: ret + +#endif + diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp index 87d03485c17b1..0420b010bb65b 100644 --- a/test/OpenMP/teams_reduction_messages.cpp +++ b/test/OpenMP/teams_reduction_messages.cpp @@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat extern S1 a; class S2 { mutable int a; - S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}} + S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}} public: S2() : a(0) {} @@ -22,7 +22,7 @@ public: static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} -S2 b; // expected-note 2 {{'b' defined here}} +S2 b; // expected-note 3 {{'b' defined here}} const S2 ba[5]; // expected-note 2 {{'ba' defined here}} class S3 { int a; @@ -34,7 +34,7 @@ public: S3 operator+(const S3 &arg1) { return arg1; } }; int operator+(const S3 &arg1, const S3 &arg2) { return 5; } -S3 c; // expected-note 2 {{'c' defined here}} +S3 c; // expected-note 3 {{'c' defined here}} const S3 ca[5]; // expected-note 2 {{'ca' defined here}} extern const int f; // expected-note 4 {{'f' declared here}} class S4 { @@ -56,9 +56,9 @@ class S5 { public: S5(int v) : a(v) {} }; -class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} +class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}} #if __cplusplus >= 201103L // C++11 or later -// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}} #endif int a; @@ -112,7 +112,7 @@ T tmain(T argc) { #pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} foo(); #pragma omp target #pragma omp teams reduction(&& : argc) @@ -121,22 +121,22 @@ T tmain(T argc) { #pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); #pragma omp target -#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target -#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} +#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -151,7 +151,7 @@ T tmain(T argc) { #pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(+ : o) // expected-error {{no viable overloaded '='}} +#pragma omp teams reduction(+ : o) // expected-error 2 {{no viable overloaded '='}} foo(); #pragma omp target #pragma omp teams private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} @@ -161,7 +161,7 @@ T tmain(T argc) { #pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} foo(); #pragma omp target -#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} +#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}} foo(); #pragma omp target #pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} @@ -175,6 +175,7 @@ T tmain(T argc) { #pragma omp teams #pragma omp parallel for private(fl) for (int i = 0; i < 10; ++i) + {} #pragma omp target #pragma omp teams reduction(+ : fl) foo(); @@ -182,6 +183,7 @@ T tmain(T argc) { #pragma omp teams #pragma omp parallel for reduction(- : fl) for (int i = 0; i < 10; ++i) + {} #pragma omp target #pragma omp teams reduction(+ : fl) foo(); @@ -258,13 +260,13 @@ int main(int argc, char **argv) { #pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -306,6 +308,7 @@ int main(int argc, char **argv) { #pragma omp teams #pragma omp parallel for private(fl) for (int i = 0; i < 10; ++i) + {} #pragma omp target #pragma omp teams reduction(+ : fl) foo(); @@ -313,6 +316,7 @@ int main(int argc, char **argv) { #pragma omp teams #pragma omp parallel for reduction(- : fl) for (int i = 0; i < 10; ++i) + {} #pragma omp target #pragma omp teams reduction(+ : fl) foo(); diff --git a/test/OpenMP/threadprivate_ast_print.cpp b/test/OpenMP/threadprivate_ast_print.cpp index 2d876c1909fa9..f789c2f277d34 100644 --- a/test/OpenMP/threadprivate_ast_print.cpp +++ b/test/OpenMP/threadprivate_ast_print.cpp @@ -69,4 +69,5 @@ int main () { return (foo<int>()); } +extern template int ST<int>::m; #endif diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp index 53d7ef7083850..273f0488220ce 100644 --- a/test/OpenMP/threadprivate_codegen.cpp +++ b/test/OpenMP/threadprivate_codegen.cpp @@ -221,7 +221,7 @@ static S1 gs1(5); // CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]], // CHECK-DEBUG: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] // CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]* -// CHECK-DEBUG-NEXT: call {{.*}} [[S1_CTOR:@.+]]([[S1]]* [[RES]], {{.*}} 5) +// CHECK-DEBUG-NEXT: call {{.*}} [[S1_CTOR:@.+]]([[S1]]* [[RES]], {{.*}} 5){{.*}}, !dbg // CHECK-DEBUG: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] // CHECK-DEBUG: ret i8* [[ARG]] // CHECK-DEBUG-NEXT: } @@ -230,7 +230,7 @@ static S1 gs1(5); // CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]], // CHECK-DEBUG: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] // CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]* -// CHECK-DEBUG-NEXT: call {{.*}} [[S1_DTOR:@.+]]([[S1]]* [[RES]]) +// CHECK-DEBUG-NEXT: call {{.*}} [[S1_DTOR:@.+]]([[S1]]* [[RES]]){{.*}}, !dbg // CHECK-DEBUG-NEXT: ret void // CHECK-DEBUG-NEXT: } // CHECK-DEBUG: define {{.*}} [[S1_DTOR]]([[S1]]* {{.*}}) @@ -617,7 +617,7 @@ int main() { // CHECK-DEBUG: call {{.*}} [[SMAIN_DTOR:@.+]]([[SMAIN]]* // CHECK-DEBUG: } // CHECK-DEBUG: define {{.*}} [[SMAIN_DTOR]]([[SMAIN]]* {{.*}}) -// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] { +// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS-NEXT: call void [[GS1_TLS_INIT]] // CHECK-TLS-NEXT: ret [[S1]]* [[GS1]] // CHECK-TLS-NEXT: } @@ -639,15 +639,15 @@ int main() { // CHECK-TLS: call void [[ARR_X_TLS_INIT]] // CHECK-TLS: ret [2 x [3 x [[S1]]]]* [[ARR_X]] // CHECK-TLS: } -// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] { +// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS: call void [[ST_INT_ST_TLS_INIT]] // CHECK-TLS: ret i32* [[ST_INT_ST]] // CHECK-TLS: } -// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] { +// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS: call void [[ST_FLOAT_ST_TLS_INIT]] // CHECK-TLS: ret float* [[ST_FLOAT_ST]] // CHECK-TLS: } -// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] { +// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS: call void [[ST_S4_ST_TLS_INIT]] // CHECK-TLS: ret [[S4]]* [[ST_S4_ST]] // CHECK-TLS: } @@ -948,5 +948,5 @@ int foobar() { // CHECK-TLS: call void [[ST_S4_ST_CXX_INIT]] // CHECK-TLS: [[DONE_LABEL]] -// CHECK-TLS: declare {{.*}} void [[GS3_TLS_INIT]] -// CHECK-TLS: declare {{.*}} void [[STATIC_S_TLS_INIT]] +// CHECK-TLS-DAG: declare {{.*}} void [[GS3_TLS_INIT]] +// CHECK-TLS-DAG: declare {{.*}} void [[STATIC_S_TLS_INIT]] diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp index 8c442f47ad5ee..9775bfa458f49 100644 --- a/test/OpenMP/threadprivate_messages.cpp +++ b/test/OpenMP/threadprivate_messages.cpp @@ -70,7 +70,7 @@ class TestClass { namespace ns { int m; -#pragma omp threadprivate (m) +#pragma omp threadprivate (m, m) } #pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}} #pragma omp threadprivate (ns::m) |