From 45b533945f0851ec234ca846e1af5ee1e4df0b6e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 30 Dec 2015 11:49:41 +0000 Subject: Vendor import of clang trunk r256633: https://llvm.org/svn/llvm-project/cfe/trunk@256633 --- test/OpenMP/atomic_capture_codegen.cpp | 5 +- test/OpenMP/atomic_codegen.cpp | 14 +- test/OpenMP/atomic_messages.cpp | 9 +- test/OpenMP/atomic_read_codegen.c | 5 +- test/OpenMP/atomic_update_codegen.cpp | 5 +- test/OpenMP/atomic_write_codegen.c | 5 +- test/OpenMP/cancel_ast_print.cpp | 8 +- test/OpenMP/cancel_codegen.cpp | 76 +- test/OpenMP/cancel_if_messages.cpp | 66 + test/OpenMP/cancellation_point_codegen.cpp | 73 + test/OpenMP/critical_ast_print.cpp | 28 +- test/OpenMP/critical_codegen.cpp | 33 +- test/OpenMP/critical_messages.cpp | 92 +- test/OpenMP/distribute_ast_print.cpp | 74 + test/OpenMP/distribute_collapse_messages.cpp | 83 + test/OpenMP/distribute_firstprivate_messages.cpp | 157 ++ test/OpenMP/distribute_private_messages.cpp | 132 ++ test/OpenMP/driver.c | 10 + test/OpenMP/flush_codegen.cpp | 2 +- test/OpenMP/for_ast_print.cpp | 42 +- test/OpenMP/for_codegen.cpp | 23 +- test/OpenMP/for_collapse_messages.cpp | 8 +- test/OpenMP/for_firstprivate_codegen.cpp | 92 +- test/OpenMP/for_firstprivate_messages.cpp | 20 +- test/OpenMP/for_lastprivate_codegen.cpp | 148 +- test/OpenMP/for_lastprivate_messages.cpp | 16 +- test/OpenMP/for_linear_codegen.cpp | 266 +++ test/OpenMP/for_linear_messages.cpp | 218 +++ test/OpenMP/for_loop_messages.cpp | 23 +- test/OpenMP/for_misc_messages.c | 11 +- test/OpenMP/for_ordered_clause.cpp | 120 ++ test/OpenMP/for_private_codegen.cpp | 79 +- test/OpenMP/for_private_messages.cpp | 12 +- test/OpenMP/for_reduction_codegen.cpp | 332 +++- test/OpenMP/for_reduction_messages.cpp | 59 +- test/OpenMP/for_schedule_messages.cpp | 54 +- test/OpenMP/for_simd_aligned_messages.cpp | 4 +- test/OpenMP/for_simd_ast_print.cpp | 16 +- test/OpenMP/for_simd_codegen.cpp | 13 +- test/OpenMP/for_simd_collapse_messages.cpp | 8 +- test/OpenMP/for_simd_firstprivate_messages.cpp | 16 +- test/OpenMP/for_simd_lastprivate_messages.cpp | 12 +- test/OpenMP/for_simd_linear_messages.cpp | 8 +- test/OpenMP/for_simd_loop_messages.cpp | 18 +- test/OpenMP/for_simd_misc_messages.c | 111 +- test/OpenMP/for_simd_private_messages.cpp | 12 +- test/OpenMP/for_simd_reduction_messages.cpp | 46 +- test/OpenMP/for_simd_safelen_messages.cpp | 8 +- test/OpenMP/for_simd_schedule_messages.cpp | 26 +- test/OpenMP/for_simd_simdlen_messages.cpp | 79 + test/OpenMP/function-attr.cpp | 54 + test/OpenMP/linking.c | 18 + test/OpenMP/master_codegen.cpp | 2 +- test/OpenMP/nesting_of_regions.cpp | 2033 +++++++++++++++----- test/OpenMP/openmp_check.cpp | 15 + test/OpenMP/ordered_ast_print.cpp | 156 +- test/OpenMP/ordered_codegen.cpp | 21 +- test/OpenMP/ordered_messages.cpp | 213 +- test/OpenMP/parallel_ast_print.cpp | 47 +- test/OpenMP/parallel_codegen.cpp | 90 +- test/OpenMP/parallel_copyin_codegen.cpp | 215 +-- test/OpenMP/parallel_firstprivate_codegen.cpp | 191 +- test/OpenMP/parallel_firstprivate_messages.cpp | 6 +- test/OpenMP/parallel_for_ast_print.cpp | 48 +- test/OpenMP/parallel_for_codegen.cpp | 63 +- test/OpenMP/parallel_for_collapse_messages.cpp | 8 +- test/OpenMP/parallel_for_firstprivate_messages.cpp | 15 +- test/OpenMP/parallel_for_if_messages.cpp | 28 + test/OpenMP/parallel_for_lastprivate_messages.cpp | 20 +- test/OpenMP/parallel_for_linear_codegen.cpp | 249 +++ test/OpenMP/parallel_for_linear_messages.cpp | 269 +++ test/OpenMP/parallel_for_loop_messages.cpp | 19 +- test/OpenMP/parallel_for_misc_messages.c | 14 +- test/OpenMP/parallel_for_num_threads_messages.cpp | 6 +- test/OpenMP/parallel_for_ordered_messages.cpp | 104 + test/OpenMP/parallel_for_private_messages.cpp | 12 +- test/OpenMP/parallel_for_reduction_messages.cpp | 52 +- test/OpenMP/parallel_for_schedule_messages.cpp | 26 +- test/OpenMP/parallel_for_simd_aligned_messages.cpp | 4 +- test/OpenMP/parallel_for_simd_ast_print.cpp | 28 +- test/OpenMP/parallel_for_simd_codegen.cpp | 21 +- .../OpenMP/parallel_for_simd_collapse_messages.cpp | 8 +- .../parallel_for_simd_firstprivate_messages.cpp | 12 +- test/OpenMP/parallel_for_simd_if_messages.cpp | 28 + .../parallel_for_simd_lastprivate_messages.cpp | 16 +- test/OpenMP/parallel_for_simd_linear_messages.cpp | 8 +- test/OpenMP/parallel_for_simd_loop_messages.cpp | 18 +- test/OpenMP/parallel_for_simd_misc_messages.c | 109 +- .../parallel_for_simd_num_threads_messages.cpp | 6 +- test/OpenMP/parallel_for_simd_private_messages.cpp | 12 +- .../parallel_for_simd_reduction_messages.cpp | 52 +- test/OpenMP/parallel_for_simd_safelen_messages.cpp | 8 +- .../OpenMP/parallel_for_simd_schedule_messages.cpp | 26 +- test/OpenMP/parallel_for_simd_simdlen_messages.cpp | 79 + test/OpenMP/parallel_if_codegen.cpp | 16 +- test/OpenMP/parallel_if_messages.cpp | 14 + test/OpenMP/parallel_num_threads_messages.cpp | 6 +- test/OpenMP/parallel_private_codegen.cpp | 72 +- test/OpenMP/parallel_private_messages.cpp | 11 +- test/OpenMP/parallel_reduction_codegen.cpp | 177 +- test/OpenMP/parallel_reduction_messages.cpp | 51 +- test/OpenMP/parallel_sections_ast_print.cpp | 8 +- test/OpenMP/parallel_sections_codegen.cpp | 7 +- .../parallel_sections_firstprivate_messages.cpp | 13 +- test/OpenMP/parallel_sections_if_messages.cpp | 48 + .../parallel_sections_lastprivate_messages.cpp | 17 +- .../parallel_sections_num_threads_messages.cpp | 6 +- test/OpenMP/parallel_sections_private_messages.cpp | 13 +- .../parallel_sections_reduction_messages.cpp | 53 +- test/OpenMP/sections_codegen.cpp | 3 +- test/OpenMP/sections_firstprivate_codegen.cpp | 88 +- test/OpenMP/sections_firstprivate_messages.cpp | 17 +- test/OpenMP/sections_lastprivate_codegen.cpp | 135 +- test/OpenMP/sections_lastprivate_messages.cpp | 13 +- test/OpenMP/sections_private_codegen.cpp | 60 +- test/OpenMP/sections_private_messages.cpp | 13 +- test/OpenMP/sections_reduction_codegen.cpp | 71 +- test/OpenMP/sections_reduction_messages.cpp | 47 +- test/OpenMP/simd_aligned_messages.cpp | 4 +- test/OpenMP/simd_ast_print.cpp | 24 +- test/OpenMP/simd_codegen.cpp | 137 +- test/OpenMP/simd_collapse_messages.cpp | 8 +- test/OpenMP/simd_lastprivate_messages.cpp | 12 +- test/OpenMP/simd_linear_messages.cpp | 56 +- test/OpenMP/simd_loop_messages.cpp | 18 +- test/OpenMP/simd_metadata.c | 67 + test/OpenMP/simd_misc_messages.c | 133 +- test/OpenMP/simd_private_messages.cpp | 8 +- test/OpenMP/simd_reduction_messages.cpp | 42 +- test/OpenMP/simd_safelen_messages.cpp | 8 +- test/OpenMP/simd_simdlen_messages.cpp | 79 + test/OpenMP/single_codegen.cpp | 7 +- test/OpenMP/single_firstprivate_codegen.cpp | 73 +- test/OpenMP/single_firstprivate_messages.cpp | 15 +- test/OpenMP/single_private_codegen.cpp | 51 +- test/OpenMP/single_private_messages.cpp | 11 +- test/OpenMP/target_ast_print.cpp | 72 +- test/OpenMP/target_codegen.cpp | 652 +++++++ test/OpenMP/target_codegen_global_capture.cpp | 287 +++ test/OpenMP/target_data_ast_print.cpp | 173 ++ test/OpenMP/target_data_device_messages.cpp | 28 + test/OpenMP/target_data_if_messages.cpp | 32 + test/OpenMP/target_data_messages.c | 27 + test/OpenMP/target_device_messages.cpp | 28 + test/OpenMP/target_if_messages.cpp | 12 + test/OpenMP/target_map_codegen.cpp | 1015 ++++++++++ test/OpenMP/target_map_messages.cpp | 207 ++ test/OpenMP/task_ast_print.cpp | 37 +- test/OpenMP/task_codegen.cpp | 156 +- test/OpenMP/task_depend_messages.cpp | 23 +- test/OpenMP/task_firstprivate_codegen.cpp | 127 +- test/OpenMP/task_firstprivate_messages.cpp | 6 +- test/OpenMP/task_if_codegen.cpp | 10 +- test/OpenMP/task_if_messages.cpp | 12 + test/OpenMP/task_messages.cpp | 28 +- test/OpenMP/task_priority_messages.cpp | 47 + test/OpenMP/task_private_codegen.cpp | 89 +- test/OpenMP/task_private_messages.cpp | 11 +- test/OpenMP/taskgroup_codegen.cpp | 2 +- test/OpenMP/taskloop_ast_print.cpp | 74 + test/OpenMP/taskloop_collapse_messages.cpp | 83 + test/OpenMP/taskloop_final_messages.cpp | 90 + test/OpenMP/taskloop_firstprivate_messages.cpp | 313 +++ test/OpenMP/taskloop_grainsize_messages.cpp | 99 + test/OpenMP/taskloop_lastprivate_messages.cpp | 287 +++ test/OpenMP/taskloop_loop_messages.cpp | 738 +++++++ test/OpenMP/taskloop_misc_messages.c | 373 ++++ test/OpenMP/taskloop_num_tasks_messages.cpp | 99 + test/OpenMP/taskloop_priority_messages.cpp | 93 + test/OpenMP/taskloop_private_messages.cpp | 195 ++ test/OpenMP/taskloop_simd_aligned_messages.cpp | 202 ++ test/OpenMP/taskloop_simd_ast_print.cpp | 75 + test/OpenMP/taskloop_simd_collapse_messages.cpp | 83 + test/OpenMP/taskloop_simd_final_messages.cpp | 90 + .../OpenMP/taskloop_simd_firstprivate_messages.cpp | 313 +++ test/OpenMP/taskloop_simd_grainsize_messages.cpp | 99 + test/OpenMP/taskloop_simd_lastprivate_messages.cpp | 287 +++ test/OpenMP/taskloop_simd_linear_messages.cpp | 249 +++ test/OpenMP/taskloop_simd_loop_messages.cpp | 739 +++++++ test/OpenMP/taskloop_simd_misc_messages.c | 372 ++++ test/OpenMP/taskloop_simd_num_tasks_messages.cpp | 99 + test/OpenMP/taskloop_simd_priority_messages.cpp | 93 + test/OpenMP/taskloop_simd_private_messages.cpp | 195 ++ test/OpenMP/taskloop_simd_safelen_messages.cpp | 79 + test/OpenMP/taskloop_simd_simdlen_messages.cpp | 79 + test/OpenMP/teams_ast_print.cpp | 12 +- test/OpenMP/teams_firstprivate_messages.cpp | 8 +- test/OpenMP/teams_num_teams_messages.cpp | 111 ++ test/OpenMP/teams_private_messages.cpp | 12 +- test/OpenMP/teams_reduction_messages.cpp | 52 +- test/OpenMP/teams_thread_limit_messages.cpp | 111 ++ test/OpenMP/threadprivate_codegen.cpp | 18 +- test/OpenMP/threadprivate_messages.cpp | 5 +- 193 files changed, 15741 insertions(+), 2085 deletions(-) create mode 100644 test/OpenMP/cancel_if_messages.cpp create mode 100644 test/OpenMP/distribute_ast_print.cpp create mode 100644 test/OpenMP/distribute_collapse_messages.cpp create mode 100644 test/OpenMP/distribute_firstprivate_messages.cpp create mode 100644 test/OpenMP/distribute_private_messages.cpp create mode 100644 test/OpenMP/driver.c create mode 100644 test/OpenMP/for_linear_codegen.cpp create mode 100644 test/OpenMP/for_linear_messages.cpp create mode 100644 test/OpenMP/for_ordered_clause.cpp create mode 100644 test/OpenMP/for_simd_simdlen_messages.cpp create mode 100644 test/OpenMP/function-attr.cpp create mode 100644 test/OpenMP/openmp_check.cpp create mode 100644 test/OpenMP/parallel_for_linear_codegen.cpp create mode 100644 test/OpenMP/parallel_for_linear_messages.cpp create mode 100644 test/OpenMP/parallel_for_ordered_messages.cpp create mode 100644 test/OpenMP/parallel_for_simd_simdlen_messages.cpp create mode 100644 test/OpenMP/simd_simdlen_messages.cpp create mode 100644 test/OpenMP/target_codegen.cpp create mode 100644 test/OpenMP/target_codegen_global_capture.cpp create mode 100644 test/OpenMP/target_data_ast_print.cpp create mode 100644 test/OpenMP/target_data_device_messages.cpp create mode 100644 test/OpenMP/target_data_if_messages.cpp create mode 100644 test/OpenMP/target_data_messages.c create mode 100644 test/OpenMP/target_device_messages.cpp create mode 100644 test/OpenMP/target_map_codegen.cpp create mode 100644 test/OpenMP/target_map_messages.cpp create mode 100644 test/OpenMP/task_priority_messages.cpp create mode 100644 test/OpenMP/taskloop_ast_print.cpp create mode 100644 test/OpenMP/taskloop_collapse_messages.cpp create mode 100644 test/OpenMP/taskloop_final_messages.cpp create mode 100644 test/OpenMP/taskloop_firstprivate_messages.cpp create mode 100644 test/OpenMP/taskloop_grainsize_messages.cpp create mode 100644 test/OpenMP/taskloop_lastprivate_messages.cpp create mode 100644 test/OpenMP/taskloop_loop_messages.cpp create mode 100644 test/OpenMP/taskloop_misc_messages.c create mode 100644 test/OpenMP/taskloop_num_tasks_messages.cpp create mode 100644 test/OpenMP/taskloop_priority_messages.cpp create mode 100644 test/OpenMP/taskloop_private_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_aligned_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_ast_print.cpp create mode 100644 test/OpenMP/taskloop_simd_collapse_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_final_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_firstprivate_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_grainsize_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_lastprivate_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_linear_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_loop_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_misc_messages.c create mode 100644 test/OpenMP/taskloop_simd_num_tasks_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_priority_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_private_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_safelen_messages.cpp create mode 100644 test/OpenMP/taskloop_simd_simdlen_messages.cpp create mode 100644 test/OpenMP/teams_num_teams_messages.cpp create mode 100644 test/OpenMP/teams_thread_limit_messages.cpp (limited to 'test/OpenMP') diff --git a/test/OpenMP/atomic_capture_codegen.cpp b/test/OpenMP/atomic_capture_codegen.cpp index 6dd9f7ab2a41..f91da3e80f54 100644 --- a/test/OpenMP/atomic_capture_codegen.cpp +++ b/test/OpenMP/atomic_capture_codegen.cpp @@ -72,7 +72,10 @@ struct BitFields4_packed { typedef float float2 __attribute__((ext_vector_type(2))); float2 float2x; -register int rix __asm__("0"); +// Register "0" is currently an invalid register for global register variables. +// Use "esp" instead of "0". +// register int rix __asm__("0"); +register int rix __asm__("esp"); int main() { // CHECK: [[PREV:%.+]] = atomicrmw add i8* @{{.+}}, i8 1 monotonic diff --git a/test/OpenMP/atomic_codegen.cpp b/test/OpenMP/atomic_codegen.cpp index 2ce1f9450b3f..536f2cdffafb 100644 --- a/test/OpenMP/atomic_codegen.cpp +++ b/test/OpenMP/atomic_codegen.cpp @@ -1,11 +1,12 @@ // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 // expected-no-diagnostics int a; int b; struct St { + unsigned long field; St() {} ~St() {} int &get() { return a; } @@ -13,6 +14,7 @@ struct St { // CHECK-LABEL: parallel_atomic_ewc void parallel_atomic_ewc() { + St s; #pragma omp parallel { // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) @@ -47,6 +49,8 @@ void parallel_atomic_ewc() { // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) #pragma omp atomic St().get() %= b; +#pragma omp atomic + s.field++; // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) // CHECK: [[B_VAL:%.+]] = load i32, i32* @b @@ -108,7 +112,7 @@ void parallel_atomic() { // TERM_DEBUG: call void @__clang_call_terminate // TERM_DEBUG: unreachable } -// TERM_DEBUG-DAG: [[READ_LOC]] = !DILocation(line: [[@LINE-33]], -// TERM_DEBUG-DAG: [[WRITE_LOC]] = !DILocation(line: [[@LINE-28]], -// TERM_DEBUG-DAG: [[UPDATE_LOC]] = !DILocation(line: [[@LINE-22]], -// TERM_DEBUG-DAG: [[CAPTURE_LOC]] = !DILocation(line: [[@LINE-16]], +// TERM_DEBUG-DAG: [[READ_LOC]] = !DILocation(line: [[@LINE-28]], +// TERM_DEBUG-DAG: [[WRITE_LOC]] = !DILocation(line: [[@LINE-22]], +// TERM_DEBUG-DAG: [[UPDATE_LOC]] = !DILocation(line: [[@LINE-16]], +// TERM_DEBUG-DAG: [[CAPTURE_LOC]] = !DILocation(line: [[@LINE-9]], diff --git a/test/OpenMP/atomic_messages.cpp b/test/OpenMP/atomic_messages.cpp index c3e02bc96e86..7f78ad443da6 100644 --- a/test/OpenMP/atomic_messages.cpp +++ b/test/OpenMP/atomic_messages.cpp @@ -48,8 +48,8 @@ T read() { // expected-note@+1 {{expected built-in assignment operator}} foo(); #pragma omp atomic read - // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} - // expected-note@+1 {{expected built-in assignment operator}} + // expected-error@+2 2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 2 {{expected built-in assignment operator}} a += b; #pragma omp atomic read // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} @@ -93,7 +93,8 @@ int read() { #pragma omp atomic read read a = b; - // expected-note@+1 {{in instantiation of function template specialization 'read' requested here}} + // expected-note@+2 {{in instantiation of function template specialization 'read' requested here}} + // expected-note@+1 {{in instantiation of function template specialization 'read' requested here}} return read() + read().a; } @@ -147,6 +148,7 @@ int write() { #pragma omp atomic write a = foo(); + // expected-note@+1 {{in instantiation of function template specialization 'write' requested here}} return write(); } @@ -672,6 +674,7 @@ int capture() { #pragma omp atomic capture capture b = a /= b; + // expected-note@+1 {{in instantiation of function template specialization 'capture' requested here}} return capture(); } diff --git a/test/OpenMP/atomic_read_codegen.c b/test/OpenMP/atomic_read_codegen.c index fc47c82d8913..0cd46e3821fd 100644 --- a/test/OpenMP/atomic_read_codegen.c +++ b/test/OpenMP/atomic_read_codegen.c @@ -72,7 +72,10 @@ struct BitFields4_packed { typedef float float2 __attribute__((ext_vector_type(2))); float2 float2x; -register int rix __asm__("0"); +// Register "0" is currently an invalid register for global register variables. +// Use "esp" instead of "0". +// register int rix __asm__("0"); +register int rix __asm__("esp"); int main() { // CHECK: load atomic i8, i8* diff --git a/test/OpenMP/atomic_update_codegen.cpp b/test/OpenMP/atomic_update_codegen.cpp index df8b538ee165..063b76d7ff54 100644 --- a/test/OpenMP/atomic_update_codegen.cpp +++ b/test/OpenMP/atomic_update_codegen.cpp @@ -72,7 +72,10 @@ struct BitFields4_packed { typedef float float2 __attribute__((ext_vector_type(2))); float2 float2x; -register int rix __asm__("0"); +// Register "0" is currently an invalid register for global register variables. +// Use "esp" instead of "0". +// register int rix __asm__("0"); +register int rix __asm__("esp"); int main() { // CHECK-NOT: atomicrmw diff --git a/test/OpenMP/atomic_write_codegen.c b/test/OpenMP/atomic_write_codegen.c index 1ee26b078212..66172af07e8f 100644 --- a/test/OpenMP/atomic_write_codegen.c +++ b/test/OpenMP/atomic_write_codegen.c @@ -72,7 +72,10 @@ struct BitFields4_packed { typedef float float2 __attribute__((ext_vector_type(2))); float2 float2x; -register int rix __asm__("0"); +// Register "0" is currently an invalid register for global register variables. +// Use "esp" instead of "0". +// register int rix __asm__("0"); +register int rix __asm__("esp"); int main() { // CHECK: load i8, i8* diff --git a/test/OpenMP/cancel_ast_print.cpp b/test/OpenMP/cancel_ast_print.cpp index f244c784e86e..007237a7fb98 100644 --- a/test/OpenMP/cancel_ast_print.cpp +++ b/test/OpenMP/cancel_ast_print.cpp @@ -10,11 +10,11 @@ int main (int argc, char **argv) { // CHECK: int main(int argc, char **argv) { #pragma omp parallel { -#pragma omp cancel parallel +#pragma omp cancel parallel if(argc) } // CHECK: #pragma omp parallel // CHECK-NEXT: { -// CHECK-NEXT: #pragma omp cancel parallel +// CHECK-NEXT: #pragma omp cancel parallel if(argc) // CHECK-NEXT: } #pragma omp sections { @@ -26,11 +26,11 @@ int main (int argc, char **argv) { // CHECK: } #pragma omp for for (int i = 0; i < argc; ++i) { -#pragma omp cancel for +#pragma omp cancel for if(cancel:argc) } // CHECK: #pragma omp for // CHECK-NEXT: for (int i = 0; i < argc; ++i) { -// CHECK-NEXT: #pragma omp cancel for +// CHECK-NEXT: #pragma omp cancel for if(cancel: argc) // CHECK-NEXT: } #pragma omp task { diff --git a/test/OpenMP/cancel_codegen.cpp b/test/OpenMP/cancel_codegen.cpp index 4bd85a22b1d9..e2dd3673caff 100644 --- a/test/OpenMP/cancel_codegen.cpp +++ b/test/OpenMP/cancel_codegen.cpp @@ -6,11 +6,12 @@ #ifndef HEADER #define HEADER +float flag; int main (int argc, char **argv) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( #pragma omp parallel { -#pragma omp cancel parallel +#pragma omp cancel parallel if(flag) argv[0][0] = argc; } // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( @@ -50,9 +51,13 @@ int main (int argc, char **argv) { // CHECK: call void @__kmpc_for_static_fini( #pragma omp for for (int i = 0; i < argc; ++i) { -#pragma omp cancel for +#pragma omp cancel for if(cancel: flag) } // CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[FLAG:%.+]] = load float, float* @{{.+}}, +// CHECK: [[BOOL:%.+]] = fcmp une float [[FLAG]], 0.000000e+00 +// CHECK: br i1 [[BOOL]], label %[[THEN:[^,]+]], label %[[ELSE:[^,]+]] +// CHECK: [[THEN]] // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2) // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] @@ -61,6 +66,8 @@ for (int i = 0; i < argc; ++i) { // CHECK: br label // CHECK: [[CONTINUE]] // CHECK: br label +// CHECK: [[ELSE]] +// CHECK: br label // CHECK: call void @__kmpc_for_static_fini( // CHECK: call void @__kmpc_barrier(%ident_t* #pragma omp task @@ -69,16 +76,41 @@ for (int i = 0; i < argc; ++i) { } // CHECK: call i8* @__kmpc_omp_task_alloc( // CHECK: call i32 @__kmpc_omp_task( +#pragma omp parallel sections +{ +#pragma omp cancel sections +} +// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( +#pragma omp parallel sections +{ +#pragma omp cancel sections +#pragma omp section + { +#pragma omp cancel sections + } +} +// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( +#pragma omp parallel for +for (int i = 0; i < argc; ++i) { +#pragma omp cancel for +} +// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( return argc; } // CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}, +// CHECK: [[FLAG:%.+]] = load float, float* @{{.+}}, +// CHECK: [[BOOL:%.+]] = fcmp une float [[FLAG]], 0.000000e+00 +// CHECK: br i1 [[BOOL]], label %[[THEN:[^,]+]], label %[[ELSE:[^,]+]] +// CHECK: [[THEN]] // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 1) // CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 // CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]], // CHECK: [[EXIT]] // CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* // CHECK: br label %[[RETURN:.+]] +// CHECK: [[ELSE]] +// CHECK: br label // CHECK: [[RETURN]] // CHECK: ret void @@ -92,4 +124,44 @@ for (int i = 0; i < argc; ++i) { // CHECK: [[RETURN]] // CHECK: ret i32 0 +// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}) +// CHECK: call i32 @__kmpc_single( +// CHECK-NOT: @__kmpc_cancel +// CHECK: call void @__kmpc_end_single( +// CHECK: ret void + +// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}) +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 3) +// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] +// CHECK: [[EXIT]] +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* +// CHECK: br label +// CHECK: [[CONTINUE]] +// CHECK: br label +// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3) +// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] +// CHECK: [[EXIT]] +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* +// CHECK: br label +// CHECK: [[CONTINUE]] +// CHECK: br label +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: ret void + +// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}, +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 2) +// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] +// CHECK: [[EXIT]] +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* +// CHECK: br label +// CHECK: [[CONTINUE]] +// CHECK: br label +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: ret void + #endif diff --git a/test/OpenMP/cancel_if_messages.cpp b/test/OpenMP/cancel_if_messages.cpp new file mode 100644 index 000000000000..8d1afc9ecddf --- /dev/null +++ b/test/OpenMP/cancel_if_messages.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp parallel + { + #pragma omp cancel parallel if // expected-error {{expected '(' after 'if'}} + #pragma omp cancel parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if () // expected-error {{expected expression}} + #pragma omp cancel parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}} + #pragma omp cancel parallel if (argc > 0 ? argv[1] : argv[2]) + #pragma omp cancel parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause}} + #pragma omp cancel parallel if (S) // expected-error {{'S' does not refer to a value}} + #pragma omp cancel parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(argc) + #pragma omp cancel parallel if(cancel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel : argc) + #pragma omp cancel parallel if(cancel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp cancel'}} + #pragma omp cancel parallel if(cancel : argc) if (cancel:argc) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause with 'cancel' name modifier}} + #pragma omp cancel parallel if(cancel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + } + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp parallel + { + #pragma omp cancel parallel if // expected-error {{expected '(' after 'if'}} + #pragma omp cancel parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if () // expected-error {{expected expression}} + #pragma omp cancel parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}} + #pragma omp cancel parallel if (argc > 0 ? argv[1] : argv[2]) + #pragma omp cancel parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause}} + #pragma omp cancel parallel if (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp cancel parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp cancel parallel if(cancel : argc) + #pragma omp cancel parallel if(cancel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp cancel'}} + #pragma omp cancel parallel if(cancel : argc) if (cancel:argc) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause with 'cancel' name modifier}} + #pragma omp cancel parallel if(cancel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + foo(); + } + + return tmain(argc, argv); +} diff --git a/test/OpenMP/cancellation_point_codegen.cpp b/test/OpenMP/cancellation_point_codegen.cpp index 453393082ce8..795f69ed24fa 100644 --- a/test/OpenMP/cancellation_point_codegen.cpp +++ b/test/OpenMP/cancellation_point_codegen.cpp @@ -11,12 +11,16 @@ int main (int argc, char **argv) { #pragma omp parallel { #pragma omp cancellation point parallel +#pragma omp cancel parallel argv[0][0] = argc; } // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( #pragma omp sections { + { #pragma omp cancellation point sections +#pragma omp cancel sections + } } // CHECK: call i32 @__kmpc_single( // CHECK-NOT: @__kmpc_cancellationpoint @@ -28,6 +32,7 @@ int main (int argc, char **argv) { #pragma omp section { #pragma omp cancellation point sections +#pragma omp cancel sections } } // CHECK: call void @__kmpc_for_static_init_4( @@ -51,6 +56,7 @@ int main (int argc, char **argv) { #pragma omp for for (int i = 0; i < argc; ++i) { #pragma omp cancellation point for +#pragma omp cancel for } // CHECK: call void @__kmpc_for_static_init_4( // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2) @@ -66,9 +72,36 @@ for (int i = 0; i < argc; ++i) { #pragma omp task { #pragma omp cancellation point taskgroup +#pragma omp cancel taskgroup } // CHECK: call i8* @__kmpc_omp_task_alloc( // CHECK: call i32 @__kmpc_omp_task( +#pragma omp parallel sections +{ + { +#pragma omp cancellation point sections +#pragma omp cancel sections + } +} +// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( +#pragma omp parallel sections +{ + { +#pragma omp cancellation point sections +#pragma omp cancel sections + } +#pragma omp section + { +#pragma omp cancellation point sections + } +} +// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( +#pragma omp parallel for +for (int i = 0; i < argc; ++i) { +#pragma omp cancellation point for +#pragma omp cancel for +} +// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( return argc; } @@ -92,4 +125,44 @@ for (int i = 0; i < argc; ++i) { // CHECK: [[RETURN]] // CHECK: ret i32 0 +// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}) +// CHECK: call i32 @__kmpc_single( +// CHECK-NOT: @__kmpc_cancellationpoint +// CHECK: call void @__kmpc_end_single( +// CHECK: ret void + +// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}) +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 3) +// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] +// CHECK: [[EXIT]] +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* +// CHECK: br label +// CHECK: [[CONTINUE]] +// CHECK: br label +// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3) +// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] +// CHECK: [[EXIT]] +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* +// CHECK: br label +// CHECK: [[CONTINUE]] +// CHECK: br label +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: ret void + +// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}}, +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 2) +// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]] +// CHECK: [[EXIT]] +// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* +// CHECK: br label +// CHECK: [[CONTINUE]] +// CHECK: br label +// CHECK: call void @__kmpc_for_static_fini( +// CHECK: ret void + #endif diff --git a/test/OpenMP/critical_ast_print.cpp b/test/OpenMP/critical_ast_print.cpp index 87a1fe0bcee7..7189fddd7186 100644 --- a/test/OpenMP/critical_ast_print.cpp +++ b/test/OpenMP/critical_ast_print.cpp @@ -8,6 +8,26 @@ void foo() {} +// CHECK: template int tmain(T argc, char **argv) +template +int tmain (T argc, char **argv) { + T b = argc, c, d, e, f, g; + static int a; +// CHECK: static int a; +#pragma omp critical + a=2; +// CHECK-NEXT: #pragma omp critical +// CHECK-NEXT: a = 2; +// CHECK-NEXT: ++a; + ++a; +#pragma omp critical (the_name) hint(N) + foo(); +// CHECK-NEXT: #pragma omp critical (the_name) hint(N) +// CHECK-NEXT: foo(); +// CHECK-NEXT: return N; + return N; +} + int main (int argc, char **argv) { int b = argc, c, d, e, f, g; static int a; @@ -18,12 +38,12 @@ int main (int argc, char **argv) { // CHECK-NEXT: a = 2; // CHECK-NEXT: ++a; ++a; -#pragma omp critical (the_name) +#pragma omp critical (the_name1) hint(23) foo(); -// CHECK-NEXT: #pragma omp critical (the_name) +// CHECK-NEXT: #pragma omp critical (the_name1) hint(23) // CHECK-NEXT: foo(); -// CHECK-NEXT: return 0; - return 0; +// CHECK-NEXT: return tmain(a, argv); + return tmain(a, argv); } #endif diff --git a/test/OpenMP/critical_codegen.cpp b/test/OpenMP/critical_codegen.cpp index 5cf3446d9f5f..e44e2202e9a2 100644 --- a/test/OpenMP/critical_codegen.cpp +++ b/test/OpenMP/critical_codegen.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -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 -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 // expected-no-diagnostics // REQUIRES: x86-registered-target #ifndef HEADER @@ -10,6 +10,7 @@ // CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } // CHECK: [[UNNAMED_LOCK:@.+]] = common global [8 x i32] zeroinitializer // CHECK: [[THE_NAME_LOCK:@.+]] = common global [8 x i32] zeroinitializer +// CHECK: [[THE_NAME_LOCK1:@.+]] = common global [8 x i32] zeroinitializer // CHECK: define {{.*}}void [[FOO:@.+]]() @@ -32,11 +33,41 @@ int main() { // CHECK: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]]) #pragma omp critical(the_name) foo(); +// CHECK: call {{.*}}void @__kmpc_critical_with_hint([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]], i{{64|32}} 23) +// CHECK-NEXT: invoke {{.*}}void [[FOO]]() +// CHECK: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]]) +#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-NOT: call {{.*}}void @__kmpc_end_critical( + if (a) +#pragma omp critical(the_name) + while (1) + ; +// CHECK: call {{.*}}void [[FOO]]() + foo(); // CHECK-NOT: call void @__kmpc_critical // CHECK-NOT: call void @__kmpc_end_critical return a; } +struct S { + int a; +}; +// CHECK-LABEL: critical_ref +void critical_ref(S &s) { + // CHECK: [[S_ADDR:%.+]] = alloca %struct.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: call void @__kmpc_critical( +#pragma omp critical + // 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: call void @__kmpc_end_critical( +} + // CHECK-LABEL: parallel_critical // TERM_DEBUG-LABEL: parallel_critical void parallel_critical() { diff --git a/test/OpenMP/critical_messages.cpp b/test/OpenMP/critical_messages.cpp index e3f2ad70fe98..bb5ec00fdbf1 100644 --- a/test/OpenMP/critical_messages.cpp +++ b/test/OpenMP/critical_messages.cpp @@ -2,20 +2,21 @@ int foo(); -int main() { +template +int tmain(int argc, char **argv) { // expected-note {{declared here}} #pragma omp critical ; #pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}} #pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}} #pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp critical (name // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp critical (name2 // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp critical (name1) foo(); { #pragma omp critical } // expected-error {{expected statement}} - #pragma omp critical (name) // expected-note {{previous 'critical' region starts here}} + #pragma omp critical (name2) // expected-note {{previous 'critical' region starts here}} #pragma omp critical for (int i = 0; i < 10; ++i) { foo(); @@ -23,11 +24,11 @@ int main() { #pragma omp for for (int j = 0; j < 10; j++) { foo(); - #pragma omp critical(name) // expected-error {{cannot nest 'critical' regions having the same name 'name'}} + #pragma omp critical(name2) // expected-error {{cannot nest 'critical' regions having the same name 'name2'}} foo(); } } - #pragma omp critical (name) + #pragma omp critical (name2) #pragma omp critical for (int i = 0; i < 10; ++i) { foo(); @@ -38,7 +39,7 @@ int main() { foo(); } } - #pragma omp critical (name) + #pragma omp critical (name2) #pragma omp critical for (int i = 0; i < 10; ++i) { foo(); @@ -50,9 +51,86 @@ int main() { } } + #pragma omp critical (name2) hint // expected-error {{expected '(' after 'hint'}} + foo(); + #pragma omp critical (name2) hint( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp critical (name2) hint(+ // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp critical (name2) hint(argc) // expected-error {{expression is not an integral constant expression}} expected-note {{read of non-const variable 'argc' is not allowed in a constant expression}} + foo(); + #pragma omp critical (name) hint(N) // expected-error {{argument to 'hint' clause must be a strictly positive integer value}} expected-error {{constructs with the same name must have a 'hint' clause with the same value}} expected-note {{'hint' clause with value '4'}} + foo(); + #pragma omp critical hint(N) // expected-error {{the name of the construct must be specified in presence of 'hint' clause}} + foo(); return 0; } +int main(int argc, char **argv) { // expected-note {{declared here}} + #pragma omp critical + ; + #pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}} + #pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}} + #pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp critical (name2 // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp critical (name1) + foo(); + { + #pragma omp critical + } // expected-error {{expected statement}} + #pragma omp critical (name2) // expected-note {{previous 'critical' region starts here}} + #pragma omp critical + for (int i = 0; i < 10; ++i) { + foo(); + #pragma omp parallel + #pragma omp for + for (int j = 0; j < 10; j++) { + foo(); + #pragma omp critical(name2) // expected-error {{cannot nest 'critical' regions having the same name 'name2'}} + foo(); + } + } + #pragma omp critical (name2) + #pragma omp critical + for (int i = 0; i < 10; ++i) { + foo(); + #pragma omp parallel + #pragma omp for + for (int j = 0; j < 10; j++) { + #pragma omp critical + foo(); + } + } + #pragma omp critical (name2) + #pragma omp critical + for (int i = 0; i < 10; ++i) { + foo(); + #pragma omp parallel + #pragma omp for + for (int j = 0; j < 10; j++) { + #pragma omp critical (nam) + foo(); + } + } + + #pragma omp critical (name2) hint // expected-error {{expected '(' after 'hint'}} + foo(); + #pragma omp critical (name2) hint( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp critical (name2) hint(+ // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp critical (name2) hint(argc) // expected-error {{expression is not an integral constant expression}} expected-note {{read of non-const variable 'argc' is not allowed in a constant expression}} + foo(); + #pragma omp critical (name) hint(23) // expected-note {{previous 'hint' clause with value '23'}} + foo(); + #pragma omp critical hint(-5) // expected-error {{argument to 'hint' clause must be a strictly positive integer value}} + foo(); + #pragma omp critical hint(1) // expected-error {{the name of the construct must be specified in presence of 'hint' clause}} + foo(); + return tmain(argc, argv) + tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} +} + int foo() { L1: foo(); @@ -69,4 +147,4 @@ int foo() { } return 0; -} + } diff --git a/test/OpenMP/distribute_ast_print.cpp b/test/OpenMP/distribute_ast_print.cpp new file mode 100644 index 000000000000..c3a175a5e5e8 --- /dev/null +++ b/test/OpenMP/distribute_ast_print.cpp @@ -0,0 +1,74 @@ +// 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 +T tmain(T argc) { + T b = argc, c, d, e, f, g; + static T a; +// CHECK: static T a; +#pragma omp distribute +// CHECK-NEXT: #pragma omp distribute + 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 private(argc, b), firstprivate(c, d), collapse(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 private(argc,b) firstprivate(c,d) collapse(2) +// 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 +// CHECK-NEXT: #pragma omp distribute + 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 private(argc,b),firstprivate(argv, c), collapse(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 private(argc,b) firstprivate(argv,c) collapse(2) +// 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 (0); +} + +#endif diff --git a/test/OpenMP/distribute_collapse_messages.cpp b/test/OpenMP/distribute_collapse_messages.cpp new file mode 100644 index 000000000000..8818d659d441 --- /dev/null +++ b/test/OpenMP/distribute_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 // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp distribute 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 distribute 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 distribute 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 distribute 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 distribute 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 distribute collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp distribute 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', but found only 1}} + // expected-error@+3 2 {{directive '#pragma omp distribute' 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 distribute 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 distribute 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 distribute 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 distribute collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp distribute 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 distribute collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute'}} + return argc; +} + +int main(int argc, char **argv) { + #pragma omp distribute 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 distribute 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 distribute collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp distribute 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', but found only 1}} + #pragma omp distribute collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute' 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', but found only 1}} + #pragma omp distribute 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 distribute' cannot contain more than one 'collapse' clause}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} + #pragma omp distribute 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 distribute 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 distribute 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 distribute' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp distribute collapse(collapse(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp distribute collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/distribute_firstprivate_messages.cpp b/test/OpenMP/distribute_firstprivate_messages.cpp new file mode 100644 index 000000000000..5d371abbfa8e --- /dev/null +++ b/test/OpenMP/distribute_firstprivate_messages.cpp @@ -0,0 +1,157 @@ +// RUN: %clang_cc1 -verify -fopenmp %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; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} +}; +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) { } +}; +class S6 { + int a; +public: + S6() : a(0) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + S6 p; + int i; + int &j = i; + #pragma omp distribute firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp distribute firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp distribute firstprivate () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute 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 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 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 firstprivate (argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute 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 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 firstprivate (argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(ba) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(da) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(S2::S2s) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(S2::S2sc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute private(i), firstprivate(i) // 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 shared(i) + #pragma omp distribute firstprivate(i) + for (j = 0; j < argc; ++j) foo(); + #pragma omp target + #pragma omp teams shared(i) + #pragma omp distribute firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp distribute' directive may not be firstprivate, predetermined as private}} + #pragma omp target + #pragma omp teams private(argc) // expected-note {{defined as private}} + #pragma omp distribute firstprivate(argc) // expected-error {{private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams reduction(+:argc) // expected-note {{defined as reduction}} + #pragma omp distribute firstprivate(argc) // expected-error {{reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute firstprivate(j) + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams + #pragma omp distribute lastprivate(argc), firstprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate in '#pragma omp distribute'}} expected-note{{defined as lastprivate}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp target + #pragma omp teams +#pragma omp distribute firstprivate(argc), lastprivate(argc) // expected-error {{lastprivate variable cannot be firstprivate in '#pragma omp distribute'}} expected-note{{defined as firstprivate}} + for (i = 0; i < argc; ++i) foo(); + return 0; +} diff --git a/test/OpenMP/distribute_private_messages.cpp b/test/OpenMP/distribute_private_messages.cpp new file mode 100644 index 000000000000..94ba4659c684 --- /dev/null +++ b/test/OpenMP/distribute_private_messages.cpp @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -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) { } + static float S2s; // expected-note {{predetermined as shared}} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 c; // expected-note {{predetermined as shared}} +const S3 ca[5]; // expected-note {{predetermined as shared}} +extern const int f; // expected-note {{predetermined as shared}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} // 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}} + + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{predetermined as shared}} + const int da[5] = { 0 }; // expected-note {{predetermined as shared}} + S4 e(4); + S5 g(5); + int i; + int &j = i; + #pragma omp distribute private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (a, b, c, d, f) // expected-error {{private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private(ba) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private(ca) // expected-error {{shared variable cannot be private}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private(da) // expected-error {{shared variable cannot be private}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private(S2::S2s) // expected-error {{shared variable cannot be private}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute 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 distribute private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp distribute'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp target + #pragma omp teams + { + int i; // expected-note {{predetermined as private}} + #pragma omp distribute firstprivate(i), private(i) // expected-error {{private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'}} + for (int k = 0; k < argc; ++k) ++k; + } + #pragma omp target + #pragma omp teams private(i) + #pragma omp distribute private(j) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel private(i) + #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) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp distribute private(i) + for (int k = 0; k < 10; ++k) { + #pragma omp target + #pragma omp teams private(i) + #pragma omp distribute private(i) + for (int x = 0; x < 10; ++x) foo(); + } + #pragma omp target + #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 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(); + } + + return 0; +} diff --git a/test/OpenMP/driver.c b/test/OpenMP/driver.c new file mode 100644 index 000000000000..f84541bef8ba --- /dev/null +++ b/test/OpenMP/driver.c @@ -0,0 +1,10 @@ +// Test that by default -fnoopenmp-use-tls is passed to frontend. +// +// RUN: %clang %s -### -o %t.o 2>&1 -fopenmp=libomp | FileCheck --check-prefix=CHECK-DEFAULT %s +// CHECK-DEFAULT: -cc1 +// CHECK-DEFAULT-NOT: -fnoopenmp-use-tls +// +// RUN: %clang %s -### -o %t.o 2>&1 -fopenmp=libomp -fnoopenmp-use-tls | FileCheck --check-prefix=CHECK-NO-TLS %s +// CHECK-NO-TLS: -cc1 +// CHECK-NO-TLS-SAME: -fnoopenmp-use-tls +// diff --git a/test/OpenMP/flush_codegen.cpp b/test/OpenMP/flush_codegen.cpp index cd411cea4573..d0ab9f1525a8 100644 --- a/test/OpenMP/flush_codegen.cpp +++ b/test/OpenMP/flush_codegen.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -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 -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // expected-no-diagnostics // REQUIRES: x86-registered-target #ifndef HEADER diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp index c482ec56b9ca..8fd82e7f028b 100644 --- a/test/OpenMP/for_ast_print.cpp +++ b/test/OpenMP/for_ast_print.cpp @@ -13,27 +13,37 @@ T tmain(T argc) { T b = argc, c, d, e, f, g; static T a; // CHECK: static T a; -#pragma omp for schedule(dynamic) - // CHECK-NEXT: #pragma omp for schedule(dynamic) +#pragma omp for schedule(dynamic) linear(a) + // CHECK-NEXT: #pragma omp for schedule(dynamic) 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 parallel -#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered nowait - for (int i = 0; i < 10; ++i) - for (int j = 0; j < 10; ++j) - for (int j = 0; j < 10; ++j) - for (int j = 0; j < 10; ++j) - for (int j = 0; j < 10; ++j) +#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) nowait + 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 parallel - // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered nowait - // CHECK-NEXT: for (int i = 0; i < 10; ++i) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) nowait + // 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(); return T(); } @@ -49,12 +59,12 @@ int main(int argc, char **argv) { // CHECK-NEXT: for (int i = 0; i < 2; ++i) // CHECK-NEXT: a = 2; #pragma omp parallel -#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered nowait +#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered nowait linear(g:-1) for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) foo(); // CHECK-NEXT: #pragma omp parallel - // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered nowait + // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered nowait linear(g: -1) // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: for (int j = 0; j < 10; ++j) // CHECK-NEXT: foo(); diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp index 9db157011075..98761f56c762 100644 --- a/test/OpenMP/for_codegen.cpp +++ b/test/OpenMP/for_codegen.cpp @@ -1,7 +1,7 @@ // 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 -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 // // expected-no-diagnostics // REQUIRES: x86-registered-target @@ -357,7 +357,7 @@ void parallel_for(float *a) { // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]] - // TERM_DEBUG: call {{.+}} @__kmpc_cancel_barrier({{.+}}), !dbg [[DBG_LOC_CANCEL:![0-9]+]] + // TERM_DEBUG: call {{.+}} @__kmpc_barrier({{.+}}), !dbg [[DBG_LOC_CANCEL:![0-9]+]] // TERM_DEBUG: [[TERM_LPAD]] // TERM_DEBUG: call void @__clang_call_terminate // TERM_DEBUG: unreachable @@ -404,6 +404,25 @@ void for_with_global_lcv() { k = i; k = j; } + char &cnt = i; +#pragma omp for + for (cnt = 0; cnt < 2; ++cnt) + k = cnt; +} + +// CHECK-LABEL: for_with_references +void for_with_references() { +// CHECK: [[I:%.+]] = alloca i8, +// CHECK: [[CNT:%.+]] = alloca i8*, +// CHECK: [[CNT_PRIV:%.+]] = alloca i8, +// CHECK: call void @__kmpc_for_static_init_4( +// CHECK-NOT: load i8, i8* [[CNT]], +// CHECK: call void @__kmpc_for_static_fini( + char i = 0; + char &cnt = i; +#pragma omp for + for (cnt = 0; cnt < 2; ++cnt) + k = cnt; } struct Bool { diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp index 0a7443319e8c..d40c305c6271 100644 --- a/test/OpenMP/for_collapse_messages.cpp +++ b/test/OpenMP/for_collapse_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp 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 for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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 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]; @@ -41,7 +41,7 @@ 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 (1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp 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 for collapse (2) // expected-note {{as specified in 'collapse' clause}} foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}} @@ -63,7 +63,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/for_firstprivate_codegen.cpp b/test/OpenMP/for_firstprivate_codegen.cpp index 0d5f83ed4ec3..01a93559451a 100644 --- a/test/OpenMP/for_firstprivate_codegen.cpp +++ b/test/OpenMP/for_firstprivate_codegen.cpp @@ -16,6 +16,7 @@ struct St { }; volatile int g = 1212; +volatile int &g1 = g; template struct S { @@ -30,7 +31,6 @@ struct 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]+}} } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } template T tmain() { @@ -38,7 +38,7 @@ T tmain() { T t_var = T(); T vec[] = {1, 2}; S s_arr[] = {1, 2}; - S var(3); + S &var = test; #pragma omp parallel #pragma omp for firstprivate(t_var, vec, s_arr, var) for (int i = 0; i < 2; ++i) { @@ -58,22 +58,24 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S var(3); +// CHECK: [[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: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( -// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for firstprivate(g) +#pragma omp for firstprivate(g, g1, sivar) for (int i = 0; i < 2; ++i) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR_REF:%.+]]) // Skip temp vars for loop // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, @@ -81,25 +83,47 @@ int main() { // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR2_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** %{{.+}}, + // LAMBDA: [[SIVAR2_PRIVATE_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, + + // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // 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( g = 1; + g1 = 1; + sivar = 2; // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR2_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]+}}* [[SIVAR2_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini( - // LAMBDA: call i32 @__kmpc_cancel_barrier( + // LAMBDA: call void @__kmpc_barrier( [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + g1 = 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -110,11 +134,11 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* -// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for firstprivate(g) +#pragma omp for firstprivate(g, g1, sivar) for (int i = 0; i < 2; ++i) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR_REF:%.+]]) // Skip temp vars for loop // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, @@ -122,34 +146,56 @@ int main() { // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR2_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // BLOCKS: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** %{{.+}}, + // BLOCKS: [[SIVAR_REF_ADDRR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, + // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + + // 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( g = 1; + g1 =1; + sivar = 2; // BLOCKS: call void @__kmpc_for_static_init_4( // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]], + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini( - // BLOCKS: call i32 @__kmpc_cancel_barrier( + // BLOCKS: call void @__kmpc_barrier( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + g1 = 2; + sivar = 4; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } }(); return 0; #else -#pragma omp for firstprivate(t_var, vec, s_arr, var) +#pragma omp for firstprivate(t_var, vec, s_arr, var, sivar) for (int i = 0; i < 2; ++i) { vec[i] = t_var; s_arr[i] = var; + sivar += i; } return tmain(); #endif @@ -167,6 +213,7 @@ int main() { // 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: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( // firstprivate t_var(t_var) @@ -194,6 +241,10 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// firstprivate (sivar) +// CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]] +// 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]]) @@ -212,11 +263,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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] 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]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// 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) %{{.+}}) // Skip temp vars for loop // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, @@ -229,22 +280,20 @@ int main() { // 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: [[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]]]** % + // firstprivate t_var(t_var) -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], // 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]], // firstprivate vec(vec) -// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // 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]], // firstprivate s_arr(s_arr) -// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF]], // 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_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]] @@ -256,8 +305,7 @@ int main() { // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] // firstprivate var(var) -// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % // 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]]) @@ -275,7 +323,7 @@ int main() { // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_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 i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void #endif diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp index 2ec81104e771..1933de25850e 100644 --- a/test/OpenMP/for_firstprivate_messages.cpp +++ b/test/OpenMP/for_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (int k = 0; k < argc; ++k) @@ -114,15 +114,11 @@ int foomain(int argc, char **argv) { #pragma omp for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel -#pragma omp for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}} - for (int k = 0; k < argc; ++k) - ++k; #pragma omp parallel { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} -#pragma omp for firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (int k = 0; k < argc; ++k) { i = k; v += i; @@ -130,7 +126,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp for firstprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -175,7 +171,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (i = 0; i < argc; ++i) @@ -274,7 +270,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp for firstprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -289,7 +285,7 @@ int main(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} -#pragma omp for firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (int k = 0; k < argc; ++k) { i = k; v += i; @@ -307,6 +303,10 @@ int main(int argc, char **argv) { #pragma omp for firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp index 880637ea8b94..36abd8df07cb 100644 --- a/test/OpenMP/for_lastprivate_codegen.cpp +++ b/test/OpenMP/for_lastprivate_codegen.cpp @@ -18,14 +18,13 @@ struct S { ~S() {} }; -volatile int g = 1212; +volatile int g __attribute__((aligned(128)))= 1212; +volatile int &g1 = g; float f; char cnt; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } // CHECK: [[S_INT_TY:%.+]] = type { i32 } -// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[X:@.+]] = global double 0.0 // CHECK-DAG: [[F:@.+]] = global float 0.0 @@ -33,10 +32,10 @@ char cnt; template T tmain() { S test; - T t_var = T(); - T vec[] = {1, 2}; - S s_arr[] = {1, 2}; - S var(3); + T t_var __attribute__((aligned(128))) = T(); + T vec[] __attribute__((aligned(128))) = {1, 2}; + S s_arr[] __attribute__((aligned(128))) = {1, 2}; + S &var __attribute__((aligned(128))) = test; #pragma omp parallel #pragma omp for lastprivate(t_var, vec, s_arr, var) for (int i = 0; i < 2; ++i) { @@ -54,33 +53,44 @@ using A::x; } int main() { + static int 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: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* %{{.+}}) #pragma omp parallel -#pragma omp for lastprivate(g) +#pragma omp for lastprivate(g, g1, sivar) for (int i = 0; i < 2; ++i) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) // 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 + // LAMBDA: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, + // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // 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: [[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: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) g = 1; + g1 = 1; + sivar = 2; // Check for final copying of private values back to original vars. // LAMBDA: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // LAMBDA: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -91,17 +101,26 @@ int main() { // original g=private_g; // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + + // original sivar=private_sivar; + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* %{{.+}}, // LAMBDA: br label %[[LAST_DONE]] // LAMBDA: [[LAST_DONE]] - // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + g1 = 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -112,18 +131,21 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for lastprivate(g) +#pragma omp for lastprivate(g, g1, sivar) for (int i = 0; i < 2; ++i) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) // 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 + // BLOCKS: [[G1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 4 + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_ADDR:%.+]], + // BLOCKS: {{.+}} = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR]] // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) @@ -134,6 +156,8 @@ int main() { // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) g = 1; + g1 = 1; + sivar = 2; // Check for final copying of private values back to original vars. // BLOCKS: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // BLOCKS: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -144,16 +168,24 @@ int main() { // original g=private_g; // BLOCKS: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* %{{.+}}, // BLOCKS: br label %[[LAST_DONE]] // BLOCKS: [[LAST_DONE]] - // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) g = 1; + g1 = 1; ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + g1 = 1; + sivar = 4; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -166,10 +198,11 @@ int main() { S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp for lastprivate(t_var, vec, s_arr, var) +#pragma omp for lastprivate(t_var, vec, s_arr, var, sivar) for (int i = 0; i < 2; ++i) { vec[i] = t_var; s_arr[i] = var; + sivar += i; } #pragma omp parallel #pragma omp for lastprivate(A::x, B::x) firstprivate(f) lastprivate(f) @@ -193,16 +226,15 @@ int main() { // CHECK: define i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] 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]+}}*, %{{.+}}*)* [[MAIN_MICROTASK1:@.+]] 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]+}}*, %{{.+}}*)* [[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]+}}*, %{{.+}}*)* [[MAIN_MICROTASK3:@.+]] 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]+}}*, i32*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i32*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK1:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK2:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK3:@.+]] to void // CHECK: = call {{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](i32* noalias [[GTID_ADDR:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, @@ -212,21 +244,19 @@ int main() { // 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: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[VEC_REF:%.+]] = load [2 x i32]*, [2 x 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 for default initialization. -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], // CHECK-NOT: [[T_VAR_PRIV]] -// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // CHECK-NOT: [[VEC_PRIV]] -// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_REF_PTR]], // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]]) -// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_REF_PTR]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // @@ -261,17 +291,18 @@ int main() { // original var=private_var; // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* {{.*}} [[VAR_PRIV]]) +// CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIV]], // CHECK: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] // 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: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void // -// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: [[F_PRIV:%.+]] = alloca float, // CHECK-NOT: alloca float // CHECK: [[X_PRIV:%.+]] = alloca double, @@ -308,11 +339,10 @@ int main() { // CHECK-NEXT: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: [[F_PRIV:%.+]] = alloca float, // CHECK-NOT: alloca float @@ -340,11 +370,10 @@ int main() { // CHECK-NEXT: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: [[CNT_PRIV:%.+]] = alloca i8, // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] @@ -387,43 +416,41 @@ int main() { // CHECK-NEXT: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void // 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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] 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]+}}*, 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 internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// 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]+}}, // 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: [[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: [[VAR_PRIV_REF:%.+]] = alloca [[S_INT_TY]]*, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % + // Check for default initialization. -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], // CHECK-NOT: [[T_VAR_PRIV]] -// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // CHECK-NOT: [[VEC_PRIV]] -// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]], // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]* // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]]) -// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK: store [[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]** [[VAR_PRIV_REF]] // CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // // CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) @@ -456,14 +483,15 @@ int main() { // CHECK: [[S_ARR_BODY_DONE]] // original var=private_var; -// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* {{.*}} [[VAR_PRIV]]) +// CHECK: [[VAR_PRIV1:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PRIV_REF]], +// CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* {{.*}} [[VAR_PRIV1]]) // CHECK: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] // 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: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void #endif diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp index 2fa14b63bd11..79912b6efbca 100644 --- a/test/OpenMP/for_lastprivate_messages.cpp +++ b/test/OpenMP/for_lastprivate_messages.cpp @@ -67,7 +67,7 @@ int foomain(int argc, char **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (int k = 0; k < argc; ++k) @@ -116,10 +116,6 @@ int foomain(int argc, char **argv) { #pragma omp for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel -#pragma omp for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}} - for (int k = 0; k < argc; ++k) - ++k; #pragma omp parallel { int v = 0; @@ -132,7 +128,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp for lastprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -165,7 +161,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (i = 0; i < argc; ++i) @@ -272,7 +268,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp for lastprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -283,5 +279,9 @@ int main(int argc, char **argv) { #pragma omp for lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/for_linear_codegen.cpp b/test/OpenMP/for_linear_codegen.cpp new file mode 100644 index 000000000000..db9788361dd0 --- /dev/null +++ b/test/OpenMP/for_linear_codegen.cpp @@ -0,0 +1,266 @@ +// 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 +// expected-no-diagnostics +// REQUIRES: x86-registered-target +#ifndef HEADER +#define HEADER + +template +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S &operator=(const S &); + operator T() { return T(); } + ~S() {} +}; + +volatile int g = 1212; +volatile int &g1 = g; +float f; +char cnt; + +// 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* +// CHECK-DAG: [[F:@.+]] = global float 0.0 +// CHECK-DAG: [[CNT:@.+]] = global i8 0 +template +T tmain() { + S test; + T *pvar = &test.f; + T &lvar = test.f; +#pragma omp parallel +#pragma omp for linear(pvar, lvar) + for (int i = 0; i < 2; ++i) { + ++pvar, ++lvar; + } + return T(); +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { + // 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{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: [[G_START_ADDR:%.+]] = 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // LAMBDA: [[VAL:%.+]] = load i32, i32* [[G_START_ADDR]] + // LAMBDA: [[CNT:%.+]] = load i32, i32* + // LAMBDA: [[MUL:%.+]] = mul nsw i32 [[CNT]], 5 + // LAMBDA: [[ADD:%.+]] = add nsw i32 [[VAL]], [[MUL]] + // LAMBDA: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]], + // LAMBDA: [[VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]], + // LAMBDA: [[ADD:%.+]] = add nsw i32 [[VAL]], 5 + // LAMBDA: store i32 [[ADD]], i32* [[G_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: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) + g += 5; + g1 += 5; + // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + g1 = 2; + // 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: 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) { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: [[G_START_ADDR:%.+]] = 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // BLOCKS: [[VAL:%.+]] = load i32, i32* [[G_START_ADDR]] + // BLOCKS: [[CNT:%.+]] = load i32, i32* + // BLOCKS: [[MUL:%.+]] = mul nsw i32 [[CNT]], 5 + // BLOCKS: [[ADD:%.+]] = add nsw i32 [[VAL]], [[MUL]] + // BLOCKS: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]], + // BLOCKS: [[VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]], + // BLOCKS: [[ADD:%.+]] = add nsw i32 [[VAL]], 5 + // BLOCKS: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) + g += 5; + g1 += 5; + // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + g = 1; + g1 = 5; + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + g1 = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S test; + float *pvar = &test.f; + long long lvar = 0; +#pragma omp parallel +#pragma omp for linear(pvar, lvar : 3) + for (int i = 0; i < 2; ++i) { + pvar += 3, lvar += 3; + } + return tmain(); +#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: 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]+}}*, float**, i64*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: = call {{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call void [[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(8) %{{.+}}, i64* dereferenceable(8) %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[PVAR_START:%.+]] = alloca float*, +// CHECK: [[LVAR_START:%.+]] = alloca i64, +// 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: [[PVAR_PRIV:%.+]] = alloca float*, +// CHECK: [[LVAR_PRIV:%.+]] = alloca i64, +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] + +// Check for default initialization. +// CHECK: [[PVAR_REF:%.+]] = load float**, float*** % +// CHECK: [[LVAR_REF:%.+]] = load i64*, i64** % +// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_REF]], +// CHECK: store float* [[PVAR_VAL]], float** [[PVAR_START]], +// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_REF]], +// CHECK: store i64 [[LVAR_VAL]], i64* [[LVAR_START]], +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3 +// CHECK: [[IDX:%.+]] = sext i32 [[MUL]] to i64 +// CHECK: [[PTR:%.+]] = getelementptr inbounds float, float* [[PVAR_VAL]], i64 [[IDX]] +// CHECK: store float* [[PTR]], float** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3 +// CHECK: [[CONV:%.+]] = sext i32 [[MUL]] to i64 +// CHECK: [[VAL:%.+]] = add nsw i64 [[LVAR_VAL]], [[CONV]] +// CHECK: store i64 [[VAL]], i64* [[LVAR_PRIV]], +// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_PRIV]] +// CHECK: [[PTR:%.+]] = getelementptr inbounds float, float* [[PVAR_VAL]], i64 3 +// CHECK: store float* [[PTR]], float** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_PRIV]], +// CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3 +// CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]], +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: ret void + +// 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]+}} 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 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*, +// CHECK: [[LVAR_START:%.+]] = alloca i32, +// 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: [[PVAR_PRIV:%.+]] = alloca i32*, +// CHECK: [[LVAR_PRIV:%.+]] = alloca i32, +// CHECK: [[LVAR_PRIV_REF:%.+]] = alloca i32*, +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] + +// Check for default initialization. +// CHECK: [[PVAR_REF:%.+]] = load i32**, i32*** % +// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_REF]], +// CHECK: store i32* [[PVAR_VAL]], i32** [[PVAR_START]], +// CHECK: [[LVAR_REF:%.+]] = load i32*, i32** % +// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_REF]], +// CHECK: store i32 [[LVAR_VAL]], i32* [[LVAR_START]], +// CHECK: store i32* [[LVAR_PRIV]], i32** [[LVAR_PRIV_REF]], + +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 1 +// CHECK: [[IDX:%.+]] = sext i32 [[MUL]] to i64 +// CHECK: [[PTR:%.+]] = getelementptr inbounds i32, i32* [[PVAR_VAL]], i64 [[IDX]] +// CHECK: store i32* [[PTR]], i32** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 1 +// CHECK: [[VAL:%.+]] = add nsw i32 [[LVAR_VAL]], [[MUL]] +// CHECK: store i32 [[VAL]], i32* [[LVAR_PRIV]], +// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_PRIV]] +// CHECK: [[PTR:%.+]] = getelementptr inbounds i32, i32* [[PVAR_VAL]], i32 1 +// CHECK: store i32* [[PTR]], i32** [[PVAR_PRIV]], +// CHECK: [[LVAR_PRIV:%.+]] = load i32*, i32** [[LVAR_PRIV_REF]], +// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_PRIV]], +// CHECK: [[ADD:%.+]] = add nsw i32 [[LVAR_VAL]], 1 +// CHECK: store i32 [[ADD]], i32* [[LVAR_PRIV]], +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: ret void +#endif + diff --git a/test/OpenMP/for_linear_messages.cpp b/test/OpenMP/for_linear_messages.cpp new file mode 100644 index 000000000000..39fb21ef7be0 --- /dev/null +++ b/test/OpenMP/for_linear_messages.cpp @@ -0,0 +1,218 @@ +// 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 for linear(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp 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 for linear(B:ib) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp for linear(z:B:ib) + for (int i = 0; i < 10; ++i) ; + #pragma omp for linear(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp for linear(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + #pragma omp for linear(B,::z, X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp for linear(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp for linear(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp for linear(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +template 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 for linear(ind2:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template int test_warn() { + int ind2 = 0; + // expected-warning@+1 {{zero linear step (ind2 should probably be const)}} + #pragma omp 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 int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; + #pragma omp for linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp 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 for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear (argc : 5) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp 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 for linear (a, b:B::ib) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear(i) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int v = 0; + int i; + #pragma omp for linear(v:i) + for (int k = 0; k < argc; ++k) { i = k; v += i; } + } + #pragma omp for linear(j) + for (int k = 0; k < argc; ++k) ++k; + int v = 0; + #pragma omp for linear(v:j) + for (int k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp for linear(i) + for (int k = 0; k < argc; ++k) ++k; + #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; + 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 for linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp 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 for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp 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 for linear(a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp 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 for linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp 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 for linear(i) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear(i : 4) + for (int k = 0; k < argc; ++k) { ++k; i += 4; } + } + #pragma omp for linear(j) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for linear(i) + for (int k = 0; k < argc; ++k) ++k; + #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(argc,argv); + return 0; +} + diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp index 1a1315507893..895baf57e9cc 100644 --- a/test/OpenMP/for_loop_messages.cpp +++ b/test/OpenMP/for_loop_messages.cpp @@ -10,10 +10,13 @@ public: }; static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} #pragma omp threadprivate(sii) static int globalii; -register int reg0 __asm__("0"); +// Currently, we cannot use "0" for global register variables. +// register int reg0 __asm__("0"); +int reg0; int test_iteration_spaces() { const int N = 100; @@ -66,37 +69,37 @@ int test_iteration_spaces() { c[(int)fi] = a[(int)fi] + b[(int)fi]; } #pragma omp parallel -// expected-error@+2 {{variable must be of integer or random access iterator type}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (int &ref = ii; ref < 10; ref++) { } #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (int i; i < 10; i++) c[i] = a[i]; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (int i = 0, j = 0; i < 10; ++i) c[i] = a[i]; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (; ii < 10; ++ii) c[ii] = a[ii]; #pragma omp parallel // expected-warning@+3 {{expression result unused}} -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (ii + 1; ii < 10; ++ii) c[ii] = a[ii]; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (c[ii] = 0; ii < 10; ++ii) c[ii] = a[ii]; @@ -289,7 +292,6 @@ int test_iteration_spaces() { c[ii] = a[ii]; #pragma omp parallel -// expected-error@+3 {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}} // expected-note@+2 {{defined as linear}} // expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be linear, predetermined as private}} #pragma omp for linear(ii) @@ -308,6 +310,7 @@ int test_iteration_spaces() { #pragma omp parallel { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be threadprivate or thread local, predetermined as private}} #pragma omp for for (sii = 0; sii < 10; sii += 1) c[sii] = a[sii]; @@ -447,7 +450,7 @@ int test_with_random_access_iterator() { for (GoodIter I = begin; I < end; ++I) ++I; #pragma omp parallel -// expected-error@+2 {{variable must be of integer or random access iterator type}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (GoodIter &I = begin; I < end; ++I) ++I; @@ -486,7 +489,7 @@ int test_with_random_access_iterator() { for (begin = begin0; begin < end; ++begin) ++begin; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for for (++begin; begin < end; ++begin) ++begin; diff --git a/test/OpenMP/for_misc_messages.c b/test/OpenMP/for_misc_messages.c index f5b87514947c..0a7cdf8fc06b 100644 --- a/test/OpenMP/for_misc_messages.c +++ b/test/OpenMP/for_misc_messages.c @@ -62,9 +62,8 @@ void test_non_identifiers() { #pragma omp for; for (i = 0; i < 16; ++i) ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp for' are ignored}} #pragma omp parallel -// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}} -// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}} #pragma omp for linear(x); for (i = 0; i < 16; ++i) ; @@ -176,17 +175,17 @@ void test_collapse() { for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for collapse(-5) for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for collapse(0) for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for collapse(5 - 5) for (i = 0; i < 16; ++i) ; @@ -195,7 +194,7 @@ void test_collapse() { 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 {{private variable cannot be reduction}} +// expected-error@+2 {{reduction variable must be shared}} // expected-error@+1 {{region cannot be closely nested inside '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) diff --git a/test/OpenMP/for_ordered_clause.cpp b/test/OpenMP/for_ordered_clause.cpp new file mode 100644 index 000000000000..8af509ab9aa8 --- /dev/null +++ b/test/OpenMP/for_ordered_clause.cpp @@ -0,0 +1,120 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp for ordered + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp 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 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 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 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 for ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#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}} +#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}} +#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]; +#pragma omp for ordered(1) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp for ordered(N-1) // expected-error 2 {{argument to 'ordered' clause must be a strictly positive integer value}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp 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 for ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}} +#pragma omp for ordered(N) collapse(N + 2) // expected-error {{the parameter of the 'ordered' clause must be greater than or equal to the parameter of the 'collapse' clause}} expected-note {{parameter of the 'collapse' clause}} expected-error {{argument to 'ordered' clause must be a strictly positive integer value}} + for (int i = ST; i < N; i++) + for (int j = ST; j < N; j++) + for (int k = ST; k < N; k++) + foo(); + return argc; +} + +int main(int argc, char **argv) { +#pragma omp for ordered + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp 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 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 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 for', but found only 1}} +#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}} + 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 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) + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#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}} +#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]; +// expected-error@+3 {{statement after '#pragma omp for' must be a for loop}} +// expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} +#pragma omp for ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp for ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}} +#pragma omp for ordered(0) // expected-error {{argument to 'ordered' 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 for ordered(2) collapse(3) // expected-error {{the parameter of the 'ordered' clause must be greater than or equal to the parameter of the 'collapse' clause}} expected-note {{parameter of the 'collapse' clause}} + for (int i = 0; i < 10; i++) + for (int j = 0; j < 11; j++) + for (int k = 0; k < 12; k++) + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/for_private_codegen.cpp b/test/OpenMP/for_private_codegen.cpp index ed6d87bcbae0..e8f4d3f4c830 100644 --- a/test/OpenMP/for_private_codegen.cpp +++ b/test/OpenMP/for_private_codegen.cpp @@ -18,19 +18,17 @@ struct S { }; volatile double g; +volatile double &g1 = g; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i8 } -// CHECK: type { i8 } // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i8 } template T tmain() { S test; T t_var = T(); T vec[] = {1, 2}; S s_arr[] = {1, 2}; - S var(3); + S &var = test; #pragma omp parallel #pragma omp for private(t_var, vec, s_arr, s_arr, var, var) for (int i = 0; i < 2; ++i) { @@ -41,34 +39,55 @@ T tmain() { } int main() { + static int svar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( [&]() { + static float sfvar; // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for private(g) +#pragma omp for private(g, g1, svar, sfvar) for (int i = 0; i < 2; ++i) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float, g = 1; + g1 = 1; + svar = 3; + sfvar = 4.0; // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4( // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], + // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]] + // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // LAMBDA: store float* [[SFVAR_PRIVATE_ADDR]], float** [[SFVAR_PRIVATE_ADDR_REF]] // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call {{.*}}void @__kmpc_for_static_fini( [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + g1 = 2; + svar = 4; + sfvar = 8.0; // 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: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]] + // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]] + // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]] }(); } }(); @@ -78,28 +97,50 @@ int main() { // BLOCKS-LABEL: @main // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ + static float sfvar; // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* {{.+}}) + // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for private(g) +#pragma omp for private(g, g1, svar, sfvar) for (int i = 0; i < 2; ++i) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float, g = 1; + g1 = 1; + svar = 2; + sfvar = 3.0; // BLOCKS: call {{.*}}void @__kmpc_for_static_init_4( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS: store float 3.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]], + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} // BLOCKS: double* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS: float* [[SFVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 // BLOCKS: call {{.*}}void @__kmpc_for_static_fini( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + g1 = 2; + svar = 4; + sfvar = 9.0; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} + // BLOCKS: store float 9.0{{.+}}, float* + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -110,9 +151,9 @@ int main() { int t_var = 0; int vec[] = {1, 2}; S s_arr[] = {1, 2}; - S var(3); + S &var = test; #pragma omp parallel -#pragma omp for private(t_var, vec, s_arr, s_arr, var, var) +#pragma omp for private(t_var, vec, s_arr, s_arr, var, var, svar) for (int i = 0; i < 2; ++i) { vec[i] = t_var; s_arr[i] = var; @@ -130,19 +171,19 @@ int main() { // CHECK: define i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](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-NOT: alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], // CHECK-NOT: alloca [[S_FLOAT_TY]], +// CHECK: [[S_VAR_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]] @@ -161,11 +202,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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](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_INT_TY]]], diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp index 225a1beb99ea..3015f819b544 100644 --- a/test/OpenMP/for_private_messages.cpp +++ b/test/OpenMP/for_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp for private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -99,7 +99,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp for private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp for private(i) @@ -127,7 +127,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp for private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -179,12 +179,16 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp for private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp for private(i) for (int k = 0; k < argc; ++k) ++k; + static int si; +#pragma omp for private(si) // OK + for(int k = 0; k < argc; ++k) + si = k + 1; return 0; } diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp index 7de8dff31c4c..423ab3ce76d0 100644 --- a/test/OpenMP/for_reduction_codegen.cpp +++ b/test/OpenMP/for_reduction_codegen.cpp @@ -8,7 +8,8 @@ #ifndef HEADER #define HEADER -volatile double g; +volatile double g, g_orig; +volatile double &g1 = g_orig; template struct S { @@ -22,8 +23,6 @@ struct S { // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]* } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [[S_INT_TY]]*, [[S_INT_TY]]*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]* } // 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* @@ -36,7 +35,8 @@ T tmain() { T t_var = T(), t_var1; T vec[] = {1, 2}; S s_arr[] = {1, 2}; - S var(3), var1; + S &var = test; + S var1; #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) { @@ -59,26 +59,27 @@ int main() { // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for reduction(+:g) +#pragma omp for reduction(+:g, g1) for (int i = 0; i < 2; ++i) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}}) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, // Reduction list for runtime. - // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x i8*], + // LAMBDA: [[RED_LIST:%.+]] = alloca [2 x i8*], // LAMBDA: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]] // LAMBDA: call void @__kmpc_for_static_init_4( g = 1; + g1 = 1; // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini( - // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i64 0, i64 0 // LAMBDA: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8* // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], // LAMBDA: call i32 @__kmpc_reduce( @@ -104,6 +105,7 @@ int main() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + g1 = 2; // 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]] @@ -118,18 +120,19 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp for reduction(-:g) +#pragma omp for reduction(-:g, g1) for (int i = 0; i < 2; ++i) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}}) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, // Reduction list for runtime. - // BLOCKS: [[RED_LIST:%.+]] = alloca [1 x i8*], + // BLOCKS: [[RED_LIST:%.+]] = alloca [2 x i8*], // BLOCKS: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]] g = 1; + g1 = 1; // BLOCKS: call void @__kmpc_for_static_init_4( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} @@ -138,7 +141,7 @@ int main() { // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini( - // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i64 0, i64 0 // BLOCKS: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8* // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], // BLOCKS: call i32 @__kmpc_reduce( @@ -163,6 +166,7 @@ int main() { ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + g1 = 2; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} @@ -176,13 +180,18 @@ int main() { float t_var = 0, t_var1; int vec[] = {1, 2}; S s_arr[] = {1, 2}; - S var(3), var1; + S &var = test; + S var1, arrs[10][4]; #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]; return tmain(); #endif } @@ -190,13 +199,13 @@ int main() { // CHECK: define {{.*}}i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// 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 {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}) // CHECK: [[T_VAR_PRIV:%.+]] = alloca float, // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]], @@ -207,23 +216,20 @@ int main() { // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR_REF:%.+]] = load float*, float** [[T_VAR_PTR_REF]], +// 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 0. // CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]], -// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]], // For & reduction operation initial value of private variable is ones in all bits. +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) -// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]], // For && reduction operation initial value of private variable is 1.0. // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]]) -// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** [[T_VAR1_PTR_REF]], // For min reduction operation initial value of private variable is largest repesentable value. // CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]], @@ -236,16 +242,16 @@ int main() { // void *RedList[] = {[0], ..., [-1]}; -// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// 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]], i32 0, i32 1 +// 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]], i32 0, i32 2 +// 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]], i32 0, i32 3 +// 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]], @@ -372,8 +378,7 @@ int main() { // 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 i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void @@ -385,38 +390,38 @@ int main() { // } // 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:%.+]], i32 0, i32 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:%.+]], i32 0, i32 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*)lhs[1]; -// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[1]; -// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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*)lhs[2]; -// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[2]; -// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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]], i32 0, i32 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]], i32 0, i32 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* @@ -457,15 +462,218 @@ int main() { // CHECK: store float [[UP]], float* [[T_VAR1_LHS]], // 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(160) %{{.+}}) + +// 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 0, 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 @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* % +// 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[] = {[0], ..., [-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(, , , sizeof(RedList), RedList, reduce_func, &); + +// 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:%.+]] = 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]]* [[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: [[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(, , &); +// 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: 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]]* [[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: [[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: [[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[], void *rhs[]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type-1*)lhs[-1] = ReductionOperation-1(*(Type-1*)lhs[-1], +// *(Type-1*)rhs[-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*)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*)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:%.+]] = 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 [[ARRS_SIZE]] +// 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 {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_TMAIN_TY]]* -// 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]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// 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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}) // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, @@ -481,23 +689,20 @@ int main() { // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// 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 i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]], -// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], // For & reduction operation initial value of private variable is ones in all bits. +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) -// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], // For && reduction operation initial value of private variable is 1.0. // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]]) -// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR1_PTR_REF]], // For min reduction operation initial value of private variable is largest repesentable value. // CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]], @@ -509,16 +714,16 @@ int main() { // void *RedList[] = {[0], ..., [-1]}; -// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// 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]], i32 0, i32 1 +// 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]], i32 0, i32 2 +// 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]], i32 0, i32 3 +// 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]], @@ -616,7 +821,6 @@ int main() { // 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: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void // void reduce_func(void *lhs[], void *rhs[]) { @@ -627,38 +831,38 @@ int main() { // } // 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:%.+]], i32 0, i32 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:%.+]], i32 0, i32 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*)lhs[1]; -// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[1]; -// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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*)lhs[2]; -// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[2]; -// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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]], i32 0, i32 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]], i32 0, i32 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]+}}* diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp index 9c15e37989b2..317f88ce11ba 100644 --- a/test/OpenMP/for_reduction_messages.cpp +++ b/test/OpenMP/for_reduction_messages.cpp @@ -1,4 +1,6 @@ // 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() { } @@ -54,6 +56,9 @@ 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}} +#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}} +#endif int a; public: @@ -64,6 +69,8 @@ public: S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} +char *get(); + template // expected-note {{declared here}} T tmain(T argc) { const T d = T(); // expected-note 4 {{'d' defined here}} @@ -128,27 +135,27 @@ 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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'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 {{reduction variable 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 variable 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 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}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp for reduction(max : qa[1]) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -160,7 +167,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -184,7 +191,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -196,6 +203,14 @@ T tmain(T argc) { #pragma omp for reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) foo(); +#pragma omp parallel private(qa) // expected-note 2 {{defined as private}} +#pragma omp for reduction(+ : qa[1], get()[0]) // expected-error 2 {{reduction variable must be shared}} expected-error {{expected variable name as a base of the array subscript}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(qa) +#pragma omp for reduction(+ : qa[1], qa[0]) // 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 reduction(* : fl) // expected-note 2 {{defined as reduction}} #pragma omp for reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) @@ -277,27 +292,27 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 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 parallel -#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel -#pragma omp for reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp for reduction(max : argv[1]) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -309,7 +324,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -341,7 +356,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -353,10 +368,22 @@ int main(int argc, char **argv) { #pragma omp for reduction(+ : fl) // expected-error {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) foo(); +#pragma omp parallel private(argv) // expected-note {{defined as private}} +#pragma omp for reduction(+ : argv[1], get()[0]) // expected-error {{reduction variable must be shared}} expected-error {{expected variable name as a base of the array subscript}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(qa) +#pragma omp for reduction(+ : qa[1], qa[0]) // 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 parallel reduction(* : fl) // expected-note {{defined as reduction}} #pragma omp for reduction(+ : fl) // expected-error {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) foo(); + static int m=0; +#pragma omp for reduction(+:m) + for (int i = 0; i < 10; ++i) + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/for_schedule_messages.cpp b/test/OpenMP/for_schedule_messages.cpp index c4490e88f02b..8946ce3aedfb 100644 --- a/test/OpenMP/for_schedule_messages.cpp +++ b/test/OpenMP/for_schedule_messages.cpp @@ -13,13 +13,23 @@ template // expected-note {{declared here}} T tmain(T argc, S **argv) { #pragma omp 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 for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule (monotonic // expected-error {{expected ')'}} expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-warning {{missing ':' after schedule modifier - ignoring}} 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 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 for schedule (nonmonotonic, // expected-error {{expected ')'}} expected-error {{expected 'simd' in OpenMP clause 'schedule'}} expected-warning {{missing ':' after schedule modifier - ignoring}} 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 schedule (simd: // expected-error {{expected ')'}} expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} 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 schedule (monotonic, auto // expected-error {{expected ')'}} expected-warning {{missing ':' after schedule modifier - ignoring}} expected-error {{expected 'simd' in OpenMP clause 'schedule'}} 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 schedule (nonmonotonic: auto, // expected-error {{expected ')'}} expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} 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 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]; @@ -28,7 +38,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} @@ -36,17 +46,35 @@ T tmain(T argc, S **argv) { #pragma omp 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 for' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} + #pragma omp 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 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 for schedule (dynamic, 1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp 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]; + #pragma omp for schedule (nonmonotonic: static) // expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: auto) // expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: runtime) // expected-error {{'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (monotonic, nonmonotonic: auto) // expected-error {{modifier 'nonmonotonic' cannot be used along with modifier 'monotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic, monotonic: auto) // expected-error {{modifier 'monotonic' cannot be used along with modifier 'nonmonotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic, nonmonotonic: auto) // expected-error {{modifier 'nonmonotonic' cannot be used along with modifier 'nonmonotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (monotonic, monotonic: auto) // expected-error {{modifier 'monotonic' cannot be used along with modifier 'monotonic'}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for schedule (nonmonotonic: guided) ordered // expected-error {{'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for ordered(1) schedule(nonmonotonic: dynamic) // expected-error {{'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified}} for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; return argc; } @@ -54,13 +82,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp 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 for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -73,17 +101,17 @@ int main(int argc, char **argv) { #pragma omp 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 for' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} + #pragma omp 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 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 for' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp for schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/test/OpenMP/for_simd_aligned_messages.cpp b/test/OpenMP/for_simd_aligned_messages.cpp index d41ecc1f28ee..1007b3c545cc 100644 --- a/test/OpenMP/for_simd_aligned_messages.cpp +++ b/test/OpenMP/for_simd_aligned_messages.cpp @@ -50,7 +50,7 @@ template T test_template(T* arr, N num) { T sum = (T)0; T ind2 = - num * L; // Negative number is passed as L. - // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} #pragma omp for simd aligned(arr:L) for (i = 0; i < num; ++i) { T cur = arr[(int)ind2]; @@ -65,7 +65,7 @@ template T test_template(T* arr, N num) { template int test_warn() { int *ind2 = 0; - // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} #pragma omp for simd aligned(ind2:LEN) for (int i = 0; i < 100; i++) { ind2 += LEN; diff --git a/test/OpenMP/for_simd_ast_print.cpp b/test/OpenMP/for_simd_ast_print.cpp index 21c15a2fd677..725c727e261e 100644 --- a/test/OpenMP/for_simd_ast_print.cpp +++ b/test/OpenMP/for_simd_ast_print.cpp @@ -35,8 +35,8 @@ template struct S { // CHECK: T res; // CHECK: T val; // CHECK: T lin = 0; - #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) -// CHECK-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) +// CHECK-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) for (T i = 7; i < m_a; ++i) { val = v[i-7] + m_a; res = val; @@ -44,8 +44,8 @@ template struct S { } const T clen = 3; // CHECK: T clen = 3; - #pragma omp for simd safelen(clen-1) -// CHECK-NEXT: #pragma omp for simd safelen(clen - 1) + #pragma omp for simd safelen(clen-1) simdlen(clen-1) +// CHECK-NEXT: #pragma omp for simd safelen(clen - 1) simdlen(clen - 1) for(T i = clen+2; i < 20; ++i) { // CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { v[i] = v[v-clen] + 1; @@ -62,7 +62,7 @@ template struct S { template struct S2 { static void func(int n, float *a, float *b, float *c) { int k1 = 0, k2 = 0; -#pragma omp for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) +#pragma omp for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) for(int i = 0; i < n; i++) { c[i] = a[i] + b[i]; c[k1] = a[k1] + b[k1]; @@ -77,7 +77,7 @@ template struct S2 { // CHECK: template struct S2 { // CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { // CHECK-NEXT: int k1 = 0, k2 = 0; -// CHECK-NEXT: #pragma omp for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: #pragma omp for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) // CHECK-NEXT: for (int i = 0; i < n; i++) { // CHECK-NEXT: c[i] = a[i] + b[i]; // CHECK-NEXT: c[k1] = a[k1] + b[k1]; @@ -114,8 +114,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: foo(); const int CLEN = 4; // CHECK-NEXT: const int CLEN = 4; - #pragma omp for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) -// CHECK-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + #pragma omp for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) +// CHECK-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) for (int i = 0; i < 10; ++i)foo(); // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); diff --git a/test/OpenMP/for_simd_codegen.cpp b/test/OpenMP/for_simd_codegen.cpp index a5644013868c..cc8193d31803 100644 --- a/test/OpenMP/for_simd_codegen.cpp +++ b/test/OpenMP/for_simd_codegen.cpp @@ -1,7 +1,7 @@ -// 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 -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm -fexceptions -fcxx-exceptions -o - < %s | 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 -debug-info-kind=limited -std=c++11 -include-pch %t -verify -emit-llvm -o - < %s | FileCheck %s +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm -o - < %s | FileCheck %s --check-prefix=TERM_DEBUG // REQUIRES: x86-registered-target // expected-no-diagnostics #ifndef HEADER @@ -303,7 +303,7 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]], // CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* %{{.+}}, // CHECK-NEXT: br label -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* {{.+}}, i32 %{{.+}}) +// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) } int R; #pragma omp parallel @@ -354,7 +354,7 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK: [[RED:%.+]] = mul nsw i32 %{{.+}}, [[R_PRIV_VAL]] // CHECK-NEXT: store i32 [[RED]], i32* %{{.+}}, // CHECK-NEXT: call void @__kmpc_end_reduce( -// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* {{.+}}, i32 %{{.+}}) +// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) } } @@ -683,4 +683,3 @@ void parallel_simd(float *a) { } // TERM_DEBUG: !{{[0-9]+}} = !DILocation(line: [[@LINE-11]], #endif // HEADER - diff --git a/test/OpenMP/for_simd_collapse_messages.cpp b/test/OpenMP/for_simd_collapse_messages.cpp index 7bb9b04cda7a..5c9d058b975c 100644 --- a/test/OpenMP/for_simd_collapse_messages.cpp +++ b/test/OpenMP/for_simd_collapse_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp 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 for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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 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]; @@ -41,7 +41,7 @@ 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 (1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp 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 for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} foo(); // expected-error {{expected 2 for loops after '#pragma omp for simd'}} @@ -63,7 +63,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/for_simd_firstprivate_messages.cpp b/test/OpenMP/for_simd_firstprivate_messages.cpp index 6b49b11eaff6..cb74ee081710 100644 --- a/test/OpenMP/for_simd_firstprivate_messages.cpp +++ b/test/OpenMP/for_simd_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (int k = 0; k < argc; ++k) @@ -122,7 +122,7 @@ int foomain(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for simd' directive into a parallel or another task region?}} -#pragma omp for simd firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (int k = 0; k < argc; ++k) { i = k; v += i; @@ -130,7 +130,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp for simd firstprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -168,7 +168,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (i = 0; i < argc; ++i) @@ -271,7 +271,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp for simd firstprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -286,7 +286,7 @@ int main(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for simd' directive into a parallel or another task region?}} -#pragma omp for simd firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (int k = 0; k < argc; ++k) { i = k; v += i; @@ -300,6 +300,10 @@ int main(int argc, char **argv) { #pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for simd firstprivate(si) + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/for_simd_lastprivate_messages.cpp b/test/OpenMP/for_simd_lastprivate_messages.cpp index 2aa4dd12045c..d48c07d92b39 100644 --- a/test/OpenMP/for_simd_lastprivate_messages.cpp +++ b/test/OpenMP/for_simd_lastprivate_messages.cpp @@ -67,7 +67,7 @@ int foomain(int argc, char **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (int k = 0; k < argc; ++k) @@ -132,7 +132,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp for simd lastprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -158,7 +158,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (i = 0; i < argc; ++i) @@ -261,7 +261,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp for simd lastprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -272,5 +272,9 @@ int main(int argc, char **argv) { #pragma omp for simd lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp index 189c8b0be88e..44370a15664f 100644 --- a/test/OpenMP/for_simd_linear_messages.cpp +++ b/test/OpenMP/for_simd_linear_messages.cpp @@ -102,7 +102,7 @@ template int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp for simd linear // expected-error {{expected '(' after 'linear'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -138,7 +138,7 @@ template int foomain(I argc, C **argv) { #pragma omp for simd linear(v:i) for (int k = 0; k < argc; ++k) { i = k; v += i; } } - #pragma omp for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type}} + #pragma omp for simd linear(j) for (int k = 0; k < argc; ++k) ++k; int v = 0; #pragma omp for simd linear(v:j) @@ -166,7 +166,7 @@ int main(int argc, char **argv) { S4 e(4); // expected-note {{'e' defined here}} S5 g(5); // expected-note {{'g' defined here}} int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp for simd linear // expected-error {{expected '(' after 'linear'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -203,7 +203,7 @@ int main(int argc, char **argv) { #pragma omp for simd linear(i : 4) for (int k = 0; k < argc; ++k) { ++k; i += 4; } } - #pragma omp for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type 'int &'}} + #pragma omp for simd linear(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp for simd linear(i) for (int k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/for_simd_loop_messages.cpp b/test/OpenMP/for_simd_loop_messages.cpp index da7e6843a0c4..958c7f60d0eb 100644 --- a/test/OpenMP/for_simd_loop_messages.cpp +++ b/test/OpenMP/for_simd_loop_messages.cpp @@ -10,6 +10,7 @@ public: }; static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} #pragma omp threadprivate(sii) static int globalii; @@ -63,37 +64,37 @@ int test_iteration_spaces() { c[(int)fi] = a[(int)fi] + b[(int)fi]; } #pragma omp parallel -// expected-error@+2 {{variable must be of integer or random access iterator type}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (int &ref = ii; ref < 10; ref++) { } #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (int i; i < 10; i++) c[i] = a[i]; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (int i = 0, j = 0; i < 10; ++i) c[i] = a[i]; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (; ii < 10; ++ii) c[ii] = a[ii]; #pragma omp parallel // expected-warning@+3 {{expression result unused}} -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (ii + 1; ii < 10; ++ii) c[ii] = a[ii]; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (c[ii] = 0; ii < 10; ++ii) c[ii] = a[ii]; @@ -306,6 +307,7 @@ int test_iteration_spaces() { #pragma omp parallel { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be threadprivate or thread local, predetermined as linear}} #pragma omp for simd for (sii = 0; sii < 10; sii += 1) c[sii] = a[sii]; @@ -430,7 +432,7 @@ int test_with_random_access_iterator() { for (GoodIter I = begin; I < end; ++I) ++I; #pragma omp parallel -// expected-error@+2 {{variable must be of integer or random access iterator type}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (GoodIter &I = begin; I < end; ++I) ++I; @@ -469,7 +471,7 @@ int test_with_random_access_iterator() { for (begin = begin0; begin < end; ++begin) ++begin; #pragma omp parallel -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp for simd for (++begin; begin < end; ++begin) ++begin; diff --git a/test/OpenMP/for_simd_misc_messages.c b/test/OpenMP/for_simd_misc_messages.c index e87a78976e2c..ca1e366ca092 100644 --- a/test/OpenMP/for_simd_misc_messages.c +++ b/test/OpenMP/for_simd_misc_messages.c @@ -153,20 +153,117 @@ void test_safelen() { #pragma omp for simd safelen(foo()) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp for simd safelen(-5) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp for simd safelen(0) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp for simd safelen(5 - 5) for (i = 0; i < 16; ++i) ; } +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp 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 for simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp 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 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 for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp 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 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 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 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 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 for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; #pragma omp parallel @@ -259,17 +356,17 @@ void test_collapse() { for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for simd collapse(-5) for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for simd collapse(0) for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp for simd collapse(5 - 5) for (i = 0; i < 16; ++i) ; @@ -278,7 +375,7 @@ void test_collapse() { 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 simd' directive into a parallel or another task region?}} for (int j = 0; j < 16; ++j) -// expected-error@+2 {{private variable cannot be reduction}} +// expected-error@+2 {{reduction variable must be shared}} // expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}} #pragma omp for simd reduction(+ : i, j) for (int k = 0; k < 16; ++k) diff --git a/test/OpenMP/for_simd_private_messages.cpp b/test/OpenMP/for_simd_private_messages.cpp index 96885c859e99..15e235c2f8f4 100644 --- a/test/OpenMP/for_simd_private_messages.cpp +++ b/test/OpenMP/for_simd_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp for simd private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -99,7 +99,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp for simd private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp for simd private(i) @@ -120,7 +120,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp for simd private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -169,12 +169,16 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp for simd private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp for simd private(i) for (int k = 0; k < argc; ++k) ++k; + static int m; +#pragma omp for simd private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; return 0; } diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp index 74952776d508..000960fb55b5 100644 --- a/test/OpenMP/for_simd_reduction_messages.cpp +++ b/test/OpenMP/for_simd_reduction_messages.cpp @@ -1,4 +1,6 @@ // 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() { } @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -112,7 +118,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp 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 @@ -128,27 +134,27 @@ 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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'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 {{reduction variable 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 variable 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 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}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp 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 -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -160,7 +166,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -184,7 +190,7 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -261,7 +267,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp 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 parallel @@ -277,27 +283,27 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 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 parallel -#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel -#pragma omp for simd reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp 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 -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -309,7 +315,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -337,7 +343,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -353,6 +359,10 @@ int main(int argc, char **argv) { #pragma omp for simd reduction(+ : fl) // expected-error {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) foo(); + static int m; +#pragma omp for simd reduction(+ : m) + for (int i = 0; i < 10; ++i) + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/for_simd_safelen_messages.cpp b/test/OpenMP/for_simd_safelen_messages.cpp index 27a87b559bc9..d70e90198ad6 100644 --- a/test/OpenMP/for_simd_safelen_messages.cpp +++ b/test/OpenMP/for_simd_safelen_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp 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 for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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}} #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]; @@ -41,7 +41,7 @@ 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 (4) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp 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; } @@ -61,7 +61,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/for_simd_schedule_messages.cpp b/test/OpenMP/for_simd_schedule_messages.cpp index 1367676ad58c..76ba3a42eda2 100644 --- a/test/OpenMP/for_simd_schedule_messages.cpp +++ b/test/OpenMP/for_simd_schedule_messages.cpp @@ -13,13 +13,13 @@ template // expected-note {{declared here}} T tmain(T argc, S **argv) { #pragma omp 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 for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -28,7 +28,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} @@ -36,17 +36,17 @@ T tmain(T argc, S **argv) { #pragma omp 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 for simd' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + #pragma omp 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 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 for simd schedule (dynamic, 1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp 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; } @@ -54,13 +54,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp 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 for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -73,17 +73,17 @@ int main(int argc, char **argv) { #pragma omp 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 for simd' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + #pragma omp 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 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 for simd' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/test/OpenMP/for_simd_simdlen_messages.cpp b/test/OpenMP/for_simd_simdlen_messages.cpp new file mode 100644 index 000000000000..c72e54681192 --- /dev/null +++ b/test/OpenMP/for_simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp 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 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 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 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 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 for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp 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 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 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 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 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp for simd simdlen(simdlen(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/function-attr.cpp b/test/OpenMP/function-attr.cpp new file mode 100644 index 000000000000..87aba40f2b7d --- /dev/null +++ b/test/OpenMP/function-attr.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -stack-protector 2 -emit-llvm -o - %s | FileCheck %s + +// Check that function attributes are added to the OpenMP runtime functions. + +template +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + operator T() { return T(); } + ~S() {} +}; + +// CHECK: define internal void @.omp.copyprivate.copy_func(i8*, i8*) [[ATTR0:#[0-9]+]] { + +void foo0(); + +int foo1() { + char a; + +#pragma omp parallel + a = 2; +#pragma omp single copyprivate(a) + foo0(); + + return 0; +} + +// CHECK: define internal void @.omp_task_privates_map.({{.*}}) [[ATTR3:#[0-9]+]] { +// CHECK: define internal i32 @.omp_task_entry.({{.*}}) [[ATTR0]] { +// CHECK: define internal i32 @.omp_task_destructor.({{.*}}) [[ATTR0]] { + +int foo2() { + S s_arr[] = {1, 2}; + S var(3); +#pragma omp task private(s_arr, var) + s_arr[0] = var; + return 0; +} + +// CHECK: define internal void @.omp.reduction.reduction_func(i8*, i8*) [[ATTR0]] { + +float foo3(int n, float *a, float *b) { + int i; + float result; + +#pragma omp parallel for private(i) reduction(+:result) + for (i=0; i < n; i++) + result = result + (a[i] * b[i]); + return result; +} + +// CHECK: attributes [[ATTR0]] = {{{.*}} sspstrong {{.*}}} +// CHECK: attributes [[ATTR3]] = {{{.*}} sspstrong {{.*}}} diff --git a/test/OpenMP/linking.c b/test/OpenMP/linking.c index 778216d723b8..81706d4f6201 100644 --- a/test/OpenMP/linking.c +++ b/test/OpenMP/linking.c @@ -69,3 +69,21 @@ // CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt" "-lgcc" // CHECK-LD-OVERRIDE-64: "-lpthread" "-lc" // +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp=libomp -target x86_64-msvc-win32 \ +// RUN: | FileCheck --check-prefix=CHECK-MSVC-LINK-64 %s +// CHECK-MSVC-LINK-64: link.exe +// CHECK-MSVC-LINK-64-SAME: -nodefaultlib:vcomp.lib +// CHECK-MSVC-LINK-64-SAME: -nodefaultlib:vcompd.lib +// CHECK-MSVC-LINK-64-SAME: -libpath:{{.+}}/../lib +// CHECK-MSVC-LINK-64-SAME: -defaultlib:libomp.lib +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -fopenmp=libiomp5 -target x86_64-msvc-win32 \ +// RUN: | FileCheck --check-prefix=CHECK-MSVC-ILINK-64 %s +// CHECK-MSVC-ILINK-64: link.exe +// CHECK-MSVC-ILINK-64-SAME: -nodefaultlib:vcomp.lib +// CHECK-MSVC-ILINK-64-SAME: -nodefaultlib:vcompd.lib +// CHECK-MSVC-ILINK-64-SAME: -libpath:{{.+}}/../lib +// CHECK-MSVC-ILINK-64-SAME: -defaultlib:libiomp5md.lib +// diff --git a/test/OpenMP/master_codegen.cpp b/test/OpenMP/master_codegen.cpp index c364c5278baf..b491fb921c5c 100644 --- a/test/OpenMP/master_codegen.cpp +++ b/test/OpenMP/master_codegen.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -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 -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 // expected-no-diagnostics // REQUIRES: x86-registered-target #ifndef HEADER diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp index 8a3bacf0f115..6445c6b1c6d9 100644 --- a/test/OpenMP/nesting_of_regions.cpp +++ b/test/OpenMP/nesting_of_regions.cpp @@ -100,6 +100,18 @@ void foo() { #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; } +#pragma omp parallel + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp parallel + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SIMD DIRECTIVE #pragma omp simd @@ -227,6 +239,18 @@ void foo() { #pragma omp teams // 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 taskloop // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp 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 j = 0; j < 10; ++j) + ; + } // FOR DIRECTIVE #pragma omp for @@ -377,6 +401,18 @@ void foo() { #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; } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // FOR SIMD DIRECTIVE #pragma omp for simd @@ -504,6 +540,18 @@ void foo() { #pragma omp teams // 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 taskloop // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp 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 j = 0; j < 10; ++j) + ; + } // SECTIONS DIRECTIVE #pragma omp sections @@ -661,6 +709,18 @@ void foo() { #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; } +#pragma omp sections + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp sections + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute' 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}} @@ -854,6 +914,20 @@ void foo() { #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; } +#pragma omp sections + { +#pragma omp section +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SINGLE DIRECTIVE #pragma omp single @@ -994,6 +1068,18 @@ void foo() { #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; } +#pragma omp single + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp single + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // MASTER DIRECTIVE #pragma omp master @@ -1134,6 +1220,18 @@ void foo() { #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; } +#pragma omp master + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp master + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -1288,6 +1386,18 @@ void foo() { #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; } +#pragma omp critical + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp critical + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -1443,6 +1553,18 @@ void foo() { #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; } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // PARALLEL FOR SIMD DIRECTIVE #pragma omp parallel for simd @@ -1598,6 +1720,18 @@ void foo() { #pragma omp teams // 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 taskloop // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp 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 j = 0; j < 10; ++j) + ; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -1744,6 +1878,18 @@ void foo() { #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; } +#pragma omp parallel sections + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp parallel sections + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // TASK DIRECTIVE #pragma omp task @@ -1836,6 +1982,18 @@ void foo() { #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; } +#pragma omp task + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp task + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // ORDERED DIRECTIVE #pragma omp ordered @@ -1976,6 +2134,18 @@ void foo() { #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; } +#pragma omp ordered + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp ordered + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // ATOMIC DIRECTIVE #pragma omp atomic @@ -2145,6 +2315,22 @@ void foo() { #pragma omp teams // 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 taskloop // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ++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 distribute // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } // TARGET DIRECTIVE #pragma omp target @@ -2250,6 +2436,18 @@ void foo() { #pragma omp teams // expected-note {{nested teams construct here}} ++a; } +#pragma omp target + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // TEAMS DIRECTIVE #pragma omp target @@ -2370,536 +2568,659 @@ void foo() { #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; } -} - -void foo() { - int a = 0; -// PARALLEL DIRECTIVE -#pragma omp parallel -#pragma omp for - for (int i = 0; i < 10; ++i) - ; -#pragma omp parallel -#pragma omp simd - for (int i = 0; i < 10; ++i) - ; -#pragma omp parallel -#pragma omp for simd - for (int i = 0; i < 10; ++i) - ; -#pragma omp parallel -#pragma omp sections - { - bar(); - } -#pragma omp parallel -#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel region}} - { - bar(); - } -#pragma omp parallel -#pragma omp sections +#pragma omp target +#pragma omp teams { - bar(); +#pragma omp taskloop // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskloop' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ++a; } -#pragma omp parallel -#pragma omp single - bar(); -#pragma omp parallel -#pragma omp master - bar(); -#pragma omp parallel -#pragma omp critical - bar(); -#pragma omp parallel -#pragma omp parallel for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) ; -#pragma omp parallel -#pragma omp parallel for simd +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) ; -#pragma omp parallel -#pragma omp parallel sections - { - bar(); +#pragma omp distribute + for (int j = 0; j < 10; ++j) + ; + +// TASKLOOP DIRECTIVE +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; } -#pragma omp parallel -#pragma omp task - { - bar(); +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; } -#pragma omp parallel - { -#pragma omp taskyield - bar(); +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp parallel - { -#pragma omp barrier - bar(); + for (int i = 0; i < 10; ++i) + ; } -#pragma omp parallel - { -#pragma omp taskwait - bar(); +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } } -#pragma omp parallel - { -#pragma omp flush - bar(); +#pragma omp taskloop + 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 taskloop region}} + { + bar(); + } } -#pragma omp parallel - { -#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} - bar(); - } -#pragma omp parallel - { -#pragma omp atomic - ++a; - } -#pragma omp parallel - { -#pragma omp target - ++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; - } - -// SIMD DIRECTIVE -#pragma omp 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 simd - for (int i = 0; i < 10; ++i) { -#pragma omp simd // 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 for simd // 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 parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} - for (int i = 0; i < 10; ++i) - ; - } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp single // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} { bar(); } } -#pragma omp simd + +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp master // expected-error {{region cannot be closely nested inside 'taskloop' region}} { bar(); } } -#pragma omp simd +#pragma omp taskloop 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 master // expected-error {{OpenMP constructs may not be nested inside a simd region}} - bar(); +#pragma omp critical + { + bar(); + } } -#pragma omp simd +#pragma omp taskloop 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 critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} - bar(); +#pragma omp parallel + { +#pragma omp single // OK + { + bar(); + } +#pragma omp for // OK + for (int i = 0; i < 10; ++i) + ; +#pragma omp sections // OK + { + bar(); + } + } } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp parallel for for (int i = 0; i < 10; ++i) ; } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp parallel for simd for (int i = 0; i < 10; ++i) ; } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp parallel sections { bar(); } } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp task { bar(); } } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp taskyield bar(); } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'taskloop' region}} bar(); } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp taskwait bar(); } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp flush bar(); } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} bar(); } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp atomic ++a; } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp target ++a; } -#pragma omp simd +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} +#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; } - -// FOR DIRECTIVE -#pragma omp for +#pragma omp taskloop for (int i = 0; i < 10; ++i) { -#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +// DISTRIBUTE DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'distribute' 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 + for (int i = 0; i < 10; ++i) { #pragma omp for + 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 simd for (int i = 0; i < 10; ++i) ; } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { -#pragma omp for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} +#pragma omp for simd for (int i = 0; i < 10; ++i) ; } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp parallel for (int i = 0; i < 10; ++i) ; } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { -#pragma omp sections // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} +#pragma omp sections { bar(); } } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute 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 for region}} +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a distribute region}} { bar(); } } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp single + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp master + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { -#pragma omp single // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} - bar(); -#pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}} - bar(); #pragma omp critical - bar(); + { + bar(); + } } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute 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 +#pragma omp single { - bar(); + bar(); } } } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp parallel for for (int i = 0; i < 10; ++i) ; } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp parallel for simd for (int i = 0; i < 10; ++i) ; } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp parallel sections { bar(); } } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp task { bar(); } } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp taskyield bar(); } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { -#pragma omp barrier // expected-error {{region cannot be closely nested inside 'for' region}} +#pragma omp barrier bar(); } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp flush bar(); } -#pragma omp for - for (int i = 0; i < 10; ++i) { -#pragma omp ordered // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} - bar(); - } -#pragma omp for ordered +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { -#pragma omp ordered // OK +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} bar(); } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp atomic ++a; } -#pragma omp for +#pragma omp target +#pragma omp teams +#pragma omp distribute for (int i = 0; i < 10; ++i) { #pragma omp target ++a; } -#pragma omp for +#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 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} +#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; } +} -// FOR SIMD DIRECTIVE -#pragma omp 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) - ; - } +void foo() { + int a = 0; +// PARALLEL DIRECTIVE +#pragma omp parallel +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel #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}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp sections + { + bar(); + } +#pragma omp parallel +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel region}} + { + bar(); + } +#pragma omp parallel +#pragma omp sections + { + bar(); + } +#pragma omp parallel +#pragma omp single + bar(); +#pragma omp parallel +#pragma omp master + bar(); +#pragma omp parallel +#pragma omp critical + bar(); +#pragma omp parallel +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel +#pragma omp parallel sections + { + bar(); + } +#pragma omp parallel +#pragma omp task + { + bar(); + } +#pragma omp parallel + { +#pragma omp taskyield + bar(); + } +#pragma omp parallel + { +#pragma omp barrier + bar(); + } +#pragma omp parallel + { +#pragma omp taskwait + bar(); + } +#pragma omp parallel + { +#pragma omp flush + bar(); + } +#pragma omp parallel + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel + { +#pragma omp atomic + ++a; + } +#pragma omp parallel + { +#pragma omp target + ++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; + } +#pragma omp parallel + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp parallel + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} for (int i = 0; i < 10; ++i) ; } -#pragma omp for simd + +// SIMD DIRECTIVE +#pragma omp 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 simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // 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 for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; } -#pragma omp for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 master // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } -#pragma omp for simd +#pragma omp 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 critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } -#pragma omp for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#pragma omp 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 for simd +#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; } -#pragma omp for simd +#pragma omp 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 for simd +#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; } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp 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 j = 0; j < 10; ++j) + ; + } -// SECTIONS DIRECTIVE -#pragma omp sections - { -#pragma omp for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +// FOR DIRECTIVE +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} for (int i = 0; i < 10; ++i) ; } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp simd for (int i = 0; i < 10; ++i) ; } -#pragma omp sections - { -#pragma omp for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} for (int i = 0; i < 10; ++i) ; } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for (int i = 0; i < 10; ++i) ; } -#pragma omp sections - { -#pragma omp sections // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} { bar(); } } -#pragma omp sections - { -#pragma omp section +#pragma omp 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 for region}} { bar(); } } -#pragma omp sections - { -#pragma omp critical +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} bar(); -#pragma omp single // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} +#pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}} bar(); -#pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}} +#pragma omp critical bar(); } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel { #pragma omp single // OK @@ -2918,211 +3239,507 @@ void foo() { } } } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for for (int i = 0; i < 10; ++i) ; } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for simd for (int i = 0; i < 10; ++i) ; } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections { bar(); } } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp task { bar(); } } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp taskyield + bar(); } -#pragma omp sections - { -#pragma omp barrier // expected-error {{region cannot be closely nested inside 'sections' region}} +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'for' region}} bar(); } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp taskwait + bar(); } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp flush + bar(); } -#pragma omp sections - { -#pragma omp ordered // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} bar(); } -#pragma omp sections - { +#pragma omp for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp atomic ++a; } -#pragma omp sections - { +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp target ++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?}} +#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; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) ++a; } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } -// SECTION DIRECTIVE -#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} - { +// FOR SIMD DIRECTIVE +#pragma omp 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 for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // 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 for simd // 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 parallel // 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 sections // 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 section // 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 single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } -#pragma omp sections - { -#pragma omp section +#pragma omp 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 critical // 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 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 parallel for simd // 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 parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} { -#pragma omp for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} - for (int i = 0; i < 10; ++i) - ; + bar(); + } + } +#pragma omp 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 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 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 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 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 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 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 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 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 for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp 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 j = 0; j < 10; ++j) + ; + } + +// SECTIONS DIRECTIVE +#pragma omp sections + { +#pragma omp for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } #pragma omp sections { -#pragma omp section - { #pragma omp simd - for (int i = 0; i < 10; ++i) - ; - } + for (int i = 0; i < 10; ++i) + ; } #pragma omp sections { -#pragma omp section - { -#pragma omp for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} - for (int i = 0; i < 10; ++i) - ; - } +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; } #pragma omp sections { -#pragma omp section - { #pragma omp parallel - for (int i = 0; i < 10; ++i) - ; - } + for (int i = 0; i < 10; ++i) + ; } #pragma omp sections { -#pragma omp section +#pragma omp sections // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} { -#pragma omp sections // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} - { - bar(); - } + bar(); } } #pragma omp sections { #pragma omp section { -#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a section region}} - { - bar(); - } + bar(); } } #pragma omp sections { -#pragma omp section - { -#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} - bar(); -#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}} - bar(); #pragma omp critical - bar(); - } + bar(); +#pragma omp single // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + bar(); +#pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}} + bar(); } #pragma omp sections { -#pragma omp section - { #pragma omp parallel - { + { #pragma omp single // OK - { - bar(); - } + { + bar(); + } #pragma omp for // OK - for (int i = 0; i < 10; ++i) - ; + for (int i = 0; i < 10; ++i) + ; #pragma omp for simd // OK - for (int i = 0; i < 10; ++i) - ; + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK - { - bar(); - } + { + bar(); } } } #pragma omp sections { -#pragma omp section - { #pragma omp parallel for - for (int i = 0; i < 10; ++i) - ; - } + for (int i = 0; i < 10; ++i) + ; } #pragma omp sections { -#pragma omp section - { #pragma omp parallel for simd - for (int i = 0; i < 10; ++i) - ; - } + for (int i = 0; i < 10; ++i) + ; } #pragma omp sections { -#pragma omp section - { #pragma omp parallel sections - { - bar(); - } + { + bar(); } } #pragma omp sections { -#pragma omp section - { #pragma omp task - { - bar(); - } + { + bar(); } } #pragma omp sections { -#pragma omp section - { #pragma omp taskyield - bar(); - } + } +#pragma omp sections + { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'sections' region}} + bar(); + } +#pragma omp sections + { +#pragma omp taskwait + } +#pragma omp sections + { +#pragma omp flush + } +#pragma omp sections + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp sections + { +#pragma omp atomic + ++a; + } +#pragma omp sections + { +#pragma omp target + ++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; + } +#pragma omp sections + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp sections + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute' 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}} + { + bar(); + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a section region}} + { + bar(); + } + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + bar(); +#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}} + bar(); +#pragma omp critical + bar(); + } + } +#pragma omp sections + { +#pragma omp section + { +#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 sections + { +#pragma omp section + { +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp parallel sections + { + bar(); + } + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp task + { + bar(); + } + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp taskyield + bar(); + } } #pragma omp sections { @@ -3180,6 +3797,22 @@ void foo() { ++a; } } +#pragma omp sections + { +#pragma omp section + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } + } +#pragma omp sections + { +#pragma omp section +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // SINGLE DIRECTIVE #pragma omp single @@ -3310,6 +3943,18 @@ void foo() { #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; } +#pragma omp single + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp single + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // MASTER DIRECTIVE #pragma omp master @@ -3450,6 +4095,18 @@ void foo() { #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; } +#pragma omp master + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp master + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -3609,6 +4266,18 @@ void foo() { #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; } +#pragma omp critical + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp critical + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -3764,6 +4433,18 @@ void foo() { #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; } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int j = 0; j < 10; ++j) + ; + } // PARALLEL FOR SIMD DIRECTIVE #pragma omp parallel for simd @@ -3919,6 +4600,18 @@ void foo() { #pragma omp teams // 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 taskloop // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp 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 j = 0; j < 10; ++j) + ; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -4061,13 +4754,25 @@ void foo() { #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; } - -// TASK DIRECTIVE -#pragma omp task -#pragma omp for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +#pragma omp parallel sections + { +#pragma omp taskloop for (int i = 0; i < 10; ++i) - ; -#pragma omp task + ++a; + } +#pragma omp parallel sections + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// TASK DIRECTIVE +#pragma omp task +#pragma omp for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp task #pragma omp simd for (int i = 0; i < 10; ++i) ; @@ -4152,6 +4857,18 @@ void foo() { #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; } +#pragma omp task + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp task + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } // ATOMIC DIRECTIVE #pragma omp atomic @@ -4321,6 +5038,22 @@ void foo() { #pragma omp teams // 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 taskloop // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ++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 distribute // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } // TARGET DIRECTIVE #pragma omp target @@ -4343,207 +5076,579 @@ void foo() { { bar(); } -#pragma omp target -#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target region}} - { - bar(); +#pragma omp target +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target region}} + { + bar(); + } +#pragma omp target +#pragma omp single + bar(); + +#pragma omp target +#pragma omp master + { + bar(); + } +#pragma omp target +#pragma omp critical + { + bar(); + } +#pragma omp target +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp parallel sections + { + bar(); + } +#pragma omp target +#pragma omp task + { + bar(); + } +#pragma omp target + { +#pragma omp taskyield + bar(); + } +#pragma omp target + { +#pragma omp barrier + bar(); + } +#pragma omp target + { +#pragma omp taskwait + bar(); + } +#pragma omp target + { +#pragma omp flush + bar(); + } +#pragma omp target + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target' 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 atomic + ++a; + } +#pragma omp target + { +#pragma omp target + ++a; + } +#pragma omp target + { +#pragma omp teams + ++a; + } +#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}} + { + ++a; // expected-note {{statement outside teams construct here}} +#pragma omp teams // expected-note {{nested teams construct here}} + ++a; + } +#pragma omp target + { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + ++a; + } +#pragma omp target + { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}} + for (int i = 0; i < 10; ++i) + ; + } + +// TEAMS DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp parallel + bar(); +#pragma omp target +#pragma omp teams +#pragma omp for // expected-error {{region cannot be closely nested inside 'teams' 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 simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'teams' 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 sections // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a teams region}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp single // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + bar(); + +#pragma omp target +#pragma omp teams +#pragma omp master // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp master' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp critical // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp critical' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp parallel sections + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp task // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp task' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskyield // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskyield' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp barrier' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskwait // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp flush // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp flush' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'teams' 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 atomic // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp atomic' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { +#pragma omp target // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target' 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; + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskloop // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskloop' directive into a parallel 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 target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) + ; +#pragma omp distribute + for (int j = 0; j < 10; ++j) + ; + +// TASKLOOP DIRECTIVE +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp taskloop + 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 taskloop region}} + { + bar(); + } + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + { + bar(); + } } -#pragma omp target -#pragma omp single - bar(); -#pragma omp target -#pragma omp master - { - bar(); +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{region cannot be closely nested inside 'taskloop' region}} + { + bar(); + } } -#pragma omp target +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp critical - { - bar(); + { + bar(); + } } -#pragma omp target +#pragma omp taskloop + 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 sections // OK + { + bar(); + } + } + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp parallel for - for (int i = 0; i < 10; ++i) - ; -#pragma omp target + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp parallel for simd - for (int i = 0; i < 10; ++i) - ; -#pragma omp target + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections - { - bar(); + { + bar(); + } } -#pragma omp target +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp task - { - bar(); + { + bar(); + } } -#pragma omp target - { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp taskyield bar(); } -#pragma omp target - { -#pragma omp barrier +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'taskloop' region}} bar(); } -#pragma omp target - { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp taskwait bar(); } -#pragma omp target - { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp flush bar(); } -#pragma omp target - { -#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'taskloop' 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 taskloop + for (int i = 0; i < 10; ++i) { #pragma omp atomic ++a; } -#pragma omp target - { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { #pragma omp target ++a; } -#pragma omp target - { -#pragma omp teams +#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; } -#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}} - { - ++a; // expected-note {{statement outside teams construct here}} -#pragma omp teams // expected-note {{nested teams construct here}} +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { +#pragma omp taskloop + for (int i = 0; i < 10; ++i) ++a; } -// TEAMS DIRECTIVE +// DISTRIBUTE DIRECTIVE #pragma omp target #pragma omp teams -#pragma omp parallel - bar(); +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp distribute // expected-error {{region cannot be closely nested inside 'distribute' 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 for // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} - for (int i = 0; i < 10; ++i) - ; +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp for + for (int i = 0; i < 10; ++i) + ; + } #pragma omp target #pragma omp teams -#pragma omp simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp simd' directive into a parallel region?}} - for (int i = 0; i < 10; ++i) - ; +#pragma omp distribute + 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 for simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} - for (int i = 0; i < 10; ++i) - ; +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp for simd + 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 parallel + for (int i = 0; i < 10; ++i) + ; + } #pragma omp target #pragma omp teams -#pragma omp sections // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} - { - bar(); +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp sections + { + bar(); + } } #pragma omp target #pragma omp teams -#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a teams region}} - { - bar(); +#pragma omp distribute + 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 region}} + { + bar(); + } } #pragma omp target #pragma omp teams -#pragma omp single // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} - bar(); - +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp single + { + bar(); + } + } #pragma omp target #pragma omp teams -#pragma omp master // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp master' directive into a parallel region?}} - { - bar(); +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp master + { + bar(); + } } #pragma omp target #pragma omp teams -#pragma omp critical // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp critical' directive into a parallel region?}} - { - bar(); +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp critical + { + bar(); + } + } +#pragma omp target +#pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp parallel + { +#pragma omp single + { + bar(); + } + } } #pragma omp target #pragma omp teams +#pragma omp distribute + for (int i = 0; i < 10; ++i) { #pragma omp parallel for - for (int i = 0; i < 10; ++i) - ; + 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 parallel for simd - for (int i = 0; i < 10; ++i) - ; + 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 parallel sections - { - bar(); + { + bar(); + } } #pragma omp target #pragma omp teams -#pragma omp task // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp task' directive into a parallel region?}} - { - bar(); +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp task + { + bar(); + } } #pragma omp target #pragma omp teams - { -#pragma omp taskyield // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskyield' directive into a parallel region?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield bar(); } #pragma omp target #pragma omp teams - { -#pragma omp barrier // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp barrier' directive into a parallel region?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp barrier bar(); } #pragma omp target #pragma omp teams - { -#pragma omp taskwait // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait bar(); } #pragma omp target #pragma omp teams - { -#pragma omp flush // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp flush' directive into a parallel region?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp flush bar(); } #pragma omp target #pragma omp teams - { -#pragma omp ordered // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'distribute' 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 atomic // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp atomic' directive into a parallel region?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp atomic ++a; } #pragma omp target #pragma omp teams - { -#pragma omp target // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target' directive into a parallel region?}} +#pragma omp distribute + for (int i = 0; i < 10; ++i) { +#pragma omp target ++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?}} +#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(); diff --git a/test/OpenMP/openmp_check.cpp b/test/OpenMP/openmp_check.cpp new file mode 100644 index 000000000000..c9b5eb0b9cba --- /dev/null +++ b/test/OpenMP/openmp_check.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s +int nested(int a) { +#pragma omp parallel + ++a; + + auto F = [&]() { // expected-error {{expected expression}} expected-error {{expected ';' at end of declaration}} expected-warning {{'auto' type specifier is a C++11 extension}} +#pragma omp parallel + { +#pragma omp target + ++a; + } + }; + F(); // expected-error {{C++ requires a type specifier for all declarations}} + return a; // expected-error {{expected unqualified-id}} +}// expected-error {{extraneous closing brace ('}')}} diff --git a/test/OpenMP/ordered_ast_print.cpp b/test/OpenMP/ordered_ast_print.cpp index 0006080b2082..97fe7007e262 100644 --- a/test/OpenMP/ordered_ast_print.cpp +++ b/test/OpenMP/ordered_ast_print.cpp @@ -8,7 +8,7 @@ void foo() {} -template +template T tmain (T argc) { T b = argc, c, d, e, f, g; static T a; @@ -18,6 +18,36 @@ T tmain (T argc) { { a=2; } + #pragma omp for ordered + for (int i =0 ; i < argc; ++i) + #pragma omp ordered threads + { + a=2; + } + #pragma omp simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp parallel for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp parallel for ordered(1) + for (int i =0 ; i < argc; ++i) { + #pragma omp ordered depend(source) + #pragma omp ordered depend(sink:i+N) + a = 2; + } return (0); } @@ -28,7 +58,36 @@ T tmain (T argc) { // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } - +// CHECK-NEXT: #pragma omp for ordered +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered threads +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for ordered(1) +// CHECK-NEXT: for (int i = 0; i < argc; ++i) { +// CHECK-NEXT: #pragma omp ordered depend(source) +// CHECK-NEXT: #pragma omp ordered depend(sink : i + 3) +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } // CHECK: static T a; // CHECK-NEXT: #pragma omp for ordered // CHECK-NEXT: for (int i = 0; i < argc; ++i) @@ -36,7 +95,38 @@ T tmain (T argc) { // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for ordered +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered threads +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for ordered(1) +// CHECK-NEXT: for (int i = 0; i < argc; ++i) { +// CHECK-NEXT: #pragma omp ordered depend(source) +// CHECK-NEXT: #pragma omp ordered depend(sink : i + N) +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-LABEL: int main( int main (int argc, char **argv) { int b = argc, c, d, e, f, g; static int a; @@ -47,13 +137,73 @@ int main (int argc, char **argv) { { a=2; } + #pragma omp for ordered + for (int i =0 ; i < argc; ++i) + #pragma omp ordered threads + { + a=2; + } + #pragma omp simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp parallel for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp parallel for ordered(1) + for (int i =0 ; i < argc; ++i) { + #pragma omp ordered depend(source) + #pragma omp ordered depend(sink: i - 5) + a = 2; + } // CHECK-NEXT: #pragma omp for ordered // CHECK-NEXT: for (int i = 0; i < argc; ++i) // CHECK-NEXT: #pragma omp ordered // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } - return tmain(argc); +// CHECK-NEXT: #pragma omp for ordered +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered threads +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for ordered(1) +// CHECK-NEXT: for (int i = 0; i < argc; ++i) { +// CHECK-NEXT: #pragma omp ordered depend(source) +// CHECK-NEXT: #pragma omp ordered depend(sink : i - 5) +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } + return tmain(argc); } #endif diff --git a/test/OpenMP/ordered_codegen.cpp b/test/OpenMP/ordered_codegen.cpp index ff8a8047cae4..e77c1bed97ca 100644 --- a/test/OpenMP/ordered_codegen.cpp +++ b/test/OpenMP/ordered_codegen.cpp @@ -92,7 +92,7 @@ void dynamic1(float *a, float *b, float *c, float *d) { // CHECK-NOT: !llvm.mem.parallel_loop_access // CHECK-NEXT: call void @__kmpc_end_ordered([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) // ... end of ordered region ... - #pragma omp ordered + #pragma omp ordered threads a[i] = b[i] * c[i] * d[i]; // CHECK: [[IV1_2:%.+]] = load i64, i64* [[OMP_IV]]{{.*}} // CHECK-NEXT: [[ADD1_2:%.+]] = add i64 [[IV1_2]], 1 @@ -197,7 +197,7 @@ void runtime(float *a, float *b, float *c, float *d) { // CHECK-NOT: !llvm.mem.parallel_loop_access // CHECK-NEXT: call void @__kmpc_end_ordered([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) // ... end of ordered region ... - #pragma omp ordered + #pragma omp ordered threads a[i] = b[i] * c[i] * d[i]; // CHECK: [[IV1_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}} // CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 @@ -213,5 +213,22 @@ void runtime(float *a, float *b, float *c, float *d) { // CHECK: ret void } +float f[10]; +// CHECK-LABEL: foo_simd +void foo_simd(int low, int up) { + // CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}, !llvm.mem.parallel_loop_access ! + // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}) #{{[0-9]+}}, !llvm.mem.parallel_loop_access ! +#pragma omp simd + for (int i = low; i < up; ++i) { + f[i] = 0.0; +#pragma omp ordered simd + f[i] = 1.0; + } +} + +// CHECK: define internal void [[CAP_FUNC]](i32* dereferenceable({{[0-9]+}}) %{{.+}}) # +// CHECK: store float 1.000000e+00, float* %{{.+}}, align +// CHECK-NEXT: ret void + #endif // HEADER diff --git a/test/OpenMP/ordered_messages.cpp b/test/OpenMP/ordered_messages.cpp index 72e59b7c7646..36f9bb2c7777 100644 --- a/test/OpenMP/ordered_messages.cpp +++ b/test/OpenMP/ordered_messages.cpp @@ -4,6 +4,7 @@ int foo(); template T foo() { + T k; #pragma omp for ordered for (int i = 0; i < 10; ++i) { L1: @@ -24,11 +25,115 @@ T foo() { foo(); } } - + #pragma omp for ordered + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads threads // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'threads' clause}} + { + foo(); + } + } + #pragma omp for ordered(1) // expected-note {{'ordered' clause with specified parameter}} + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} + { + foo(); + } + } + #pragma omp for ordered(1) // expected-note {{'ordered' clause with specified parameter}} + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{'ordered' directive with 'threads' clause cannot be closely nested inside ordered region with specified parameter}} + { + foo(); + } + } + #pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}} + { + foo(); + } + #pragma omp simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #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}} + { + foo(); + } + } + #pragma omp for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #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}} + { + foo(); + } + } + #pragma omp 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}} + { + foo(); + } + } + #pragma omp parallel 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}} + { + foo(); + } + #pragma omp ordered depend(source) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + } +#pragma omp parallel for ordered + for (int i = 0; i < 10; ++i) { + #pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} + #pragma omp ordered depend(sink : i) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} + } +#pragma omp parallel for ordered(2) // expected-note 5 {{'ordered' clause with specified parameter}} + for (int i = 0; i < 10; ++i) { + for (int j = 0; j < 10; ++j) { +#pragma omp ordered depend // expected-error {{expected '(' after 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}} +#pragma omp ordered depend(source // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink // expected-error {{expected expression}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-error {{expected ')'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink : // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i) // expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(source) + if (i == j) +#pragma omp ordered depend(source) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} + ; + if (i == j) +#pragma omp ordered depend(sink : i, j) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} + ; +#pragma omp ordered depend(source) threads // expected-error {{'depend' clauses cannot be mixed with 'threads' clause}} +#pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}} +#pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}} +#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i, j) +#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}} +#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(sink : i-0, j+sizeof(T)) +#pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}} +#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(T)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}} + } + } return T(); } int foo() { +int k; #pragma omp for ordered for (int i = 0; i < 10; ++i) { L1: @@ -49,6 +154,110 @@ int foo() { foo(); } } + #pragma omp for ordered + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads threads // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'threads' clause}} + { + foo(); + } + } + #pragma omp for ordered(1) // expected-note {{'ordered' clause with specified parameter}} + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} + { + foo(); + } + } + #pragma omp for ordered(1) // expected-note {{'ordered' clause with specified parameter}} + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{'ordered' directive with 'threads' clause cannot be closely nested inside ordered region with specified parameter}} + { + foo(); + } + } + #pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}} + { + foo(); + } + #pragma omp simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #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}} + { + foo(); + } + } + #pragma omp for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #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}} + { + foo(); + } + } + #pragma omp 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}} + { + foo(); + } + } + #pragma omp parallel 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}} + { + foo(); + } + #pragma omp ordered depend(source) // expected-error {{OpenMP constructs may not be nested inside a simd region}} + } +#pragma omp parallel for ordered + for (int i = 0; i < 10; ++i) { + #pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} + #pragma omp ordered depend(sink : i) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} + } +#pragma omp parallel for ordered(2) // expected-note 5 {{'ordered' clause with specified parameter}} + for (int i = 0; i < 10; ++i) { + for (int j = 0; j < 10; ++j) { +#pragma omp ordered depend // expected-error {{expected '(' after 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}} +#pragma omp ordered depend(source // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink // expected-error {{expected expression}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-error {{expected ')'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink : // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i) // expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(source) + if (i == j) +#pragma omp ordered depend(source) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} + ; + if (i == j) +#pragma omp ordered depend(sink : i, j) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} + ; +#pragma omp ordered depend(source) threads // expected-error {{'depend' clauses cannot be mixed with 'threads' clause}} +#pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}} +#pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}} +#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i, j) +#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}} +#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(sink : i-0, j+sizeof(int)) +#pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}} +#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(int)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}} + } + } - return foo(); + return foo(); // expected-note {{in instantiation of function template specialization 'foo' requested here}} } diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp index c3bd416a6d5f..1e46fba48ca3 100644 --- a/test/OpenMP/parallel_ast_print.cpp +++ b/test/OpenMP/parallel_ast_print.cpp @@ -33,11 +33,12 @@ T tmain(T argc, T *argv) { T b = argc, c, d, e, f, g; static T a; S s; + T arr[C][10], arr1[C]; #pragma omp parallel a=2; -#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+:c) reduction(max:e) +#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10]) foo(); -#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f) reduction(&& : g) +#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g) foo(); return 0; } @@ -46,31 +47,34 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: int b = argc, c, d, e, f, g; // CHECK-NEXT: static int a; // CHECK-NEXT: S s; +// CHECK-NEXT: int arr[5][10], arr1[5]; // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10]) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g) // CHECK-NEXT: foo() // CHECK: template long tmain(long argc, long *argv) { // CHECK-NEXT: long b = argc, c, d, e, f, g; // CHECK-NEXT: static long a; // CHECK-NEXT: S s; +// CHECK-NEXT: long arr[1][10], arr1[1]; // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10]) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g) // CHECK-NEXT: foo() // CHECK: template T tmain(T argc, T *argv) { // CHECK-NEXT: T b = argc, c, d, e, f, g; // CHECK-NEXT: static T a; // CHECK-NEXT: S s; +// CHECK-NEXT: T arr[C][10], arr1[C]; // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10]) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g) // CHECK-NEXT: foo() enum Enum { }; @@ -80,17 +84,40 @@ int main (int argc, char **argv) { int b = argc, c, d, e, f, g; static int a; #pragma omp threadprivate(a) + int arr[10][argc], arr1[2]; Enum ee; // CHECK: Enum ee; #pragma omp parallel // CHECK-NEXT: #pragma omp parallel a=2; // CHECK-NEXT: a = 2; -#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d) reduction(* : e) -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d) reduction(*: e) +#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc]) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc]) foo(); // CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10]) +// CHECK-NEXT: foo() +#pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10]) + foo(); return tmain(b, &b) + tmain(x, &x); } +template +struct Foo { + int foo; +}; + +void foo(const Foo &arg) { +// CHECK: #pragma omp parallel +#pragma omp parallel + { +// CHECK: #pragma omp for schedule(static) +#pragma omp for schedule(static) + for (int idx = 0; idx < 1234; ++idx) { + //arg.foo = idx; + idx = arg.foo; + } + } +} + #endif diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp index 6486e44a9dac..04c5c2c85ae2 100644 --- a/test/OpenMP/parallel_codegen.cpp +++ b/test/OpenMP/parallel_codegen.cpp @@ -1,18 +1,14 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -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 -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s // expected-no-diagnostics // REQUIRES: x86-registered-target #ifndef HEADER #define HEADER // CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* } -// CHECK-DAG: %struct.anon = type { i32* } -// CHECK-DAG: %struct.anon.0 = type { i8*** } // CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" // CHECK-DAG: [[DEF_LOC_2:@.+]] = 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-DEBUG-DAG: %ident_t = type { i32, i32, i32, i32, i8* } -// CHECK-DEBUG-DAG: %struct.anon = type { i32* } -// CHECK-DEBUG-DAG: %struct.anon.0 = type { i8*** } // CHECK-DEBUG-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" // CHECK-DEBUG-DAG: [[DEF_LOC_2:@.+]] = 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-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;main;[[@LINE+14]];9;;\00" @@ -35,56 +31,42 @@ int main (int argc, char **argv) { } // CHECK-LABEL: define {{[a-z\_\b]*[ ]?i32}} @main({{i32[ ]?[a-z]*}} %argc, i8** %argv) -// CHECK: [[AGG_CAPTURED:%.+]] = alloca %struct.anon -// CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon, %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0 -// CHECK-NEXT: store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]] -// CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8* -// CHECK-NEXT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK: store i32 %argc, i32* [[ARGC_ADDR:%.+]], +// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC_ADDR]]) // CHECK-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}} // CHECK-NEXT: [[RET:%.+]] = call {{[a-z\_\b]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) // CHECK-NEXT: ret i32 [[RET]] // CHECK-NEXT: } // CHECK-DEBUG-LABEL: define i32 @main(i32 %argc, i8** %argv) -// CHECK-DEBUG-DAG: [[AGG_CAPTURED:%.+]] = alloca %struct.anon -// CHECK-DEBUG-DAG: [[LOC_2_ADDR:%.+]] = alloca %ident_t +// CHECK-DEBUG: [[LOC_2_ADDR:%.+]] = alloca %ident_t // CHECK-DEBUG: [[KMPC_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[LOC_2_ADDR]] to i8* // CHECK-DEBUG-NEXT: [[KMPC_DEFAULT_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[DEF_LOC_2]] to i8* -// CHECK-DEBUG-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 ptrtoint (%ident_t* getelementptr (%ident_t, %ident_t* null, i32 1) to i64), i32 8, i1 false) -// CHECK-DEBUG: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon, %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0 -// CHECK-DEBUG-NEXT: store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]] -// CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 +// CHECK-DEBUG-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 24, i32 8, i1 false) +// CHECK-DEBUG: store i32 %argc, i32* [[ARGC_ADDR:%.+]], +// CHECK-DEBUG: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] -// CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8* -// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-DEBUG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC_ADDR]]) // CHECK-DEBUG-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}} // CHECK-DEBUG-NEXT: [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) // CHECK-DEBUG-NEXT: ret i32 [[RET]] // CHECK-DEBUG-NEXT: } -// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) -// CHECK: #[[FN_ATTRS:[0-9]+]] -// CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon* -// CHECK: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]] -// CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon*, %struct.anon** [[CONTEXT_ADDR]] -// CHECK-NEXT: [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon, %struct.anon* [[CONTEXT_PTR]], i32 0, i32 0 -// CHECK-NEXT: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_REF]] +// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) [[ARGC_ADDR:%[^)]+]]) +// CHECK-SAME: #[[FN_ATTRS:[0-9]+]] +// CHECK: store i32* [[ARGC_ADDR]], i32** [[ARGC_PTR_ADDR:%.+]], +// CHECK: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]] // CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] // CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]]) -// CHECK: call {{.+}} @__kmpc_cancel_barrier( // CHECK: ret void // CHECK: call {{.*}}void @{{.+terminate.*|abort}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) -// CHECK-DEBUG: #[[FN_ATTRS:[0-9]+]] -// CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon* -// CHECK-DEBUG: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]] -// CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon*, %struct.anon** [[CONTEXT_ADDR]] -// CHECK-DEBUG-NEXT: [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon, %struct.anon* [[CONTEXT_PTR]], i32 0, i32 0 -// CHECK-DEBUG-NEXT: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_REF]] +// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) [[ARGC_ADDR:%[^)]+]]) +// CHECK-DEBUG-SAME: #[[FN_ATTRS:[0-9]+]] +// CHECK-DEBUG: store i32* [[ARGC_ADDR]], i32** [[ARGC_PTR_ADDR:%.+]], +// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]] // CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] // CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[ARGC]]) -// CHECK-DEBUG: call {{.+}} @__kmpc_cancel_barrier( // CHECK-DEBUG: ret void // CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG-NEXT: unreachable @@ -96,50 +78,36 @@ int main (int argc, char **argv) { // CHECK-DEBUG-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...) // CHECK: define linkonce_odr {{[a-z\_\b]*[ ]?i32}} [[TMAIN]](i8** %argc) -// CHECK: [[AGG_CAPTURED:%.+]] = alloca %struct.anon.0 -// CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0, %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0 -// CHECK-NEXT: store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]] -// CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8* -// CHECK-NEXT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK: store i8** %argc, i8*** [[ARGC_ADDR:%.+]], +// CHECK-NEXT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8***)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8*** [[ARGC_ADDR]]) // CHECK-NEXT: ret i32 0 // CHECK-NEXT: } // CHECK-DEBUG: define linkonce_odr i32 [[TMAIN]](i8** %argc) -// CHECK-DEBUG-DAG: [[AGG_CAPTURED:%.+]] = alloca %struct.anon.0 // CHECK-DEBUG-DAG: [[LOC_2_ADDR:%.+]] = alloca %ident_t // CHECK-DEBUG: [[KMPC_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[LOC_2_ADDR]] to i8* // CHECK-DEBUG-NEXT: [[KMPC_DEFAULT_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[DEF_LOC_2]] to i8* -// CHECK-DEBUG-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 ptrtoint (%ident_t* getelementptr (%ident_t, %ident_t* null, i32 1) to i64), i32 8, i1 false) -// CHECK-DEBUG: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0, %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0 -// CHECK-DEBUG-NEXT: store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]] -// CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 +// CHECK-DEBUG-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 24, i32 8, i1 false) +// CHECK-DEBUG-NEXT: store i8** %argc, i8*** [[ARGC_ADDR:%.+]], +// CHECK-DEBUG: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* [[LOC2]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] -// CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8* -// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8***)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i8*** [[ARGC_ADDR]]) // CHECK-DEBUG-NEXT: ret i32 0 // CHECK-DEBUG-NEXT: } -// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) -// CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0* -// CHECK: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]] -// CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon.0*, %struct.anon.0** [[CONTEXT_ADDR]] -// CHECK-NEXT: [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon.0, %struct.anon.0* [[CONTEXT_PTR]], i32 0, i32 0 -// CHECK-NEXT: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_REF]] +// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc) +// CHECK: store i8*** %argc, i8**** [[ARGC_PTR_ADDR:%.+]], +// CHECK: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]] // CHECK-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]] // CHECK-NEXT: invoke {{.*}}void [[FOO1:@.+foo.+]](i8** [[ARGC]]) -// CHECK: call {{.+}} @__kmpc_cancel_barrier( // CHECK: ret void // CHECK: call {{.*}}void @{{.+terminate.*|abort}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) -// CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0* -// CHECK-DEBUG: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]] -// CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon.0*, %struct.anon.0** [[CONTEXT_ADDR]] -// CHECK-DEBUG-NEXT: [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon.0, %struct.anon.0* [[CONTEXT_PTR]], i32 0, i32 0 -// CHECK-DEBUG-NEXT: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_REF]] +// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc) +// CHECK-DEBUG: store i8*** %argc, i8**** [[ARGC_PTR_ADDR:%.+]], +// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]] // CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]] // CHECK-DEBUG-NEXT: invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]]) -// CHECK-DEBUG: call {{.+}} @__kmpc_cancel_barrier( // CHECK-DEBUG: ret void // CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG-NEXT: unreachable diff --git a/test/OpenMP/parallel_copyin_codegen.cpp b/test/OpenMP/parallel_copyin_codegen.cpp index 4aacb809573f..ff76cfe4dd6c 100644 --- a/test/OpenMP/parallel_copyin_codegen.cpp +++ b/test/OpenMP/parallel_copyin_codegen.cpp @@ -11,13 +11,12 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=TLS-LAMBDA %s // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=TLS-BLOCKS %s // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=TLS-ARRAY %s -// REQUIRES: tls // expected-no-diagnostics #ifndef ARRAY #ifndef HEADER #define HEADER -volatile int g = 1212; +volatile int g __attribute__((aligned(128))) = 1212; #pragma omp threadprivate(g) template @@ -58,10 +57,10 @@ template T tmain() { S test; test = S(); - static T t_var = 333; - static T vec[] = {3, 3}; - static S s_arr[] = {1, 2}; - static S var(3); + static T t_var __attribute__((aligned(128))) = 333; + static T vec[] __attribute__((aligned(128))) = {3, 3}; + static S s_arr[] __attribute__((aligned(128))) = {1, 2}; + static S var __attribute__((aligned(128))) (3); #pragma omp threadprivate(t_var, vec, s_arr, var) #pragma omp parallel copyin(t_var, vec, s_arr, var) { @@ -78,28 +77,24 @@ int main() { // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( - // TLS-LAMBDA: [[G_CAPTURE_TY:%.+]] = type { i{{[0-9]+}}* } // TLS-LAMBDA: [[G:@.+]] = {{.*}}thread_local {{.*}}global i{{[0-9]+}} 1212, // TLS-LAMBDA-LABEL: @main // TLS-LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* + // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) - // TLS-LAMBDA-DAG: [[G_CPY_ADDR:%.+]] = getelementptr inbounds [[G_CAPTURE_TY]], [[G_CAPTURE_TY]]* [[G_CAPTURE:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // TLS-LAMBDA-DAG: [[G_CPY_VAL:%.+]] = call i{{[0-9]+}}* [[G_CTOR:@.+]]() - // TLS-LAMBDA: store i{{[0-9]+}}* [[G_CPY_VAL]], i{{[0-9]+}}** [[G_CPY_ADDR]] - // TLS-LAMBDA: [[G_CAPTURE_CAST:%.+]] = bitcast [[G_CAPTURE_TY]]* [[G_CAPTURE]] to i8* - // TLS-LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[G_CAPTURE_CAST]] + // 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: 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* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) - // TLS-LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, [[G_CAPTURE_TY]]* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) + // TLS-LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) // threadprivate_g = g; // LAMBDA: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[G]] @@ -107,24 +102,23 @@ int main() { // LAMBDA: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[G]] to i{{[0-9]+}}), %{{.+}} // LAMBDA: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] // LAMBDA: [[NOT_MASTER]] - // LAMBDA: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], - // LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, + // LAMBDA: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], align 128 + // LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, align 128 // LAMBDA: [[DONE]] - // TLS-LAMBDA-DAG: [[G_CAPTURE_FIELD:%.+]] = getelementptr inbounds [[G_CAPTURE_TY]], [[G_CAPTURE_TY]]* {{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // TLS-LAMBDA-DAG: [[G_CAPTURE_SRC:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_CAPTURE_FIELD]] - // TLS-LAMBDA-DAG: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-LAMBDA-DAG: [[G_CAPTURE_SRC:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % + // TLS-LAMBDA-DAG: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-LAMBDA-DAG: [[G_CAPTURE_SRCC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_SRC]] to i{{[0-9]+}} // TLS-LAMBDA-DAG: [[G_CAPTURE_DSTC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_DST]] to i{{[0-9]+}} // TLS-LAMBDA: icmp ne i{{[0-9]+}} {{%.+}}, {{%.+}} // TLS-LAMBDA: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] // TLS-LAMBDA: [[NOT_MASTER]] // TLS-LAMBDA: load i{{[0-9]+}}, i{{[0-9]+}}* [[G_CAPTURE_SRC]], - // TLS-LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], + // TLS-LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128 // TLS-LAMBDA: [[DONE]] - // LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( - // TLS-LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( + // LAMBDA: call {{.*}}void @__kmpc_barrier( + // TLS-LAMBDA: call {{.*}}void @__kmpc_barrier( g = 1; // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* // TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* @@ -134,8 +128,8 @@ int main() { g = 2; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] - // TLS-LAMBDA: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() - // TLS-LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_CAPTURE_DST]] + // TLS-LAMBDA: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() + // TLS-LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128 }(); } }(); @@ -145,27 +139,23 @@ int main() { // BLOCKS-LABEL: @main // BLOCKS: call {{.*}}void {{%.+}}(i8 - // TLS-BLOCKS: [[G_CAPTURE_TY:%.+]] = type { i{{[0-9]+}}* } // TLS-BLOCKS: [[G:@.+]] = {{.*}}thread_local {{.*}}global i{{[0-9]+}} 1212, // TLS-BLOCKS-LABEL: @main // TLS-BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* + // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) - // TLS-BLOCKS-DAG: [[G_CPY_ADDR:%.+]] = getelementptr inbounds [[G_CAPTURE_TY]], [[G_CAPTURE_TY]]* [[G_CAPTURE:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // TLS-BLOCKS-DAG: [[G_CPY_VAL:%.+]] = call i{{[0-9]+}}* [[G_CTOR:@.+]]() - // TLS-BLOCKS: store i{{[0-9]+}}* [[G_CPY_VAL]], i{{[0-9]+}}** [[G_CPY_ADDR]] - // TLS-BLOCKS: [[G_CAPTURE_CAST:%.+]] = bitcast [[G_CAPTURE_TY]]* [[G_CAPTURE]] to i8* - // TLS-BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[G_CAPTURE_CAST]] + // 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: 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* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) - // TLS-BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, [[G_CAPTURE_TY]]* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) + // TLS-BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) // threadprivate_g = g; // BLOCKS: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[G]] @@ -173,30 +163,29 @@ int main() { // BLOCKS: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[G]] to i{{[0-9]+}}), %{{.+}} // BLOCKS: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] // BLOCKS: [[NOT_MASTER]] - // BLOCKS: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], - // BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, + // BLOCKS: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], align 128 + // BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, align 128 // BLOCKS: [[DONE]] - // TLS-BLOCKS-DAG: [[G_CAPTURE_FIELD:%.+]] = getelementptr inbounds [[G_CAPTURE_TY]], [[G_CAPTURE_TY]]* {{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // TLS-BLOCKS-DAG: [[G_CAPTURE_SRC:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_CAPTURE_FIELD]] - // TLS-BLOCKS-DAG: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS-DAG: [[G_CAPTURE_SRC:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % + // TLS-BLOCKS-DAG: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS-DAG: [[G_CAPTURE_SRCC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_SRC]] to i{{[0-9]+}} // TLS-BLOCKS-DAG: [[G_CAPTURE_DSTC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_DST]] to i{{[0-9]+}} // TLS-BLOCKS: icmp ne i{{[0-9]+}} {{%.+}}, {{%.+}} // TLS-BLOCKS: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] // TLS-BLOCKS: [[NOT_MASTER]] // TLS-BLOCKS: load i{{[0-9]+}}, i{{[0-9]+}}* [[G_CAPTURE_SRC]], - // TLS-BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], + // TLS-BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128 // TLS-BLOCKS: [[DONE]] - // BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( - // TLS-BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( + // BLOCKS: call {{.*}}void @__kmpc_barrier( + // TLS-BLOCKS: call {{.*}}void @__kmpc_barrier( g = 1; // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 - // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_CAPTURE_DST]] // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} // TLS-BLOCKS: call {{.*}}void {{%.+}}(i8 @@ -211,7 +200,7 @@ int main() { // BLOCKS: ret // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} - // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_CAPTURE_DST]] // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} // TLS-BLOCKS: ret @@ -241,8 +230,8 @@ int main() { // CHECK-LABEL: @main // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[TEST]], [[S_FLOAT_TY]]* -// 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]+}}*, {{%.+}}*)* [[MAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), 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]+}}*, {{%.+}}*)* [[MAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*)) +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*)) // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret @@ -250,28 +239,18 @@ int main() { // TLS-CHECK-LABEL: @main // TLS-CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // TLS-CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[TEST]], [[S_FLOAT_TY]]* -// TLS-CHECK-DAG: store i{{[0-9]+}}* [[T_VAR]], i{{[0-9]+}}** [[T_VAR_FIELD:%.+]], -// TLS-CHECK-DAG: store [2 x i{{[0-9]+}}]* [[VEC]], [2 x i{{[0-9]+}}]** [[VEC_FIELD:%.+]], -// TLS-CHECK-DAG: store [2 x [[S_FLOAT_TY]]]* [[S_ARR]], [2 x [[S_FLOAT_TY]]]** [[S_ARR_FIELD:%.+]], -// TLS-CHECK-DAG: store [[S_FLOAT_TY]]* [[VAR]], [[S_FLOAT_TY]]** [[VAR_FIELD:%.+]], -// TLS-CHECK-DAG: [[T_VAR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-CHECK-DAG: [[VEC_FIELD]] = getelementptr inbounds {{.*}} -// TLS-CHECK-DAG: [[S_ARR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-CHECK-DAG: [[VAR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-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]+}}*, {{%.+}}*)* [[MAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// TLS-CHECK-DAG: store i{{[0-9]+}}* [[T_VAR]], i{{[0-9]+}}** [[T_VAR_FIELD:%.+]], -// TLS-CHECK-DAG: [[T_VAR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-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]+}}*, {{%.+}}*)* [[MAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// TLS-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_FLOAT_TY]]]*, [[S_FLOAT_TY]]*)* [[MAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), +// TLS-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]+}}*, i32*)* [[MAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), // TLS-CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // TLS-CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // TLS-CHECK: ret -// CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// TLS-CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // TLS-CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // threadprivate_t_var = t_var; @@ -283,8 +262,11 @@ int main() { // CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** [[MASTER_FIELD]] +// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** % +// TLS-CHECK: [[MASTER_REF2:%.+]] = load [2 x i32]*, [2 x i32]** % +// TLS-CHECK: [[MASTER_REF3:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** % +// TLS-CHECK: [[MASTER_REF4:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % + // TLS-CHECK: [[MASTER_LONG:%.+]] = ptrtoint i32* [[MASTER_REF]] to i{{[0-9]+}} // TLS-CHECK: icmp ne i{{[0-9]+}} [[MASTER_LONG]], ptrtoint (i{{[0-9]+}}* [[T_VAR]] to i{{[0-9]+}}) // TLS-CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] @@ -296,9 +278,7 @@ int main() { // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[VEC]] // CHECK: call void @llvm.memcpy{{.*}}(i8* %{{.+}}, i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load [2 x i32]*, [2 x i32]** [[MASTER_FIELD]] -// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x i32]* [[MASTER_REF]] to i8* +// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x i32]* [[MASTER_REF2]] to i8* // TLS-CHECK: call void @llvm.memcpy{{.*}}(i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), i8* [[MASTER_CAST]] // threadprivate_s_arr = s_arr; @@ -311,9 +291,7 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}) // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[MASTER_FIELD]] -// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[MASTER_REF]] to [[S_FLOAT_TY]]* +// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[MASTER_REF3]] to [[S_FLOAT_TY]]* // TLS-CHECK-DAG: [[S_ARR_SRC_BEGIN:%.+]] = phi [[S_FLOAT_TY]]* {{.*}}[[MASTER_CAST]] // TLS-CHECK-DAG: [[S_ARR_DST_BEGIN:%.+]] = phi [[S_FLOAT_TY]]* {{.*}}getelementptr inbounds ([2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0) // TLS-CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}) @@ -328,24 +306,22 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{%.+}}, [[S_FLOAT_TY]]* {{.*}}[[VAR]]) // CHECK: [[DONE]] -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[MASTER_FIELD]] -// TLS-CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.*}}[[VAR]], [[S_FLOAT_TY]]* {{.*}}[[MASTER_REF]]) +// TLS-CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.*}}[[VAR]], [[S_FLOAT_TY]]* {{.*}}[[MASTER_REF4]]) -// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // TLS-CHECK: ret void -// CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// TLS-CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // TLS-CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // threadprivate_t_var = t_var; @@ -358,8 +334,8 @@ int main() { // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, // CHECK: [[DONE]] -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** [[MASTER_FIELD]] +// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** % + // TLS-CHECK: [[MASTER_LONG:%.+]] = ptrtoint i32* [[MASTER_REF]] to i{{[0-9]+}} // TLS-CHECK: icmp ne i{{[0-9]+}} [[MASTER_LONG]], ptrtoint (i{{[0-9]+}}* [[T_VAR]] to i{{[0-9]+}}) // TLS-CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] @@ -368,44 +344,34 @@ int main() { // TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[T_VAR]] // TLS-CHECK: [[DONE]] -// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // TLS-CHECK: ret void // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[TEST]], [[S_INT_TY]]* -// 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]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), 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]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*)) +// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[TMAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*)) // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // TLS-CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // TLS-CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // TLS-CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[TEST]], [[S_INT_TY]]* -// TLS-CHECK-DAG: store i{{[0-9]+}}* [[TMAIN_T_VAR]], i{{[0-9]+}}** [[T_VAR_FIELD:%.+]], -// TLS-CHECK-DAG: store [2 x i{{[0-9]+}}]* [[TMAIN_VEC]], [2 x i{{[0-9]+}}]** [[VEC_FIELD:%.+]], -// TLS-CHECK-DAG: store [2 x [[S_INT_TY]]]* [[TMAIN_S_ARR]], [2 x [[S_INT_TY]]]** [[S_ARR_FIELD:%.+]], -// TLS-CHECK-DAG: store [[S_INT_TY]]* [[TMAIN_VAR]], [[S_INT_TY]]** [[VAR_FIELD:%.+]], -// TLS-CHECK-DAG: [[T_VAR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-CHECK-DAG: [[VEC_FIELD]] = getelementptr inbounds {{.*}} -// TLS-CHECK-DAG: [[S_ARR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-CHECK-DAG: [[VAR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-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]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// TLS-CHECK-DAG: store i{{[0-9]+}}* [[TMAIN_T_VAR]], i{{[0-9]+}}** [[T_VAR_FIELD:%.+]], -// TLS-CHECK-DAG: [[T_VAR_FIELD]] = getelementptr inbounds {{.*}} -// TLS-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]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// TLS-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 (i32*, i32*, ...)*), +// TLS-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]+}}*, i32*)* [[TMAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), // -// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], // -// TLS-CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// TLS-CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // TLS-CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // threadprivate_t_var = t_var; @@ -414,25 +380,26 @@ int main() { // CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}), %{{.+}} // CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] // CHECK: [[NOT_MASTER]] -// CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[TMAIN_T_VAR]], -// CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, +// CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[TMAIN_T_VAR]], align 128 +// CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, align 128 + +// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** % +// TLS-CHECK: [[MASTER_REF1:%.+]] = load [2 x i32]*, [2 x i32]** % +// TLS-CHECK: [[MASTER_REF2:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % +// TLS-CHECK: [[MASTER_REF3:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** [[MASTER_FIELD]] // TLS-CHECK: [[MASTER_LONG:%.+]] = ptrtoint i32* [[MASTER_REF]] to i{{[0-9]+}} // TLS-CHECK: icmp ne i{{[0-9]+}} [[MASTER_LONG]], ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}) // TLS-CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] // TLS-CHECK: [[NOT_MASTER]] -// TLS-CHECK: [[MASTER_VAL:%.+]] = load i32, i32* [[MASTER_REF]] -// TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[TMAIN_T_VAR]] +// TLS-CHECK: [[MASTER_VAL:%.+]] = load i32, i32* [[MASTER_REF]], +// TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[TMAIN_T_VAR]], align 128 // threadprivate_vec = vec; // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_VEC]] // CHECK: call {{.*}}void @llvm.memcpy{{.*}}(i8* %{{.+}}, i8* bitcast ([2 x i{{[0-9]+}}]* [[TMAIN_VEC]] to i8*), -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load [2 x i32]*, [2 x i32]** [[MASTER_FIELD]] -// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x i32]* [[MASTER_REF]] to i8* +// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x i32]* [[MASTER_REF1]] to i8* // TLS-CHECK: call void @llvm.memcpy{{.*}}(i8* bitcast ([2 x i{{[0-9]+}}]* [[TMAIN_VEC]] to i8*), i8* [[MASTER_CAST]] // threadprivate_s_arr = s_arr; @@ -445,9 +412,7 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}) // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[MASTER_FIELD]] -// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[MASTER_REF]] to [[S_INT_TY]]* +// TLS-CHECK: [[MASTER_CAST:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[MASTER_REF2]] to [[S_INT_TY]]* // TLS-CHECK-DAG: [[S_ARR_SRC_BEGIN:%.+]] = phi [[S_INT_TY]]* {{.*}}[[MASTER_CAST]] // TLS-CHECK-DAG: [[S_ARR_DST_BEGIN:%.+]] = phi [[S_INT_TY]]* {{.*}}getelementptr inbounds ([2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[TMAIN_S_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0) // TLS-CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}) @@ -462,24 +427,22 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{%.+}}, [[S_INT_TY]]* {{.*}}[[TMAIN_VAR]]) // CHECK: [[DONE]] -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[MASTER_FIELD]] -// TLS-CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.*}}[[TMAIN_VAR]], [[S_INT_TY]]* {{.*}}[[MASTER_REF]]) +// TLS-CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.*}}[[TMAIN_VAR]], [[S_INT_TY]]* {{.*}}[[MASTER_REF3]]) -// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // TLS-CHECK: ret void -// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) +// TLS-CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // TLS-CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // threadprivate_t_var = t_var; @@ -492,8 +455,8 @@ int main() { // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, // CHECK: [[DONE]] -// TLS-CHECK: [[MASTER_FIELD:%.+]] = getelementptr inbounds {{.+}} -// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** [[MASTER_FIELD]] +// TLS-CHECK: [[MASTER_REF:%.+]] = load i32*, i32** % + // TLS-CHECK: [[MASTER_LONG:%.+]] = ptrtoint i32* [[MASTER_REF]] to i{{[0-9]+}} // TLS-CHECK: icmp ne i{{[0-9]+}} [[MASTER_LONG]], ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}) // TLS-CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] @@ -502,18 +465,17 @@ int main() { // TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[TMAIN_T_VAR]] // TLS-CHECK: [[DONE]] -// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // CHECK: ret void // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], -// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) +// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) // TLS-CHECK: ret void #endif #else // ARRAY-LABEL: array_func -// TLS-ARRAY: [[ARR_CAPTURETY:%.+]] = type { [2 x {{.*}}]*, [2 x {{.*}}]* } // TLS-ARRAY-LABEL: array_func struct St { @@ -531,15 +493,10 @@ void array_func() { // ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* bitcast ([2 x i32]* @{{.+}} to i8*), i64 8, i32 4, i1 false) // ARRAY: call dereferenceable(8) %struct.St* @{{.+}}(%struct.St* %{{.+}}, %struct.St* dereferenceable(8) %{{.+}}) -// TLS-ARRAY-DAG: [[ARR_CAP1:%.+]] = getelementptr inbounds [[ARR_CAPTURETY]], [[ARR_CAPTURETY]]* {{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// TLS-ARRAY-DAG: [[ARR_CAP2:%.+]] = getelementptr inbounds [[ARR_CAPTURETY]], [[ARR_CAPTURETY]]* {{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// TLS-ARRAY-DAG: store [2 x {{.*}}]* @{{.*}}, [2 x {{.*}}]** [[ARR_CAP1]] -// TLS-ARRAY-DAG: store [2 x {{.*}}]* @{{.*}}, [2 x {{.*}}]** [[ARR_CAP2]] // TLS-ARRAY: @__kmpc_fork_call( -// TLS-ARRAY-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([2 x i32]* @{{.+}} to i8*), i8* [[REF:%.+]], i64 8, i32 4, i1 false) -// TLS-ARRAY-DAG: [[REF]] = bitcast [2 x i32]* [[REFT:%.+]] to i8* -// TLS-ARRAY-DAG: [[REFT]] = load [2 x i32]*, [2 x i32]** [[FIELDADDR:%.+]], -// TLS-ARRAY-DAG: [[FIELDADDR]] = getelementptr inbounds [[ARR_CAPTURETY]], [[ARR_CAPTURETY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} +// TLS-ARRAY: [[REFT:%.+]] = load [2 x i32]*, [2 x i32]** [[ADDR:%.+]], +// TLS-ARRAY: [[REF:%.+]] = bitcast [2 x i32]* [[REFT]] to i8* +// TLS-ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([2 x i32]* @{{.+}} to i8*), i8* [[REF]], i64 8, i32 4, i1 false) // TLS-ARRAY: call dereferenceable(8) %struct.St* @{{.+}}(%struct.St* %{{.+}}, %struct.St* dereferenceable(8) %{{.+}}) #pragma omp threadprivate(a, s) diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp index 6e0f014f4d9e..d0da8cea87ac 100644 --- a/test/OpenMP/parallel_firstprivate_codegen.cpp +++ b/test/OpenMP/parallel_firstprivate_codegen.cpp @@ -16,7 +16,7 @@ struct St { ~St() {} }; -volatile int g = 1212; +volatile int g __attribute__((aligned(128))) = 1212; template struct S { @@ -31,17 +31,15 @@ struct 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]+}} } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* template T tmain() { S test; - T t_var = T(); - T vec[] = {1, 2}; - S s_arr[] = {1, 2}; - S var(3); + T t_var __attribute__((aligned(128))) = T(); + T vec[] __attribute__((aligned(128))) = {1, 2}; + S s_arr[] __attribute__((aligned(128))) = {1, 2}; + S var __attribute__((aligned(128))) (3); #pragma omp parallel firstprivate(t_var, vec, s_arr, var) { vec[0] = t_var; @@ -53,40 +51,46 @@ T tmain() { } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] - // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel firstprivate(g) + // 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* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) - // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // LAMBDA: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] - // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] - // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]] - // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] - // LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // 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: [[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( 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: [[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: 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -97,33 +101,42 @@ int main() { // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] - // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel firstprivate(g) + // 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* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) - // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // BLOCKS: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] - // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] - // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]] - // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] - // BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // 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: [[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( 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-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-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 4; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -135,10 +148,11 @@ int main() { int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp parallel firstprivate(t_var, vec, s_arr, var) +#pragma omp parallel firstprivate(t_var, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 2; } #pragma omp parallel firstprivate(t_var) {} @@ -149,29 +163,29 @@ int main() { // CHECK: define {{.*}}i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_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]+}}*, [2 x i32]*, i32*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] 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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// 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: [[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: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], + +// 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_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: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // 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_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[S_ARR_REF_PTR]], // 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 @@ -182,42 +196,41 @@ int main() { // 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: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_REF_PTR]], // 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: [[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 {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) + +// 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-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 {{.*}} 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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] 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]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) -// 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: 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 +// 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: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], -// 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: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], + +// 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]], -// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]], +// 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 @@ -228,44 +241,62 @@ int main() { // 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: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], // 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 {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // 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 #endif #else -// ARRAY-LABEL: array_func 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 parallel firstprivate(s, vla1, vla2) + vla1[b] = vla2[1][n - 1] = a = b; + } }; +// ARRAY-LABEL: array_func void array_func(float a[3], St s[2], int n, long double vla1[n]) { - double vla2[n]; + double vla2[n][n] __attribute__((aligned(128))); // ARRAY: @__kmpc_fork_call( -// ARRAY: [[PRIV_A:%.+]] = alloca float* -// ARRAY: [[PRIV_S:%.+]] = alloca %struct.St* -// ARRAY: [[PRIV_VLA1:%.+]] = alloca x86_fp80* -// ARRAY: store float* %{{.+}}, float** [[PRIV_A]], -// ARRAY: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], -// ARRAY: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], +// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float**, +// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St**, +// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80**, +// 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 double* %{{.+}}, double** [[PRIV_VLA2]], // ARRAY: call i8* @llvm.stacksave() // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8 -// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* %{{.+}}, i64 [[SIZE]], i32 8, i1 false) -// ARRAY: call void @llvm.stackrestore(i8* +// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* %{{.+}}, i64 [[SIZE]], i32 128, i1 false) #pragma omp parallel firstprivate(a, s, vla1, vla2) + s[0].St_func(s, n, vla1); ; } + +// 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_VLA2:%.+]] = alloca double*, +// 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 +// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* %{{.+}}, i64 [[SIZE]], i32 128, i1 false) #endif diff --git a/test/OpenMP/parallel_firstprivate_messages.cpp b/test/OpenMP/parallel_firstprivate_messages.cpp index c6f8dbe138d5..fc0eb4c7d358 100644 --- a/test/OpenMP/parallel_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_firstprivate_messages.cpp @@ -61,7 +61,8 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; + static int m; #pragma omp parallel firstprivate // expected-error {{expected '(' after 'firstprivate'}} #pragma omp parallel firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel firstprivate () // expected-error {{expected expression}} @@ -83,7 +84,8 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel shared(i) #pragma omp parallel firstprivate(i) - #pragma omp parallel firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} + #pragma omp parallel firstprivate(j) + #pragma omp parallel firstprivate(m) foo(); return 0; diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp index f2899ee16ef5..c4be521455df 100644 --- a/test/OpenMP/parallel_for_ast_print.cpp +++ b/test/OpenMP/parallel_for_ast_print.cpp @@ -15,25 +15,35 @@ T tmain(T argc) { // CHECK: static T a; static T g; #pragma omp threadprivate(g) -#pragma omp parallel for schedule(dynamic) default(none) copyin(g) - // CHECK: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) +#pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) + // CHECK: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) 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 parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered if (argc) num_threads(N) default(shared) shared(e) reduction(+ : h) - for (int i = 0; i < 10; ++i) - for (int j = 0; j < 10; ++j) - for (int j = 0; j < 10; ++j) - for (int j = 0; j < 10; ++j) - for (int j = 0; j < 10; ++j) +#pragma omp 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 parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered if(argc) num_threads(N) default(shared) shared(e) reduction(+: h) - // CHECK-NEXT: for (int i = 0; i < 10; ++i) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) - // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: #pragma omp 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(); return T(); } @@ -44,18 +54,18 @@ int main(int argc, char **argv) { // CHECK: static int a; static float g; #pragma omp threadprivate(g) -#pragma omp parallel for schedule(guided, argc) default(none) copyin(g) - // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) +#pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) + // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) 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 parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) +#pragma omp parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (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 parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) - // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(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(); return (tmain(argc) + tmain(argv[0][0])); diff --git a/test/OpenMP/parallel_for_codegen.cpp b/test/OpenMP/parallel_for_codegen.cpp index 9fda8404c6e7..036fa37cf91b 100644 --- a/test/OpenMP/parallel_for_codegen.cpp +++ b/test/OpenMP/parallel_for_codegen.cpp @@ -1,7 +1,7 @@ // 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 -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -O1 -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=CLEANUP // REQUIRES: x86-registered-target // expected-no-diagnostics @@ -9,25 +9,19 @@ #define HEADER // CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } -// CHECK-DAG: [[CAP_TY:%.+]] = type { i8* } // CHECK-LABEL: with_var_schedule void with_var_schedule() { double a = 5; // CHECK: [[CHUNK_SIZE:%.+]] = fptosi double %{{.+}}to i8 // CHECK: store i8 %{{.+}}, i8* [[CHUNK:%.+]], -// CHECK: [[CHUNK_REF:%.+]] = getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 -// CHECK: store i8* [[CHUNK]], i8** [[CHUNK_REF]], -// CHECK: [[BITCAST:%.+]] = bitcast [[CAP_TY]]* [[CAP_ARG]] to i8* -// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, i8* [[BITCAST]]) +// CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, i8* [[CHUNK]]) -// CHECK: [[CHUNK_REF:%.+]] = getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* %{{.+}}, i{{.+}} 0, i{{.+}} 0 -// CHECK: [[CHUNK:%.+]] = load i8*, i8** [[CHUNK_REF]], +// CHECK: [[CHUNK:%.+]] = load i8*, i8** % // CHECK: [[CHUNK_VAL:%.+]] = load i8, i8* [[CHUNK]], // CHECK: [[CHUNK_SIZE:%.+]] = sext i8 [[CHUNK_VAL]] to i64 // CHECK: call void @__kmpc_for_static_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC:@[^,]+]], i32 [[GTID:%[^,]+]], i32 33, i32* [[IS_LAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]], i64 1, i64 [[CHUNK_SIZE]]) // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: __kmpc_barrier #pragma omp parallel for schedule(static, char(a)) for (unsigned long long i = 1; i < 2; ++i) { } @@ -36,8 +30,8 @@ void with_var_schedule() { // 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 parallel for -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -73,15 +67,14 @@ void without_schedule_clause(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // 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 parallel for schedule(static) -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -117,15 +110,14 @@ void static_not_chunked(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // 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 parallel for schedule(static, 5) -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -180,15 +172,14 @@ void static_chunked(float *a, float *b, float *c, float *d) { // CHECK: [[O_LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // CHECK: ret void } // CHECK-LABEL: define {{.*void}} @{{.*}}dynamic1{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void dynamic1(float *a, float *b, float *c, float *d) { #pragma omp parallel for schedule(dynamic) -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -225,15 +216,14 @@ void dynamic1(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // CHECK: ret void } // CHECK-LABEL: define {{.*void}} @{{.*}}guided7{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void guided7(float *a, float *b, float *c, float *d) { #pragma omp parallel for schedule(guided, 7) -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -270,7 +260,6 @@ void guided7(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // CHECK: ret void } @@ -279,8 +268,8 @@ void test_auto(float *a, float *b, float *c, float *d) { unsigned int x = 0; unsigned int y = 0; #pragma omp parallel for schedule(auto) collapse(2) -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 6, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -320,9 +309,6 @@ void test_auto(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], -// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // CHECK: ret void } @@ -330,8 +316,8 @@ void test_auto(float *a, float *b, float *c, float *d) { void runtime(float *a, float *b, float *c, float *d) { int x = 0; #pragma omp parallel for collapse(2) schedule(runtime) -// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}, float** dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], // CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], @@ -367,9 +353,6 @@ void runtime(float *a, float *b, float *c, float *d) { } // CHECK: [[LOOP1_END]] // CHECK: [[O_LOOP1_END]] -// CHECK: [[GTID_REF:%.+]] = load i32*, i32** [[GTID_REF_ADDR]], -// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_REF]], -// CHECK: call {{.+}} @__kmpc_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) // CHECK: ret void } @@ -378,29 +361,27 @@ int foo() {return 0;}; // TERM_DEBUG-LABEL: parallel_for // CLEANUP: parallel_for -void parallel_for(float *a) { -#pragma omp parallel for schedule(static, 5) +void parallel_for(float *a, int n) { + float arr[n]; +#pragma omp parallel for schedule(static, 5) private(arr) // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_for_static_init_4u({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke i32 {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]] - // TERM_DEBUG: call {{.+}} @__kmpc_barrier({{.+}}), !dbg [[DBG_LOC_CANCEL:![0-9]+]] // TERM_DEBUG: [[TERM_LPAD]] // TERM_DEBUG: call void @__clang_call_terminate // TERM_DEBUG: unreachable // CLEANUP-NOT: __kmpc_global_thread_num // CLEANUP: call void @__kmpc_for_static_init_4u({{.+}}) // CLEANUP: call void @__kmpc_for_static_fini({{.+}}) - // CLEANUP: call {{.+}} @__kmpc_barrier({{.+}}) for (unsigned i = 131071; i <= 2147483647; i += 127) - a[i] += foo(); + a[i] += foo() + arr[i]; } // Check source line corresponds to "#pragma omp parallel for schedule(static, 5)" above: // TERM_DEBUG-DAG: [[DBG_LOC_START]] = !DILocation(line: [[@LINE-4]], -// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-20]], -// TERM_DEBUG-DAG: [[DBG_LOC_CANCEL]] = !DILocation(line: [[@LINE-21]], +// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-18]], #endif // HEADER diff --git a/test/OpenMP/parallel_for_collapse_messages.cpp b/test/OpenMP/parallel_for_collapse_messages.cpp index 042b819fe58e..6e5f71ff1672 100644 --- a/test/OpenMP/parallel_for_collapse_messages.cpp +++ b/test/OpenMP/parallel_for_collapse_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp 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 parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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 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]; @@ -41,7 +41,7 @@ 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 (1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp 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 parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}} foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}} @@ -63,7 +63,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/parallel_for_firstprivate_messages.cpp b/test/OpenMP/parallel_for_firstprivate_messages.cpp index 2c762b49b39e..c9a69dab2cb2 100644 --- a/test/OpenMP/parallel_for_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_for_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (int k = 0; k < argc; ++k) ++k; @@ -102,9 +102,6 @@ int foomain(int argc, char **argv) { #pragma omp 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 for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}} - for (int k = 0; k < argc; ++k) - ++k; #pragma omp parallel { int v = 0; @@ -117,7 +114,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp parallel for firstprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for firstprivate(i) @@ -153,7 +150,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (i = 0; i < argc; ++i) foo(); @@ -228,7 +225,7 @@ int main(int argc, char **argv) { #pragma omp parallel for firstprivate(xa) // OK: may be firstprivate for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp parallel for firstprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} @@ -255,6 +252,10 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for' directive may not be firstprivate, predetermined as private}} foo(); + static int si; +#pragma omp parallel for firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/parallel_for_if_messages.cpp b/test/OpenMP/parallel_for_if_messages.cpp index cf2a3b431dc7..2b7a5f7e2b3e 100644 --- a/test/OpenMP/parallel_for_if_messages.cpp +++ b/test/OpenMP/parallel_for_if_messages.cpp @@ -34,6 +34,20 @@ int tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for if(argc) for (i = 0; i < argc; ++i) foo(); + #pragma omp 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 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 parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp 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(); return 0; } @@ -64,6 +78,20 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp 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 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 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 parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp 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(); return tmain(argc, argv); } diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp index 09bed02a05f9..ccfe2ea407b1 100644 --- a/test/OpenMP/parallel_for_lastprivate_messages.cpp +++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp @@ -17,7 +17,7 @@ public: S2(S2 &s2) : a(s2.a) {} S2 &operator=(const S2 &); const S2 &operator=(const S2 &) const; - static float S2s; + 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}} @@ -67,7 +67,7 @@ int foomain(int argc, char **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (int k = 0; k < argc; ++k) ++k; @@ -104,9 +104,6 @@ int foomain(int argc, char **argv) { #pragma omp 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 for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}} - for (int k = 0; k < argc; ++k) - ++k; #pragma omp parallel { int v = 0; @@ -119,7 +116,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp parallel for lastprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for lastprivate(i) @@ -144,7 +141,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (i = 0; i < argc; ++i) foo(); @@ -191,7 +188,7 @@ int main(int argc, char **argv) { #pragma omp parallel for lastprivate(xa) // OK for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(S2::S2s) +#pragma omp parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} @@ -223,7 +220,7 @@ int main(int argc, char **argv) { #pragma omp parallel for lastprivate(xa) for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp parallel for lastprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} @@ -232,5 +229,10 @@ int main(int argc, char **argv) { #pragma omp parallel for lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp parallel for lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 2; + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/parallel_for_linear_codegen.cpp b/test/OpenMP/parallel_for_linear_codegen.cpp new file mode 100644 index 000000000000..940d6032a14a --- /dev/null +++ b/test/OpenMP/parallel_for_linear_codegen.cpp @@ -0,0 +1,249 @@ +// 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 +// expected-no-diagnostics +// REQUIRES: x86-registered-target +#ifndef HEADER +#define HEADER + +template +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + S &operator=(const S &); + operator T() { return T(); } + ~S() {} +}; + +volatile int g = 1212; +float f; +char cnt; + +// CHECK: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK: [[S_INT_TY:%.+]] = type { i32 } +// CHECK-DAG: [[F:@.+]] = global float 0.0 +// CHECK-DAG: [[CNT:@.+]] = global i8 0 +template +T tmain() { + S test; + T *pvar = &test.f; + T lvar = T(); +#pragma omp parallel for linear(pvar, lvar) + for (int i = 0; i < 2; ++i) { + ++pvar, ++lvar; + } + return T(); +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) +#pragma omp parallel for linear(g:5) + for (int i = 0; i < 2; ++i) { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) + // LAMBDA: alloca i{{[0-9]+}}, + // LAMBDA: [[G_START_ADDR:%.+]] = 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i32 0, + // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // LAMBDA: [[VAL:%.+]] = load i32, i32* [[G_START_ADDR]] + // LAMBDA: [[CNT:%.+]] = load i32, i32* + // LAMBDA: [[MUL:%.+]] = mul nsw i32 [[CNT]], 5 + // LAMBDA: [[ADD:%.+]] = add nsw i32 [[VAL]], [[MUL]] + // LAMBDA: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]], + // LAMBDA: [[VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]], + // LAMBDA: [[ADD:%.+]] = add nsw i32 [[VAL]], 5 + // LAMBDA: store i32 [[ADD]], i32* [[G_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: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) + g += 5; + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8 + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) +#pragma omp parallel for linear(g:5) + for (int i = 0; i < 2; ++i) { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) + // BLOCKS: alloca i{{[0-9]+}}, + // BLOCKS: [[G_START_ADDR:%.+]] = 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store i32 0, + // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // BLOCKS: [[VAL:%.+]] = load i32, i32* [[G_START_ADDR]] + // BLOCKS: [[CNT:%.+]] = load i32, i32* + // BLOCKS: [[MUL:%.+]] = mul nsw i32 [[CNT]], 5 + // BLOCKS: [[ADD:%.+]] = add nsw i32 [[VAL]], [[MUL]] + // BLOCKS: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]], + // BLOCKS: [[VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]], + // BLOCKS: [[ADD:%.+]] = add nsw i32 [[VAL]], 5 + // BLOCKS: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8 + // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) + g += 5; + g = 1; + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S test; + float *pvar = &test.f; + long long lvar = 0; +#pragma omp parallel for linear(pvar, lvar : 3) + for (int i = 0; i < 2; ++i) { + pvar += 3, lvar += 3; + } + return tmain(); +#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: 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]+}}*, float**, i64*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: = call {{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call void [[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(8) %{{.+}}, i64* dereferenceable(8) %{{.+}}) +// CHECK: alloca i{{[0-9]+}}, +// CHECK: [[PVAR_START:%.+]] = alloca float*, +// CHECK: [[LVAR_START:%.+]] = alloca i64, +// 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: [[PVAR_PRIV:%.+]] = alloca float*, +// CHECK: [[LVAR_PRIV:%.+]] = alloca i64, +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] + +// CHECK: [[PVAR_REF:%.+]] = load float**, float*** % +// CHECK: [[LVAR_REF:%.+]] = load i64*, i64** % + +// Check for default initialization. +// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_REF]], +// CHECK: store float* [[PVAR_VAL]], float** [[PVAR_START]], +// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_REF]], +// CHECK: store i64 [[LVAR_VAL]], i64* [[LVAR_START]], +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3 +// CHECK: [[IDX:%.+]] = sext i32 [[MUL]] to i64 +// CHECK: [[PTR:%.+]] = getelementptr inbounds float, float* [[PVAR_VAL]], i64 [[IDX]] +// CHECK: store float* [[PTR]], float** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3 +// CHECK: [[CONV:%.+]] = sext i32 [[MUL]] to i64 +// CHECK: [[VAL:%.+]] = add nsw i64 [[LVAR_VAL]], [[CONV]] +// CHECK: store i64 [[VAL]], i64* [[LVAR_PRIV]], +// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_PRIV]] +// CHECK: [[PTR:%.+]] = getelementptr inbounds float, float* [[PVAR_VAL]], i64 3 +// CHECK: store float* [[PTR]], float** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_PRIV]], +// CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3 +// CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]], +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) +// CHECK: ret void + +// 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]+}} 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 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*, +// CHECK: [[LVAR_START:%.+]] = alloca i32, +// 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: [[PVAR_PRIV:%.+]] = alloca i32*, +// CHECK: [[LVAR_PRIV:%.+]] = alloca i32, +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] + +// CHECK: [[PVAR_REF:%.+]] = load i32**, i32*** % +// CHECK: [[LVAR_REF:%.+]] = load i32*, i32** % + +// Check for default initialization. +// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_REF]], +// CHECK: store i32* [[PVAR_VAL]], i32** [[PVAR_START]], +// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_REF]], +// CHECK: store i32 [[LVAR_VAL]], i32* [[LVAR_START]], +// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) +// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 1 +// CHECK: [[IDX:%.+]] = sext i32 [[MUL]] to i64 +// CHECK: [[PTR:%.+]] = getelementptr inbounds i32, i32* [[PVAR_VAL]], i64 [[IDX]] +// CHECK: store i32* [[PTR]], i32** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_START]], +// CHECK: [[CNT:%.+]] = load i32, i32* +// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 1 +// CHECK: [[VAL:%.+]] = add nsw i32 [[LVAR_VAL]], [[MUL]] +// CHECK: store i32 [[VAL]], i32* [[LVAR_PRIV]], +// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_PRIV]] +// CHECK: [[PTR:%.+]] = getelementptr inbounds i32, i32* [[PVAR_VAL]], i32 1 +// CHECK: store i32* [[PTR]], i32** [[PVAR_PRIV]], +// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_PRIV]], +// CHECK: [[ADD:%.+]] = add nsw i32 [[LVAR_VAL]], 1 +// CHECK: store i32 [[ADD]], i32* [[LVAR_PRIV]], +// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) +// CHECK: ret void +#endif + diff --git a/test/OpenMP/parallel_for_linear_messages.cpp b/test/OpenMP/parallel_for_linear_messages.cpp new file mode 100644 index 000000000000..7272aada92a0 --- /dev/null +++ b/test/OpenMP/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 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 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 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 parallel for linear(z : B : ib) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel for linear(B : B::bfoo()) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel for linear(X::x : ::z) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel for linear(B, ::z, X::x) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel for linear(::z) + for (int i = 0; i < 10; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp parallel for linear(B::bfoo()) + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel for linear(B::ib, B : C1 + C2) + for (int i = 0; i < 10; ++i) + ; +} + +template +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 parallel for linear(ind2 : L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template +int test_warn() { + int ind2 = 0; +// expected-warning@+1 {{zero linear step (ind2 should probably be const)}} +#pragma omp 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 +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp parallel for linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(argc : 5) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear(a, b : B::ib) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp parallel for linear(v : i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel for linear(j) + for (int k = 0; k < argc; ++k) + ++k; + int v = 0; +#pragma omp parallel for linear(v : j) + for (int k = 0; k < argc; ++k) { + ++k; + v += j; + } +#pragma omp 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 parallel for linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear(a, b) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp 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 parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(i : 4) + for (int k = 0; k < argc; ++k) { + ++k; + i += 4; + } + } +#pragma omp parallel for linear(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for linear(i) + for (int k = 0; k < argc; ++k) + ++k; + + foomain(argc, argv); + return 0; +} + diff --git a/test/OpenMP/parallel_for_loop_messages.cpp b/test/OpenMP/parallel_for_loop_messages.cpp index 7d14a3c9b74c..2bb32bdfc176 100644 --- a/test/OpenMP/parallel_for_loop_messages.cpp +++ b/test/OpenMP/parallel_for_loop_messages.cpp @@ -10,6 +10,7 @@ public: }; static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} #pragma omp threadprivate(sii) static int globalii; @@ -54,32 +55,32 @@ int test_iteration_spaces() { for (double 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}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (int &ref = ii; ref < 10; ref++) { } -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (int i; i < 10; i++) c[i] = a[i]; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (int i = 0, j = 0; i < 10; ++i) c[i] = a[i]; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp 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 must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (ii + 1; ii < 10; ++ii) c[ii] = a[ii]; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (c[ii] = 0; ii < 10; ++ii) c[ii] = a[ii]; @@ -242,7 +243,6 @@ int test_iteration_spaces() { for (ii = 0; ii < 10; ii++) c[ii] = a[ii]; -// expected-error@+3 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}} // expected-note@+2 {{defined as linear}} // expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be linear, predetermined as private}} #pragma omp parallel for linear(ii) @@ -258,6 +258,7 @@ int test_iteration_spaces() { c[ii] = a[ii]; { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be threadprivate or thread local, predetermined as private}} #pragma omp parallel for for (sii = 0; sii < 10; sii += 1) c[sii] = a[sii]; @@ -375,7 +376,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for for (GoodIter I = begin; I < end; ++I) ++I; -// expected-error@+2 {{variable must be of integer or random access iterator type}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (GoodIter &I = begin; I < end; ++I) ++I; @@ -406,7 +407,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for for (begin = begin0; begin < end; ++begin) ++begin; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for for (++begin; begin < end; ++begin) ++begin; diff --git a/test/OpenMP/parallel_for_misc_messages.c b/test/OpenMP/parallel_for_misc_messages.c index ee6f2e81bb8d..1a773be617c7 100644 --- a/test/OpenMP/parallel_for_misc_messages.c +++ b/test/OpenMP/parallel_for_misc_messages.c @@ -59,11 +59,6 @@ void test_non_identifiers() { #pragma omp parallel for; for (i = 0; i < 16; ++i) ; -// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}} -// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}} -#pragma omp parallel for linear(x); - for (i = 0; i < 16; ++i) - ; // expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}} #pragma omp parallel for private(x); @@ -153,15 +148,15 @@ void test_collapse() { #pragma omp parallel for collapse(foo()) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for collapse(-5) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for collapse(0) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for collapse(5 - 5) for (i = 0; i < 16; ++i) ; @@ -170,8 +165,7 @@ void test_collapse() { 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@+3 {{reduction variable must be shared}} -// expected-error@+2 {{private variable cannot be reduction}} +// expected-error@+2 2 {{reduction variable must be shared}} // expected-error@+1 {{region cannot be closely nested inside '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) diff --git a/test/OpenMP/parallel_for_num_threads_messages.cpp b/test/OpenMP/parallel_for_num_threads_messages.cpp index 60c7dfb6e3cd..10a4e1bfb1aa 100644 --- a/test/OpenMP/parallel_for_num_threads_messages.cpp +++ b/test/OpenMP/parallel_for_num_threads_messages.cpp @@ -24,7 +24,7 @@ T tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp 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 parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp 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 parallel for num_threads (S) // expected-error {{'S' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); @@ -32,7 +32,7 @@ T tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for num_threads (argc) for (i = 0; i < argc; ++i) foo(); - #pragma omp parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp 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; @@ -52,7 +52,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} for (i = 0; i < argc; ++i) foo(); - #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp 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 parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/parallel_for_ordered_messages.cpp b/test/OpenMP/parallel_for_ordered_messages.cpp new file mode 100644 index 000000000000..3729eb9a68a3 --- /dev/null +++ b/test/OpenMP/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 // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} +#pragma omp parallel for ordered + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp 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 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 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 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 parallel for ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#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}} +#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}} +#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]; +#pragma omp parallel for ordered(1) + for (int i = ST; i < N; i++) + argv[0][i] = argv[0][i] - argv[0][i - ST]; +#pragma omp 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 parallel for ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}} + return argc; +} + +int main(int argc, char **argv) { +#pragma omp parallel for ordered + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#pragma omp 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 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 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 parallel for', but found only 1}} +#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}} + 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 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) + for (int i = 4; i < 12; i++) + argv[0][i] = argv[0][i] - argv[0][i - 4]; +#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}} +#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]; +// expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}} +// expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} +#pragma omp parallel for ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); +#pragma omp parallel for ordered(2) // expected-note {{as specified in 'ordered' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp index 17344f62d7f1..efc827b0d5e5 100644 --- a/test/OpenMP/parallel_for_private_messages.cpp +++ b/test/OpenMP/parallel_for_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -99,7 +99,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp parallel for private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for private(i) @@ -120,7 +120,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -169,12 +169,16 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp parallel for private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for private(i) for (int k = 0; k < argc; ++k) ++k; + static int m; +#pragma omp parallel for private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; return 0; } diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp index 26fa48cf5697..22251b446300 100644 --- a/test/OpenMP/parallel_for_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_reduction_messages.cpp @@ -1,4 +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 void foo() { } @@ -16,7 +18,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; + 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}} @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -102,7 +108,7 @@ T tmain(T argc) { #pragma omp 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 parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#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'}} @@ -114,31 +120,31 @@ 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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'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 {{reduction variable 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 variable 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 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}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2s) +#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -157,7 +163,7 @@ T tmain(T argc) { #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}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -224,7 +230,7 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp 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 parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -236,31 +242,31 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(^ : S1) // expected-error {{'S1' 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 {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 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 parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel for reduction(max : argv[1]) // expected-error {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2s) +#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp 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')}} @@ -282,7 +288,7 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -298,6 +304,10 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(+ : fl) for (int i = 0; i < 10; ++i) foo(); + static int m; +#pragma omp 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' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/parallel_for_schedule_messages.cpp b/test/OpenMP/parallel_for_schedule_messages.cpp index c12c4282686b..f446609615da 100644 --- a/test/OpenMP/parallel_for_schedule_messages.cpp +++ b/test/OpenMP/parallel_for_schedule_messages.cpp @@ -13,13 +13,13 @@ template // expected-note {{declared here}} T tmain(T argc, S **argv) { #pragma omp 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 parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -28,7 +28,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} @@ -36,17 +36,17 @@ T tmain(T argc, S **argv) { #pragma omp 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 parallel for' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} + #pragma omp 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 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 parallel for schedule (dynamic, 1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp 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; } @@ -54,13 +54,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp 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 parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -73,17 +73,17 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} + #pragma omp 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 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 parallel for' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp parallel for schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/test/OpenMP/parallel_for_simd_aligned_messages.cpp b/test/OpenMP/parallel_for_simd_aligned_messages.cpp index e1b9602f0ca7..8bffd21f4655 100644 --- a/test/OpenMP/parallel_for_simd_aligned_messages.cpp +++ b/test/OpenMP/parallel_for_simd_aligned_messages.cpp @@ -50,7 +50,7 @@ template T test_template(T* arr, N num) { T sum = (T)0; T ind2 = - num * L; // Negative number is passed as L. - // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} #pragma omp parallel for simd aligned(arr:L) for (i = 0; i < num; ++i) { T cur = arr[(int)ind2]; @@ -65,7 +65,7 @@ template T test_template(T* arr, N num) { template int test_warn() { int *ind2 = 0; - // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} #pragma omp parallel for simd aligned(ind2:LEN) for (int i = 0; i < 100; i++) { ind2 += LEN; diff --git a/test/OpenMP/parallel_for_simd_ast_print.cpp b/test/OpenMP/parallel_for_simd_ast_print.cpp index cd62fc51af7f..e23c2cbd2428 100644 --- a/test/OpenMP/parallel_for_simd_ast_print.cpp +++ b/test/OpenMP/parallel_for_simd_ast_print.cpp @@ -14,8 +14,8 @@ template T reduct(T* arr, N num) { N myind; T sum = (T)0; // CHECK: T sum = (T)0; -#pragma omp parallel for simd private(myind, g_ind), linear(ind), aligned(arr) -// CHECK-NEXT: #pragma omp parallel for simd private(myind,g_ind) linear(ind) aligned(arr) +#pragma omp parallel for simd private(myind, g_ind), linear(ind), aligned(arr) if (parallel :num) +// CHECK-NEXT: #pragma omp parallel for simd private(myind,g_ind) linear(ind) aligned(arr) if(parallel: num) for (i = 0; i < num; ++i) { myind = ind; T cur = arr[myind]; @@ -35,8 +35,8 @@ template struct S { // CHECK: T res; // CHECK: T val; // CHECK: T lin = 0; - #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) -// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) if(7) +// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) if(7) for (T i = 7; i < m_a; ++i) { val = v[i-7] + m_a; res = val; @@ -44,8 +44,8 @@ template struct S { } const T clen = 3; // CHECK: T clen = 3; - #pragma omp parallel for simd safelen(clen-1) -// CHECK-NEXT: #pragma omp parallel for simd safelen(clen - 1) + #pragma omp parallel for simd safelen(clen-1) simdlen(clen-1) +// CHECK-NEXT: #pragma omp parallel for simd safelen(clen - 1) simdlen(clen - 1) for(T i = clen+2; i < 20; ++i) { // CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { v[i] = v[v-clen] + 1; @@ -62,7 +62,7 @@ template struct S { template struct S2 { static void func(int n, float *a, float *b, float *c) { int k1 = 0, k2 = 0; -#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) +#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) for(int i = 0; i < n; i++) { c[i] = a[i] + b[i]; c[k1] = a[k1] + b[k1]; @@ -77,7 +77,7 @@ template struct S2 { // CHECK: template struct S2 { // CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { // CHECK-NEXT: int k1 = 0, k2 = 0; -// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) // CHECK-NEXT: for (int i = 0; i < n; i++) { // CHECK-NEXT: c[i] = a[i] + b[i]; // CHECK-NEXT: c[k1] = a[k1] + b[k1]; @@ -92,17 +92,17 @@ int main (int argc, char **argv) { int k1=0,k2=0; static int *a; // CHECK: static int *a; -#pragma omp parallel for simd -// CHECK-NEXT: #pragma omp parallel for simd +#pragma omp parallel for simd if(parallel :b) +// CHECK-NEXT: #pragma omp parallel for simd if(parallel: 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 parallel -#pragma omp parallel for simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) ,firstprivate( g ) +#pragma omp parallel for simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) ,firstprivate( g ) if(g) for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;} // CHECK-NEXT: #pragma omp parallel -// CHECK-NEXT: #pragma omp parallel for simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) firstprivate(g) +// CHECK-NEXT: #pragma omp parallel for simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) firstprivate(g) if(g) // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: for (int j = 0; j < 10; ++j) { // CHECK-NEXT: foo(); @@ -114,8 +114,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: foo(); const int CLEN = 4; // CHECK-NEXT: const int CLEN = 4; - #pragma omp parallel for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) -// CHECK-NEXT: #pragma omp parallel for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + #pragma omp parallel for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) +// CHECK-NEXT: #pragma omp parallel for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) for (int i = 0; i < 10; ++i)foo(); // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); diff --git a/test/OpenMP/parallel_for_simd_codegen.cpp b/test/OpenMP/parallel_for_simd_codegen.cpp index eb1e493230e3..53f18d09b751 100644 --- a/test/OpenMP/parallel_for_simd_codegen.cpp +++ b/test/OpenMP/parallel_for_simd_codegen.cpp @@ -1,7 +1,7 @@ // 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 -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// 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 @@ -63,7 +63,6 @@ void simple(float *a, float *b, float *c, float *d) { } // CHECK: [[SIMPLE_LOOP1_END]] // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) long long k = get_val(); @@ -112,21 +111,19 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]] // CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27 // CHECK-NEXT: store i64 [[LIN_ADD2]], i64* %{{.+}} -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) int lin = 12; #pragma omp parallel for simd linear(lin : get_val()), linear(g_ptr) // Init linear private var. // CHECK: [[LIN_VAR:%.+]] = load i32*, i32** % -// CHECK-NEXT: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]] +// CHECK: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]] // CHECK-NEXT: store i32 [[LIN_LOAD]], i32* [[LIN_START:%[^,]+]] // Remember linear step. // CHECK: [[CALL_VAL:%.+]] = invoke // CHECK: store i64 [[CALL_VAL]], i64* [[LIN_STEP:%[^,]+]] -// CHECK: [[GLIN_VAR:%.+]] = load double**, double*** % -// CHECK-NEXT: [[GLIN_LOAD:%.+]] = load double*, double** [[GLIN_VAR]] +// CHECK: [[GLIN_LOAD:%.+]] = load double*, double** [[GLIN_VAR:%.+]], // CHECK-NEXT: store double* [[GLIN_LOAD]], double** [[GLIN_START:%[^,]+]] // CHECK: call void @__kmpc_for_static_init_8u(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 34, i32* %{{[^,]+}}, i64* [[LB:%[^,]+]], i64* [[UB:%[^,]+]], i64* [[STRIDE:%[^,]+]], i64 1, i64 1) @@ -179,14 +176,11 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) // // Linear start and step are used to calculate final value of the linear variables. -// CHECK: [[LIN_VAR:%.+]] = load i32*, i32** % // CHECK: [[LINSTART:.+]] = load i32, i32* [[LIN_START]] // CHECK: [[LINSTEP:.+]] = load i64, i64* [[LIN_STEP]] // CHECK: store i32 {{.+}}, i32* [[LIN_VAR]], -// CHECK: [[GLIN_VAR:%.+]] = load double**, double*** % // CHECK: [[GLINSTART:.+]] = load double*, double** [[GLIN_START]] // CHECK: store double* {{.*}}[[GLIN_VAR]] -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) #pragma omp parallel for simd // CHECK: call void @__kmpc_for_static_init_4(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 34, i32* %{{[^,]+}}, i32* [[LB:%[^,]+]], i32* [[UB:%[^,]+]], i32* [[STRIDE:%[^,]+]], i32 1, i32 1) @@ -223,7 +217,6 @@ void simple(float *a, float *b, float *c, float *d) { } // CHECK: [[SIMPLE_LOOP4_END]] // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) #pragma omp parallel for simd // CHECK: call void @__kmpc_for_static_init_4(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 34, i32* %{{[^,]+}}, i32* [[LB:%[^,]+]], i32* [[UB:%[^,]+]], i32* [[STRIDE:%[^,]+]], i32 1, i32 1) @@ -260,7 +253,6 @@ void simple(float *a, float *b, float *c, float *d) { } // CHECK: [[SIMPLE_LOOP5_END]] // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK-NOT: mul i32 %{{.+}}, 10 #pragma omp parallel for simd @@ -315,7 +307,6 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]], // CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* %{{.+}}, // CHECK-NEXT: br label -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) } int R; { @@ -364,7 +355,6 @@ void simple(float *a, float *b, float *c, float *d) { // CHECK: [[RED:%.+]] = mul nsw i32 %{{.+}}, [[R_PRIV_VAL]] // CHECK-NEXT: store i32 [[RED]], i32* %{{.+}}, // CHECK-NEXT: call void @__kmpc_end_reduce_nowait( -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) } } @@ -473,7 +463,6 @@ void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) { } // CHECK: [[IT_END]] // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK: ret void } @@ -552,7 +541,6 @@ void collapsed(float *a, float *b, float *c, float *d) { // CHECK: store i32 3, i32* [[I:%[^,]+]] // CHECK: store i32 5, i32* [[I:%[^,]+]] // CHECK: store i16 9, i16* [[I:%[^,]+]] -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK: ret void } @@ -672,7 +660,6 @@ void widened(float *a, float *b, float *c, float *d) { // CHECK-NEXT: br label {{%.+}} // CHECK: [[T1_END]] // CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}}) -// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK: ret void // // TERM_DEBUG-LABEL: bar diff --git a/test/OpenMP/parallel_for_simd_collapse_messages.cpp b/test/OpenMP/parallel_for_simd_collapse_messages.cpp index 22090e6b23ef..4f04cca5635e 100644 --- a/test/OpenMP/parallel_for_simd_collapse_messages.cpp +++ b/test/OpenMP/parallel_for_simd_collapse_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp 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 parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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 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]; @@ -41,7 +41,7 @@ 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 (1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp 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 parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for simd'}} @@ -63,7 +63,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp index 2ff32246dc17..7a08572f7d1a 100644 --- a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (int k = 0; k < argc; ++k) ++k; @@ -116,7 +116,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp parallel for simd firstprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd firstprivate(i) @@ -152,7 +152,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} for (i = 0; i < argc; ++i) foo(); @@ -226,7 +226,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd firstprivate(xa) // OK: may be firstprivate for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp parallel for simd firstprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} @@ -253,6 +253,10 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for simd' directive may not be firstprivate, predetermined as linear}} foo(); + static int si; +#pragma omp parallel for simd firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 2; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/parallel_for_simd_if_messages.cpp b/test/OpenMP/parallel_for_simd_if_messages.cpp index ca327cff7206..829b825aaf50 100644 --- a/test/OpenMP/parallel_for_simd_if_messages.cpp +++ b/test/OpenMP/parallel_for_simd_if_messages.cpp @@ -34,6 +34,20 @@ int tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd if(argc) for (i = 0; i < argc; ++i) foo(); + #pragma omp 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 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 parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp 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(); return 0; } @@ -64,6 +78,20 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp 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 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 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 parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp 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(); return tmain(argc, argv); } diff --git a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp index e85e28b3f18a..bd1a6d505572 100644 --- a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp +++ b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp @@ -16,7 +16,7 @@ public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} const S2 &operator=(const S2 &) const; - static float S2s; + 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}} @@ -66,7 +66,7 @@ int foomain(int argc, char **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (int k = 0; k < argc; ++k) ++k; @@ -118,7 +118,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp parallel for simd lastprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd lastprivate(i) @@ -143,7 +143,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (i = 0; i < argc; ++i) foo(); @@ -190,7 +190,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd lastprivate(xa) // OK for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd lastprivate(S2::S2s) +#pragma omp parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} @@ -222,7 +222,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd lastprivate(xa) for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp parallel for simd lastprivate(j) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} @@ -231,5 +231,9 @@ int main(int argc, char **argv) { #pragma omp parallel for simd lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp parallel for simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 3; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp index 55b0c3d7f9c8..858f53f4674d 100644 --- a/test/OpenMP/parallel_for_simd_linear_messages.cpp +++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp @@ -102,7 +102,7 @@ template int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd linear // expected-error {{expected '(' after 'linear'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -138,7 +138,7 @@ template int foomain(I argc, C **argv) { #pragma omp parallel for simd linear(v:i) for (int k = 0; k < argc; ++k) { i = k; v += i; } } - #pragma omp parallel for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type}} + #pragma omp parallel for simd linear(j) for (int k = 0; k < argc; ++k) ++k; int v = 0; #pragma omp parallel for simd linear(v:j) @@ -166,7 +166,7 @@ int main(int argc, char **argv) { S4 e(4); // expected-note {{'e' defined here}} S5 g(5); // expected-note {{'g' defined here}} int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd linear // expected-error {{expected '(' after 'linear'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -203,7 +203,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd linear(i : 4) for (int k = 0; k < argc; ++k) { ++k; i += 4; } } - #pragma omp parallel for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type 'int &'}} + #pragma omp parallel for simd linear(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd linear(i) for (int k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/parallel_for_simd_loop_messages.cpp b/test/OpenMP/parallel_for_simd_loop_messages.cpp index 85d8574ba9f4..f4929d97d484 100644 --- a/test/OpenMP/parallel_for_simd_loop_messages.cpp +++ b/test/OpenMP/parallel_for_simd_loop_messages.cpp @@ -10,6 +10,7 @@ public: }; static int sii; +// expected-note@+1 {{defined as threadprivate or thread local}} #pragma omp threadprivate(sii) static int globalii; @@ -54,32 +55,32 @@ int test_iteration_spaces() { for (double 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}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for simd for (int &ref = ii; ref < 10; ref++) { } -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for simd for (int i; i < 10; i++) c[i] = a[i]; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp 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 must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp 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 must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for simd for (ii + 1; ii < 10; ++ii) c[ii] = a[ii]; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for simd for (c[ii] = 0; ii < 10; ++ii) c[ii] = a[ii]; @@ -259,6 +260,7 @@ int test_iteration_spaces() { c[ii] = a[ii]; { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}} #pragma omp parallel for simd for (sii = 0; sii < 10; sii += 1) c[sii] = a[sii]; @@ -375,7 +377,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for simd for (GoodIter I = begin; I < end; ++I) ++I; -// expected-error@+2 {{variable must be of integer or random access iterator type}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for simd for (GoodIter &I = begin; I < end; ++I) ++I; @@ -406,7 +408,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for simd for (begin = begin0; begin < end; ++begin) ++begin; -// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp parallel for simd for (++begin; begin < end; ++begin) ++begin; diff --git a/test/OpenMP/parallel_for_simd_misc_messages.c b/test/OpenMP/parallel_for_simd_misc_messages.c index ed9ac4b5242a..378c48ff8a4c 100644 --- a/test/OpenMP/parallel_for_simd_misc_messages.c +++ b/test/OpenMP/parallel_for_simd_misc_messages.c @@ -153,20 +153,117 @@ void test_safelen() { #pragma omp parallel for simd safelen(foo()) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp parallel for simd safelen(-5) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp parallel for simd safelen(0) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp parallel for simd safelen(5 - 5) for (i = 0; i < 16; ++i) ; } +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp 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 parallel for simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp 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 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 parallel for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp 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 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 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 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 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 parallel for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; #pragma omp parallel @@ -259,17 +356,17 @@ void test_collapse() { for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for simd collapse(-5) for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for simd collapse(0) for (i = 0; i < 16; ++i) ; #pragma omp parallel -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp parallel for simd collapse(5 - 5) for (i = 0; i < 16; ++i) ; diff --git a/test/OpenMP/parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/parallel_for_simd_num_threads_messages.cpp index 5b5d33464ef8..940565cc10c3 100644 --- a/test/OpenMP/parallel_for_simd_num_threads_messages.cpp +++ b/test/OpenMP/parallel_for_simd_num_threads_messages.cpp @@ -24,7 +24,7 @@ T tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp 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 parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp 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 parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); @@ -32,7 +32,7 @@ T tmain(T argc, S **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd num_threads (argc) for (i = 0; i < argc; ++i) foo(); - #pragma omp parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp 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; @@ -52,7 +52,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} for (i = 0; i < argc; ++i) foo(); - #pragma omp parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp 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 parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); diff --git a/test/OpenMP/parallel_for_simd_private_messages.cpp b/test/OpenMP/parallel_for_simd_private_messages.cpp index 130736a33a07..a031d407ec1b 100644 --- a/test/OpenMP/parallel_for_simd_private_messages.cpp +++ b/test/OpenMP/parallel_for_simd_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -99,7 +99,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp parallel for simd private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd private(i) @@ -120,7 +120,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; @@ -169,12 +169,16 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp parallel for simd private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for simd private(i) for (int k = 0; k < argc; ++k) ++k; + static int m; +#pragma omp parallel for simd private(m) // OK + for (int k = 0; k < argc; ++k) + m = k + 3; return 0; } diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp index 75733a3647ac..e2e9e1bca38b 100644 --- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s void foo() { } @@ -16,7 +18,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; + 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}} @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -102,7 +108,7 @@ T tmain(T argc) { #pragma omp 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 parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#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'}} @@ -114,31 +120,31 @@ 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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'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 {{reduction variable 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 variable 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 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}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} 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')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2s) +#pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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 parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -157,7 +163,7 @@ T tmain(T argc) { #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}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -224,7 +230,7 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp 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 parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -236,31 +242,31 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(^ : S1) // expected-error {{'S1' 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 {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 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 parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel for simd reduction(max : argv[1]) // expected-error {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} 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')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2s) +#pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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 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')}} @@ -282,7 +288,7 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -298,6 +304,10 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(+ : fl) for (int i = 0; i < 10; ++i) foo(); + static int m; +#pragma omp 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' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/parallel_for_simd_safelen_messages.cpp b/test/OpenMP/parallel_for_simd_safelen_messages.cpp index eb0aa5ae8b5e..45f2fa2b6277 100644 --- a/test/OpenMP/parallel_for_simd_safelen_messages.cpp +++ b/test/OpenMP/parallel_for_simd_safelen_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp 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 parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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}} #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]; @@ -41,7 +41,7 @@ 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 (4) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp 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; } @@ -61,7 +61,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/parallel_for_simd_schedule_messages.cpp b/test/OpenMP/parallel_for_simd_schedule_messages.cpp index 36befb213559..4135427ce10b 100644 --- a/test/OpenMP/parallel_for_simd_schedule_messages.cpp +++ b/test/OpenMP/parallel_for_simd_schedule_messages.cpp @@ -13,13 +13,13 @@ template // expected-note {{declared here}} T tmain(T argc, S **argv) { #pragma omp 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 parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -28,7 +28,7 @@ T tmain(T argc, S **argv) { // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 parallel for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} @@ -36,17 +36,17 @@ T tmain(T argc, S **argv) { #pragma omp 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 parallel for simd' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + #pragma omp 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 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 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 parallel for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp 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; } @@ -54,13 +54,13 @@ T tmain(T argc, S **argv) { int main(int argc, char **argv) { #pragma omp 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 parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + #pragma omp 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 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 parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp 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 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]; @@ -73,17 +73,17 @@ int main(int argc, char **argv) { #pragma omp 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 parallel for simd' cannot contain more than one 'schedule' clause}} - // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}} #pragma omp 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 parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + #pragma omp 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 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 parallel for simd' must be a for loop}} // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} - #pragma omp parallel for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel for simd schedule(dynamic, schedule(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} foo(); // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} return tmain(argc, argv); diff --git a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp new file mode 100644 index 000000000000..dd1cf0feaa49 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp 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 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 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 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 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 parallel for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp 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 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 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 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 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp parallel for simd simdlen(simdlen(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/parallel_if_codegen.cpp b/test/OpenMP/parallel_if_codegen.cpp index ace20ecd8317..9ecf57211f85 100644 --- a/test/OpenMP/parallel_if_codegen.cpp +++ b/test/OpenMP/parallel_if_codegen.cpp @@ -16,14 +16,14 @@ int Arg; // CHECK-LABEL: define {{.*}}void @{{.+}}gtid_test void gtid_test() { -// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void +// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void #pragma omp parallel -#pragma omp parallel if (false) +#pragma omp parallel if (parallel: false) gtid_test(); // CHECK: ret void } -// CHECK: define internal {{.*}}void [[GTID_TEST_REGION1]](i{{.+}}* [[GTID_PARAM:%.+]], i +// CHECK: define internal {{.*}}void [[GTID_TEST_REGION1]](i{{.+}}* noalias [[GTID_PARAM:%.+]], i32* noalias // CHECK: store i{{[0-9]+}}* [[GTID_PARAM]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]], // CHECK: [[GTID_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_ADDR]] @@ -43,7 +43,7 @@ int tmain(T Arg) { fn1(); #pragma omp parallel if (false) fn2(); -#pragma omp parallel if (Arg) +#pragma omp parallel if (parallel: Arg) fn3(); return 0; } @@ -51,7 +51,7 @@ int tmain(T Arg) { // CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main() int main() { // CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num( -// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN4:@.+]] to void +// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN4:@.+]] to void #pragma omp parallel if (true) fn4(); // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) @@ -63,7 +63,7 @@ int main() { // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] -// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN6:@.+]] to void +// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN6:@.+]] to void // CHECK: br label %[[OMP_END:.+]] // CHECK: [[OMP_ELSE]] // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) @@ -92,14 +92,14 @@ int main() { // CHECK-LABEL: define {{.+}} @{{.+}}tmain // CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num( -// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN1:@.+]] to void +// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN1:@.+]] to void // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]], // CHECK: call void [[CAP_FN2:@.+]](i32* [[GTID_ADDR]], // CHECK: call {{.*}}void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) // CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] // CHECK: [[OMP_THEN]] -// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN3:@.+]] to void +// CHECK: call {{.*}}void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, void {{.+}}* [[CAP_FN3:@.+]] to void // CHECK: br label %[[OMP_END:.+]] // CHECK: [[OMP_ELSE]] // CHECK: call {{.*}}void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) diff --git a/test/OpenMP/parallel_if_messages.cpp b/test/OpenMP/parallel_if_messages.cpp index 97096dfae3e8..1ffc567b5916 100644 --- a/test/OpenMP/parallel_if_messages.cpp +++ b/test/OpenMP/parallel_if_messages.cpp @@ -22,6 +22,13 @@ int tmain(T argc, S **argv) { #pragma omp parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if(argc) + #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc) + #pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}} + #pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}} + #pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); return 0; @@ -40,6 +47,13 @@ int main(int argc, char **argv) { #pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp parallel if(parallel : argc) + #pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}} + #pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}} + #pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); return tmain(argc, argv); diff --git a/test/OpenMP/parallel_num_threads_messages.cpp b/test/OpenMP/parallel_num_threads_messages.cpp index 180d9cd8035a..adcf6ca4253f 100644 --- a/test/OpenMP/parallel_num_threads_messages.cpp +++ b/test/OpenMP/parallel_num_threads_messages.cpp @@ -19,11 +19,11 @@ T tmain(T argc, S **argv) { #pragma omp parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} #pragma omp parallel num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} - #pragma omp parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} #pragma omp parallel num_threads (S) // expected-error {{'S' does not refer to a value}} #pragma omp 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 *'}} #pragma omp parallel num_threads (argc) - #pragma omp parallel num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} #pragma omp parallel redef_num_threads (argc, argc) foo(); @@ -37,7 +37,7 @@ int main(int argc, char **argv) { #pragma omp parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} #pragma omp parallel num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} - #pragma omp parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} #pragma omp parallel num_threads (S1) // expected-error {{'S1' does not refer to a value}} #pragma omp 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 *'}} #pragma omp parallel num_threads (num_threads(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} diff --git a/test/OpenMP/parallel_private_codegen.cpp b/test/OpenMP/parallel_private_codegen.cpp index d2d02a7c3d37..1d195be97d6e 100644 --- a/test/OpenMP/parallel_private_codegen.cpp +++ b/test/OpenMP/parallel_private_codegen.cpp @@ -16,19 +16,17 @@ struct S { ~S() {} }; -volatile int g = 1212; +volatile int g __attribute__((aligned(128))) = 1212; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i8 } // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i8 } template T tmain() { S test; - T t_var = T(); - T vec[] = {1, 2}; - S s_arr[] = {1, 2}; - S var(3); + T t_var __attribute__((aligned(128))) = T(); + T vec[] __attribute__((aligned(128))) = {1, 2}; + S s_arr[] __attribute__((aligned(128))) = {1, 2}; + S var __attribute__((aligned(128))) (3); #pragma omp parallel private(t_var, vec, s_arr, var) { vec[0] = t_var; @@ -38,6 +36,7 @@ T tmain() { } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -45,26 +44,35 @@ int main() { [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA-NOT: = getelementptr inbounds %{{.+}}, - // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* %{{.+}} to i8* - // LAMBDA: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel private(g) + // LAMBDA: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) +#pragma omp parallel private(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, 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: [[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: 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -76,25 +84,33 @@ int main() { ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS-NOT: = getelementptr inbounds %{{.+}}, - // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* %{{.+}} to i8* - // BLOCKS: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel private(g) + // BLOCKS: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) +#pragma omp parallel private(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, g = 1; + sivar = 20; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 20, 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-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call{{.*}} void {{%.+}}(i8 ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 40; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 40, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -106,10 +122,11 @@ int main() { int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp parallel private(t_var, vec, s_arr, var) +#pragma omp parallel private(t_var, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 3; } return tmain(); #endif @@ -118,17 +135,17 @@ int main() { // CHECK: define i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](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]] @@ -145,18 +162,19 @@ 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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) -// 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: 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 +// 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-NOT: [[SIVAR_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]]) diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp index a637b5018f53..ab535b475265 100644 --- a/test/OpenMP/parallel_private_messages.cpp +++ b/test/OpenMP/parallel_private_messages.cpp @@ -13,7 +13,7 @@ class S2 { mutable int a; public: S2():a(0) { } - static float S2s; + static float S2s; // expected-note {{static data member is predetermined as shared}} }; const S2 b; const S2 ba[5]; @@ -55,7 +55,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g[] = {5, 6}; int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel private // expected-error {{expected '(' after 'private'}} #pragma omp parallel private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel private () // expected-error {{expected expression}} @@ -69,7 +69,7 @@ int main(int argc, char **argv) { #pragma omp parallel private(ba) #pragma omp parallel private(ca) // expected-error {{shared variable cannot be private}} #pragma omp parallel private(da) // expected-error {{shared variable cannot be private}} - #pragma omp parallel private(S2::S2s) + #pragma omp parallel private(S2::S2s) // expected-error {{shared variable cannot be private}} #pragma omp parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} #pragma omp parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} @@ -77,13 +77,16 @@ int main(int argc, char **argv) { #pragma omp parallel firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} foo(); #pragma omp parallel private(i) - #pragma omp parallel private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type 'int &'}} + #pragma omp parallel private(j) foo(); #pragma omp parallel firstprivate(i) for (int k = 0; k < 10; ++k) { #pragma omp parallel private(i) foo(); } + static int m; + #pragma omp parallel private(m) // OK + foo(); return 0; } diff --git a/test/OpenMP/parallel_reduction_codegen.cpp b/test/OpenMP/parallel_reduction_codegen.cpp index 04d19ebea8c5..b9744b634118 100644 --- a/test/OpenMP/parallel_reduction_codegen.cpp +++ b/test/OpenMP/parallel_reduction_codegen.cpp @@ -8,7 +8,7 @@ #ifndef HEADER #define HEADER -volatile int g = 1212; +volatile int g __attribute__((aligned(128))) = 1212; template struct S { @@ -22,9 +22,6 @@ struct S { // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, float*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float* } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*, [[S_INT_TY]]*, i{{[0-9]+}}* } -// 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 @@ -32,10 +29,10 @@ template T tmain() { T t; S test; - T t_var = T(), t_var1; + T t_var __attribute__((aligned(128))) = T(), t_var1 __attribute__((aligned(128))); T vec[] = {1, 2}; - S s_arr[] = {1, 2}; - S var(3), var1; + S s_arr[] = {1, 2}; + S var __attribute__((aligned(128))) (3), var1 __attribute__((aligned(128))); #pragma omp parallel reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) { vec[0] = t_var; @@ -51,30 +48,24 @@ int main() { // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] - // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) #pragma omp parallel reduction(+:g) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // Reduction list for runtime. // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x i8*], - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // LAMBDA: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] - // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] - // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] + // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 g = 1; - // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 // 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: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) - // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i64 0, i64 0 // LAMBDA: [[BITCAST:%.+]] = bitcast i32* [[G_PRIVATE_ADDR]] to i8* // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], // LAMBDA: call i32 @__kmpc_reduce_nowait( @@ -112,31 +103,25 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] - // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* - // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) #pragma omp parallel reduction(-:g) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // Reduction list for runtime. // BLOCKS: [[RED_LIST:%.+]] = alloca [1 x i8*], - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // BLOCKS: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] - // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 - // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] - // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] + // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 g = 1; - // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 - // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i64 0, i64 0 // BLOCKS: [[BITCAST:%.+]] = bitcast i32* [[G_PRIVATE_ADDR]] to i8* // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], // BLOCKS: call i32 @__kmpc_reduce_nowait( @@ -178,6 +163,12 @@ int main() { vec[0] = t_var; s_arr[0] = var; } + if (var1) +#pragma omp parallel reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1) + while (1) { + vec[0] = t_var; + s_arr[0] = var; + } return tmain(); #endif } @@ -185,13 +176,13 @@ int main() { // CHECK: define {{.*}}i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// 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]+}}*, [2 x i32]*, float*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*)* [[MAIN_MICROTASK:@.+]] to void +// 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]+}}*, [2 x i32]*, float*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*)* [[MAIN_MICROTASK1:@.+]] 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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // CHECK: [[T_VAR_PRIV:%.+]] = alloca float, // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]], @@ -202,23 +193,20 @@ int main() { // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR_REF:%.+]] = load float*, float** [[T_VAR_PTR_REF]], +// CHECK: [[T_VAR_REF:%.+]] = load float*, float** % +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// 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 0. // CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]], -// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]], // For & reduction operation initial value of private variable is ones in all bits. // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) -// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]], // For && reduction operation initial value of private variable is 1.0. // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]]) -// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** [[T_VAR1_PTR_REF]], // For min reduction operation initial value of private variable is largest repesentable value. // CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]], @@ -226,16 +214,16 @@ int main() { // void *RedList[] = {[0], ..., [-1]}; -// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// 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]], i32 0, i32 1 +// 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]], i32 0, i32 2 +// 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]], i32 0, i32 3 +// 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]], @@ -359,7 +347,6 @@ int main() { // break; // CHECK: br label %[[RED_DONE]] // CHECK: [[RED_DONE]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* @@ -373,38 +360,38 @@ int main() { // } // 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:%.+]], i32 0, i32 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:%.+]], i32 0, i32 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*)lhs[1]; -// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[1]; -// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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*)lhs[2]; -// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[2]; -// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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]], i32 0, i32 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]], i32 0, i32 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* @@ -445,42 +432,67 @@ int main() { // CHECK: store float [[UP]], float* [[T_VAR1_LHS]], // CHECK: ret void +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, +// 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, + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[T_VAR_REF:%.+]] = load float*, float** % +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % +// 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 0. +// CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]], + +// For & reduction operation initial value of private variable is ones in all bits. +// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) + +// For && reduction operation initial value of private variable is 1.0. +// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]]) + +// For min reduction operation initial value of private variable is largest repesentable value. +// CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]], + +// CHECK-NOT: call i32 @__kmpc_reduce + +// 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: %{{.+}} = bitcast [[CAP_TMAIN_TY]]* -// 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]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// 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]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) -// 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]+}}, +// 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 +// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 +// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 // 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_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % +// 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 i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]], -// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], // For & reduction operation initial value of private variable is ones in all bits. // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) -// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], // For && reduction operation initial value of private variable is 1.0. // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]]) -// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR1_PTR_REF]], // For min reduction operation initial value of private variable is largest repesentable value. // CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]], @@ -488,16 +500,16 @@ int main() { // void *RedList[] = {[0], ..., [-1]}; -// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// 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]], i32 0, i32 1 +// 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]], i32 0, i32 2 +// 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]], i32 0, i32 3 +// 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]], @@ -594,7 +606,6 @@ int main() { // break; // CHECK: br label %[[RED_DONE]] // CHECK: [[RED_DONE]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* @@ -608,38 +619,38 @@ int main() { // } // 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:%.+]], i32 0, i32 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:%.+]], i32 0, i32 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*)lhs[1]; -// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[1]; -// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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*)lhs[2]; -// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[2]; -// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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]], i32 0, i32 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]], i32 0, i32 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]+}}* diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp index c93cfbd9efaf..b29f7c98a574 100644 --- a/test/OpenMP/parallel_reduction_messages.cpp +++ b/test/OpenMP/parallel_reduction_messages.cpp @@ -1,4 +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 void foo() { } @@ -16,7 +18,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; + 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}} @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -93,7 +99,7 @@ T tmain(T argc) { foo(); #pragma omp 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 parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#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'}} foo(); @@ -101,23 +107,23 @@ T tmain(T 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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'operator+' is a private member of 'S2'}} foo(); -#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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}} foo(); -#pragma omp parallel reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); -#pragma omp parallel reduction(&& : S2::S2s) +#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} foo(); -#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} foo(); @@ -130,7 +136,7 @@ T tmain(T argc) { 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}} foo(); -#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) @@ -188,7 +194,7 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); -#pragma omp parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp parallel reduction(~ : argc) // expected-error {{expected unqualified-id}} foo(); @@ -196,23 +202,23 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} foo(); -#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} foo(); -#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel reduction(max : argv[1]) // expected-error {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); -#pragma omp parallel reduction(&& : S2::S2s) +#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} foo(); -#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp 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(); @@ -227,7 +233,7 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} foo(); -#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) @@ -243,6 +249,9 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) #pragma omp parallel reduction(+ : fl) foo(); + static int m; +#pragma omp parallel reduction(+ : m) // OK + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp index 7667e45bfdbc..9f5c1fadbeb8 100644 --- a/test/OpenMP/parallel_sections_ast_print.cpp +++ b/test/OpenMP/parallel_sections_ast_print.cpp @@ -37,7 +37,7 @@ T tmain(T argc, T *argv) { { a = 2; } -#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) num_threads(C) copyin(S < T > ::TS) proc_bind(master) reduction(+ : c) reduction(max : e) +#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) shared(d) if (parallel: argc > 0) num_threads(C) copyin(S < T > ::TS) proc_bind(master) reduction(+ : c) reduction(max : e) { foo(); } @@ -58,7 +58,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } -// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) // CHECK-NEXT: { // CHECK-NEXT: foo(); // CHECK-NEXT: } @@ -76,7 +76,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } -// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) // CHECK-NEXT: { // CHECK-NEXT: foo(); // CHECK-NEXT: } @@ -94,7 +94,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } -// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) // CHECK-NEXT: { // CHECK-NEXT: foo(); // CHECK-NEXT: } diff --git a/test/OpenMP/parallel_sections_codegen.cpp b/test/OpenMP/parallel_sections_codegen.cpp index 2e9e1f95aec5..b8c1e39d8f9e 100644 --- a/test/OpenMP/parallel_sections_codegen.cpp +++ b/test/OpenMP/parallel_sections_codegen.cpp @@ -5,7 +5,6 @@ // REQUIRES: x86-registered-target #ifndef HEADER #define HEADER -// CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-LABEL: foo void foo() {}; // CHECK-LABEL: bar @@ -22,9 +21,9 @@ T tmain() { // CHECK-LABEL: @main int main() { -// CHECK: call void (%{{.+}}*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %{{.+}}*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) +// CHECK: call void (%{{.+}}*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*)) // CHECK-LABEL: } -// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* [[GTID_PARAM_ADDR:%.+]], i32* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], #pragma omp parallel sections { @@ -73,7 +72,6 @@ int main() { // CHECK: [[INNER_LOOP_END]] } // CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], return tmain(); } @@ -89,7 +87,6 @@ int main() { // CHECK: call void @__kmpc_end_single( // CHECK-NEXT: br label %[[END]] // CHECK: [[END]] -// CHECK-NEXT: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], // CHECK-NEXT: ret // CHECK: [[TERM_LPAD]] // CHECK: call void @__clang_call_terminate(i8* diff --git a/test/OpenMP/parallel_sections_firstprivate_messages.cpp b/test/OpenMP/parallel_sections_firstprivate_messages.cpp index 84d18596c99c..b733aabb7f25 100644 --- a/test/OpenMP/parallel_sections_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_sections_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}} { foo(); @@ -130,7 +130,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp parallel sections firstprivate(j) { foo(); } @@ -171,7 +171,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}} { foo(); @@ -266,7 +266,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp parallel sections firstprivate(j) { foo(); } @@ -298,6 +298,11 @@ int main(int argc, char **argv) { { foo(); } + static int r; +#pragma omp parallel sections firstprivate(r) // OK + { + foo(); + } return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/parallel_sections_if_messages.cpp b/test/OpenMP/parallel_sections_if_messages.cpp index 03182b4c8fe1..c2e3f5ec99bd 100644 --- a/test/OpenMP/parallel_sections_if_messages.cpp +++ b/test/OpenMP/parallel_sections_if_messages.cpp @@ -55,6 +55,30 @@ int tmain(T argc, S **argv) { { foo(); } + #pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + { + foo(); + } return 0; } @@ -108,6 +132,30 @@ int main(int argc, char **argv) { { foo(); } + #pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}} + { + foo(); + } + #pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} + { + foo(); + } return tmain(argc, argv); } diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp index 10cc36e5ea7f..af3c5e2a575b 100644 --- a/test/OpenMP/parallel_sections_lastprivate_messages.cpp +++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp @@ -16,7 +16,7 @@ public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} const S2 &operator=(const S2 &) const; - static float S2s; + 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}} @@ -66,7 +66,7 @@ int foomain(int argc, char **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}} { foo(); @@ -131,7 +131,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp parallel sections lastprivate(j) { foo(); } @@ -158,7 +158,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}} { foo(); @@ -220,7 +220,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(S2::S2s) +#pragma omp parallel sections lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} { foo(); } @@ -262,7 +262,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp parallel sections lastprivate(j) { foo(); } @@ -271,6 +271,11 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel sections lastprivate(n) firstprivate(n) // OK + { + foo(); + } + static int r; +#pragma omp parallel sections lastprivate(r) // OK { foo(); } diff --git a/test/OpenMP/parallel_sections_num_threads_messages.cpp b/test/OpenMP/parallel_sections_num_threads_messages.cpp index a50025660da9..cda3841ace97 100644 --- a/test/OpenMP/parallel_sections_num_threads_messages.cpp +++ b/test/OpenMP/parallel_sections_num_threads_messages.cpp @@ -23,7 +23,7 @@ T tmain(T argc, S **argv) { {foo();} #pragma omp parallel sections num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} {foo();} - #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' 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 parallel sections num_threads (S) // expected-error {{'S' does not refer to a value}} {foo();} @@ -31,7 +31,7 @@ T tmain(T argc, S **argv) { {foo();} #pragma omp parallel sections num_threads (argc) {foo();} - #pragma omp parallel sections num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel sections num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}} {foo();} return argc; @@ -50,7 +50,7 @@ int main(int argc, char **argv) { {foo();} #pragma omp parallel sections num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} {foo();} - #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' 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 parallel sections num_threads (S1) // expected-error {{'S1' does not refer to a value}} {foo();} diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp index d9c4404bd984..ac9280e74ce1 100644 --- a/test/OpenMP/parallel_sections_private_messages.cpp +++ b/test/OpenMP/parallel_sections_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel sections private // expected-error {{expected '(' after 'private'}} { foo(); @@ -112,7 +112,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp parallel sections private(j) { foo(); } @@ -135,7 +135,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel sections private // expected-error {{expected '(' after 'private'}} { foo(); @@ -198,7 +198,7 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp parallel sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp parallel sections private(j) { foo(); } @@ -206,6 +206,11 @@ int main(int argc, char **argv) { { foo(); } + static int m; +#pragma omp parallel sections private(m) + { + foo(); + } return 0; } diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp index 2ed828dabfa7..eff1849d7132 100644 --- a/test/OpenMP/parallel_sections_reduction_messages.cpp +++ b/test/OpenMP/parallel_sections_reduction_messages.cpp @@ -1,4 +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 void foo() { } @@ -16,7 +18,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; + 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}} @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -111,7 +117,7 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp parallel sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} { foo(); } @@ -127,27 +133,27 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'operator+' is a private member of 'S2'}} { foo(); } -#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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}} { foo(); } -#pragma omp parallel sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp parallel sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} { foo(); } @@ -155,11 +161,11 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2s) +#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -184,7 +190,7 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} { foo(); } @@ -264,7 +270,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp parallel sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} { foo(); } @@ -280,27 +286,27 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} { foo(); } -#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel sections reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp parallel sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} { foo(); } @@ -308,11 +314,11 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2s) +#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -341,7 +347,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -361,6 +367,11 @@ int main(int argc, char **argv) { { foo(); } + static int m; +#pragma omp parallel sections reduction(+ : m) // OK + { + foo(); + } return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/sections_codegen.cpp b/test/OpenMP/sections_codegen.cpp index 2c257e83ae30..44fdefeee733 100644 --- a/test/OpenMP/sections_codegen.cpp +++ b/test/OpenMP/sections_codegen.cpp @@ -95,8 +95,7 @@ int main() { // CHECK: call void @__kmpc_end_single( // CHECK-NEXT: br label %[[END]] // CHECK: [[END]] -// CHECK-NEXT: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]], -// CHECK: call i32 @__kmpc_cancel_barrier( +// CHECK-NEXT: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]], // CHECK: ret // CHECK: [[TERM_LPAD]] // CHECK: call void @__clang_call_terminate(i8* diff --git a/test/OpenMP/sections_firstprivate_codegen.cpp b/test/OpenMP/sections_firstprivate_codegen.cpp index af9c1fe5fbda..f673597f660b 100644 --- a/test/OpenMP/sections_firstprivate_codegen.cpp +++ b/test/OpenMP/sections_firstprivate_codegen.cpp @@ -30,7 +30,6 @@ struct 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]+}} } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } template T tmain() { @@ -59,50 +58,70 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S 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]]) // CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( -// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp sections firstprivate(g) +#pragma omp sections firstprivate(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR_REF:%.+]]) // Skip temp vars for loop // 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** [[SIVAR_REF_ADDR:%.+]], + // LAMBDA: [[SIVAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]], // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + + // 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( - g = 1; + { + g = 1; + sivar = 10; + } // LAMBDA: call void @__kmpc_for_static_init_4( // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 10, i{{[0-9]+}}* [[SIVAR1_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]+}}* [[SIVAR1_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini( - // LAMBDA: call i32 @__kmpc_cancel_barrier( + // LAMBDA: call void @__kmpc_barrier( #pragma omp section [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 20; // 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 20, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -113,11 +132,11 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* -// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp sections firstprivate(g) +#pragma omp sections firstprivate(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR_REF:%.+]]) // Skip temp vars for loop // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, @@ -125,36 +144,56 @@ int main() { // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // BLOCKS: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** {{.+}}, + // BLOCKS: [[SIVAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** {{.+}}, + // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + + // 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( - g = 1; + { + g = 1; + sivar = 10; + } // BLOCKS: call void @__kmpc_for_static_init_4( // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 10, i{{[0-9]+}}* [[SIVAR1_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]+}}* [[SIVAR1_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini( - // BLOCKS: call i32 @__kmpc_cancel_barrier( + // BLOCKS: call void @__kmpc_barrier( #pragma omp section ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 20; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 20, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } }(); return 0; #else -#pragma omp sections firstprivate(t_var, vec, s_arr, var) nowait +#pragma omp sections firstprivate(t_var, vec, s_arr, var, sivar) nowait { { vec[0] = t_var; s_arr[0] = var; + sivar = 31; } } return tmain(); @@ -168,12 +207,12 @@ int main() { // 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: call i32 @__kmpc_single( // 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*), @@ -195,6 +234,10 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// firstprivate isvar +// CHEC: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], +// CHEC: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]], + // ~(firstprivate var), ~(firstprivate s_arr) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* @@ -209,11 +252,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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] 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]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // Skip temp vars for loop // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, @@ -226,22 +269,21 @@ int main() { // 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: [[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_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], // 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]], // firstprivate vec(vec) -// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // 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]], // firstprivate s_arr(s_arr) -// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF]], // 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_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]] @@ -253,8 +295,6 @@ int main() { // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] // firstprivate var(var) -// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], // 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]]) @@ -272,7 +312,7 @@ int main() { // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_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 i32 @__kmpc_cancel_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void #endif diff --git a/test/OpenMP/sections_firstprivate_messages.cpp b/test/OpenMP/sections_firstprivate_messages.cpp index ff7614967ee8..cd2b4b883873 100644 --- a/test/OpenMP/sections_firstprivate_messages.cpp +++ b/test/OpenMP/sections_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp sections firstprivate // expected-error {{expected '(' after 'firstprivate'}} { @@ -135,7 +135,7 @@ int foomain(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}} -#pragma omp sections firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp sections firstprivate(i) // expected-error {{firstprivate variable must be shared}} { foo(); } @@ -143,7 +143,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp sections firstprivate(j) { foo(); } @@ -186,7 +186,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp sections firstprivate // expected-error {{expected '(' after 'firstprivate'}} { @@ -304,7 +304,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp sections firstprivate(j) { foo(); } @@ -322,7 +322,7 @@ int main(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}} -#pragma omp sections firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp sections firstprivate(i) // expected-error {{firstprivate variable must be shared}} { foo(); } @@ -338,6 +338,11 @@ int main(int argc, char **argv) { { foo(); } + static int r; +#pragma omp sections firstprivate(r) // OK + { + foo(); + } return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/sections_lastprivate_codegen.cpp b/test/OpenMP/sections_lastprivate_codegen.cpp index c2f68aa0fe7d..a1ff007fd61d 100644 --- a/test/OpenMP/sections_lastprivate_codegen.cpp +++ b/test/OpenMP/sections_lastprivate_codegen.cpp @@ -21,10 +21,8 @@ struct S { volatile int g = 1212; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}* } // CHECK: [[S_INT_TY:%.+]] = type { i32 } -// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } -// 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-DAG: [[SECTIONS_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8* // CHECK-DAG: [[X:@.+]] = global double 0.0 @@ -53,33 +51,45 @@ using A::x; } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp sections lastprivate(g) +#pragma omp sections lastprivate(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias [[GTID:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR_REF:%.+]]) // 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} - // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] - // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // LAMBDA: [[SIVAR1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** %{{.+}}, + // LAMBDA: [[SIVAR_REF_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, + + // LAMBDA: [[GTID_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, align 8 + // LAMBDA: [[GTID_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_ADDR]], align 4 + + // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID_ADDR_REF]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 13, i{{[0-9]+}}* [[SIVAR1_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]+}}* [[SIVAR1_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) - // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) - g = 1; + // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID_ADDR_REF]]) + { + g = 1; + sivar = 13; + } // Check for final copying of private values back to original vars. // LAMBDA: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // LAMBDA: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -90,18 +100,26 @@ int main() { // original g=private_g; // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + + // original sivar = private sivar; + // LAMBDA: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR_REF_ADDR]], // LAMBDA: br label %[[LAST_DONE]] // LAMBDA: [[LAST_DONE]] - // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID_ADDR_REF]]) #pragma omp section [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 23; // 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 23, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -112,28 +130,39 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp sections lastprivate(g) +#pragma omp sections lastprivate(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias [[GTID:%.+]], i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) // 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: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} - // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] - // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) + // BLOCKS: [[SIVAR1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // BLOCKS: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_ADDR:%.+]], + // BLOCKS: [[SIVAR_REF_ADDR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR]], + + // BLOCKS: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID:%.+]], align 8 + // BLOCKS: [[GTID_ADDR_REF:%.+]] = load i32, i32* [[GTID_ADDR]], align 4 + // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID_ADDR_REF]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 17, i{{[0-9]+}}* [[SIVAR1_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]+}}* [[SIVAR1_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 - // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) - g = 1; + // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID_ADDR_REF]]) + { + g = 1; + sivar = 17; + } // Check for final copying of private values back to original vars. // BLOCKS: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // BLOCKS: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -144,16 +173,24 @@ int main() { // original g=private_g; // BLOCKS: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + + // original sivar = private sivar; + // BLOCKS: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR_REF_ADDR]], // BLOCKS: br label %[[LAST_DONE]] // BLOCKS: [[LAST_DONE]] - // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) + // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID_ADDR_REF]]) #pragma omp section ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 29; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 29, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -166,11 +203,12 @@ int main() { S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp sections lastprivate(t_var, vec, s_arr, var) +#pragma omp sections lastprivate(t_var, vec, s_arr, var, sivar) { { vec[0] = t_var; s_arr[0] = var; + sivar = 31; } } #pragma omp parallel @@ -187,14 +225,15 @@ int main() { // CHECK: define i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] 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]+}}*, %{{.+}}*)* [[MAIN_MICROTASK1:@.+]] 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]+}}*, i32*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void + +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK1:@.+]] to void // CHECK: = call {{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // CHECK-NOT: alloca i{{[0-9]+}}, // CHECK-NOT: alloca [2 x i{{[0-9]+}}], // CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]], @@ -205,10 +244,8 @@ int main() { // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // CHECK: call i32 @__kmpc_single( -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK-DAG: getelementptr inbounds [2 x i32], [2 x i32]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK-DAG: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 // @@ -217,12 +254,11 @@ int main() { // CHECK: call void @__kmpc_end_single( -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void // -// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, %{{.+}}* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: [[X_PRIV:%.+]] = alloca double, // CHECK-NOT: alloca double @@ -248,18 +284,17 @@ int main() { // CHECK-NEXT: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void // 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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] 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]+}}*, 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 internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, @@ -271,19 +306,16 @@ int main() { // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x 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 for default initialization. -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], // CHECK-NOT: [[T_VAR_PRIV]] -// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // CHECK-NOT: [[VEC_PRIV]] -// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]], // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]* // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]]) -// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // @@ -309,6 +341,10 @@ int main() { // CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]] to [[S_INT_TY]]* // CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 + +// CHK: [[SIVAR_REF:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 4 +// CHK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}} [[SIVAR_REF]] + // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_END]] // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] // CHECK: [[S_ARR_BODY]] @@ -324,10 +360,7 @@ int main() { // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void #endif diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp index 870dd158aeeb..5f6b420cb8ea 100644 --- a/test/OpenMP/sections_lastprivate_messages.cpp +++ b/test/OpenMP/sections_lastprivate_messages.cpp @@ -66,7 +66,7 @@ int foomain(int argc, char **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp sections lastprivate // expected-error {{expected '(' after 'lastprivate'}} { @@ -144,7 +144,7 @@ int foomain(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp sections lastprivate(j) { foo(); } @@ -172,7 +172,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp sections lastprivate // expected-error {{expected '(' after 'lastprivate'}} { @@ -300,7 +300,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp sections lastprivate(j) { foo(); } @@ -311,6 +311,11 @@ int main(int argc, char **argv) { } #pragma omp parallel #pragma omp sections lastprivate(n) firstprivate(n) // OK + { + foo(); + } + static int r; +#pragma omp sections lastprivate(r) // OK { foo(); } diff --git a/test/OpenMP/sections_private_codegen.cpp b/test/OpenMP/sections_private_codegen.cpp index 9b579a2aa661..cd2218832bcf 100644 --- a/test/OpenMP/sections_private_codegen.cpp +++ b/test/OpenMP/sections_private_codegen.cpp @@ -20,9 +20,7 @@ struct S { volatile double g; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i8 } // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i8 } template T tmain() { S test; @@ -41,24 +39,31 @@ T tmain() { } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp sections private(g) +#pragma omp sections private(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - g = 1; + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + { + g = 1; + sivar = 11; + } // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4( // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[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: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call {{.*}}void @__kmpc_for_static_fini( #pragma omp section @@ -66,10 +71,16 @@ int main() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 22; // 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]+}} 22, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -80,28 +91,39 @@ int main() { // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* {{.+}}) + // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp sections private(g) +#pragma omp sections private(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - g = 1; + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + { + g = 1; + sivar = 111; + } // BLOCKS: call {{.*}}void @__kmpc_for_static_init_4( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 111, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: double* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 // BLOCKS: call {{.*}}void @__kmpc_for_static_fini( #pragma omp section ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 222; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 222, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -114,11 +136,12 @@ int main() { S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp sections private(t_var, vec, s_arr, s_arr, var, var) +#pragma omp sections private(t_var, vec, s_arr, s_arr, var, var, sivar) { { vec[0] = t_var; s_arr[0] = var; + sivar = 2; } } return tmain(); @@ -128,23 +151,24 @@ int main() { // CHECK: define i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](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-NOT: alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK-NOT: alloca [[S_FLOAT_TY]], // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // CHECK: call i32 @__kmpc_single( // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] +// CHECK-NOT: [[SIVAR_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]]) @@ -159,11 +183,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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: alloca i32, // CHECK: alloca i32, // CHECK: alloca i32, diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp index 7854b3d8bdd3..f13bbdb012e2 100644 --- a/test/OpenMP/sections_private_messages.cpp +++ b/test/OpenMP/sections_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp sections private // expected-error {{expected '(' after 'private'}} { foo(); @@ -112,7 +112,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp sections private(j) { foo(); } @@ -135,7 +135,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp sections private // expected-error {{expected '(' after 'private'}} { foo(); @@ -198,7 +198,7 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp sections private(j) { foo(); } @@ -206,6 +206,11 @@ int main(int argc, char **argv) { { foo(); } + static int m; +#pragma omp sections private(m) + { + foo(); + } return 0; } diff --git a/test/OpenMP/sections_reduction_codegen.cpp b/test/OpenMP/sections_reduction_codegen.cpp index 4d404dbcc6d1..f67977c39580 100644 --- a/test/OpenMP/sections_reduction_codegen.cpp +++ b/test/OpenMP/sections_reduction_codegen.cpp @@ -22,10 +22,7 @@ struct S { // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]* } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [[S_INT_TY]]*, [[S_INT_TY]]*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]* } // 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: [[SINGLE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, 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 @@ -55,11 +52,11 @@ int main() { // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel #pragma omp sections reduction(+:g) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}}) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, // Reduction list for runtime. @@ -74,7 +71,7 @@ int main() { // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini( - // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i64 0, i64 0 // LAMBDA: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8* // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], // LAMBDA: call i32 @__kmpc_reduce( @@ -115,11 +112,11 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel #pragma omp sections reduction(-:g) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}}) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, // Reduction list for runtime. @@ -135,7 +132,7 @@ int main() { // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini( - // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0 + // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i64 0, i64 0 // BLOCKS: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8* // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], // BLOCKS: call i32 @__kmpc_reduce( @@ -192,13 +189,12 @@ int main() { // CHECK: define {{.*}}i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// 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 {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // CHECK-NOT: alloca float, // CHECK-NOT: alloca [[S_FLOAT_TY]], // CHECK-NOT: alloca [[S_FLOAT_TY]], @@ -210,30 +206,23 @@ int main() { // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // CHECK: call i32 @__kmpc_single( -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 - // CHECK-NOT: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-NOT: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK: call void @__kmpc_end_single( -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // 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: %{{.+}} = bitcast [[CAP_TMAIN_TY]]* -// 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]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// 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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, // CHECK: alloca i{{[0-9]+}}, @@ -249,23 +238,20 @@ int main() { // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % +// 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 i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]], -// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], // For & reduction operation initial value of private variable is ones in all bits. // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) -// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]], // For && reduction operation initial value of private variable is 1.0. // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]]) -// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}} -// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR1_PTR_REF]], // For min reduction operation initial value of private variable is largest repesentable value. // CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]], @@ -277,16 +263,16 @@ int main() { // void *RedList[] = {[0], ..., [-1]}; -// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0 +// 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]], i32 0, i32 1 +// 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]], i32 0, i32 2 +// 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]], i32 0, i32 3 +// 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]], @@ -384,7 +370,6 @@ int main() { // 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: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void // void reduce_func(void *lhs[], void *rhs[]) { @@ -395,38 +380,38 @@ int main() { // } // 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:%.+]], i32 0, i32 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:%.+]], i32 0, i32 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*)lhs[1]; -// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[1]; -// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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*)lhs[2]; -// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 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*)rhs[2]; -// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 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]], i32 0, i32 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]], i32 0, i32 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]+}}* diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp index a0f56d5a1e2a..79473d4e5d28 100644 --- a/test/OpenMP/sections_reduction_messages.cpp +++ b/test/OpenMP/sections_reduction_messages.cpp @@ -1,4 +1,6 @@ // 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() { } @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -121,7 +127,7 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} { foo(); } @@ -141,32 +147,32 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'operator+' is a private member of 'S2'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} { foo(); } @@ -181,7 +187,7 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -211,7 +217,7 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} { foo(); } @@ -301,7 +307,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} { foo(); } @@ -321,32 +327,32 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 parallel -#pragma omp sections reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} { foo(); } @@ -361,7 +367,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -396,7 +402,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -416,6 +422,11 @@ int main(int argc, char **argv) { { foo(); } + static int m; +#pragma omp sections reduction(+ : m) // OK + { + foo(); + } return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/simd_aligned_messages.cpp b/test/OpenMP/simd_aligned_messages.cpp index 408cc2e360b5..6be7529ad511 100644 --- a/test/OpenMP/simd_aligned_messages.cpp +++ b/test/OpenMP/simd_aligned_messages.cpp @@ -50,7 +50,7 @@ template T test_template(T* arr, N num) { T sum = (T)0; T ind2 = - num * L; // Negative number is passed as L. - // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} #pragma omp simd aligned(arr:L) for (i = 0; i < num; ++i) { T cur = arr[(int)ind2]; @@ -65,7 +65,7 @@ template T test_template(T* arr, N num) { template int test_warn() { int *ind2 = 0; - // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} #pragma omp simd aligned(ind2:LEN) for (int i = 0; i < 100; i++) { ind2 += LEN; diff --git a/test/OpenMP/simd_ast_print.cpp b/test/OpenMP/simd_ast_print.cpp index 069862b6dfbc..cabbe338db2a 100644 --- a/test/OpenMP/simd_ast_print.cpp +++ b/test/OpenMP/simd_ast_print.cpp @@ -12,10 +12,11 @@ template T reduct(T* arr, N num) { N i; N ind; N myind; + N &ref = i; T sum = (T)0; // CHECK: T sum = (T)0; -#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr) -// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr) +#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr), linear(uval(ref)) +// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr) linear(uval(ref)) for (i = 0; i < num; ++i) { myind = ind; T cur = arr[myind]; @@ -32,11 +33,13 @@ template struct S { T res; T val; T lin = 0; + T &ref = res; // CHECK: T res; // CHECK: T val; // CHECK: T lin = 0; - #pragma omp simd private(val) safelen(7) linear(lin : -5) lastprivate(res) -// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res) +// CHECK: T &ref = res; + #pragma omp simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) linear(ref(ref)) +// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) linear(ref(ref)) for (T i = 7; i < m_a; ++i) { val = v[i-7] + m_a; res = val; @@ -44,8 +47,8 @@ template struct S { } const T clen = 3; // CHECK: T clen = 3; - #pragma omp simd safelen(clen-1) -// CHECK-NEXT: #pragma omp simd safelen(clen - 1) + #pragma omp simd safelen(clen-1) simdlen(clen-1) +// CHECK-NEXT: #pragma omp simd safelen(clen - 1) simdlen(clen - 1) for(T i = clen+2; i < 20; ++i) { // CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { v[i] = v[v-clen] + 1; @@ -62,7 +65,7 @@ template struct S { template struct S2 { static void func(int n, float *a, float *b, float *c) { int k1 = 0, k2 = 0; -#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) +#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) for(int i = 0; i < n; i++) { c[i] = a[i] + b[i]; c[k1] = a[k1] + b[k1]; @@ -77,7 +80,7 @@ template struct S2 { // CHECK: template struct S2 { // CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { // CHECK-NEXT: int k1 = 0, k2 = 0; -// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) // CHECK-NEXT: for (int i = 0; i < n; i++) { // CHECK-NEXT: c[i] = a[i] + b[i]; // CHECK-NEXT: c[k1] = a[k1] + b[k1]; @@ -90,6 +93,7 @@ template struct S2 { int main (int argc, char **argv) { int b = argc, c, d, e, f, g; int k1=0,k2=0; + int &ref = b; static int *a; // CHECK: static int *a; #pragma omp simd @@ -112,8 +116,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: foo(); const int CLEN = 4; // CHECK-NEXT: const int CLEN = 4; - #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) -// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(ref): CLEN) +// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN) for (int i = 0; i < 10; ++i)foo(); // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp index e67ad5d4c7e0..62028339f514 100644 --- a/test/OpenMP/simd_codegen.cpp +++ b/test/OpenMP/simd_codegen.cpp @@ -1,7 +1,7 @@ // 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 -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// 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 @@ -481,6 +481,139 @@ void widened(float *a, float *b, float *c, float *d) { // CHECK: ret void } +// CHECK-LABEL: define {{.*void}} @{{.*}}linear{{.*}}(float* {{.+}}) +void linear(float *a) { + // CHECK: [[VAL_ADDR:%.+]] = alloca i64, + // CHECK: [[K_ADDR:%.+]] = alloca i64*, + long long val = 0; + long long &k = val; + + #pragma omp simd linear(k : 3) +// CHECK: store i64* [[VAL_ADDR]], i64** [[K_ADDR]], +// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]] +// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]] +// CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] + +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID:[0-9]+]] +// CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9 +// CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]] + for (int i = 10; i > 1; i--) { +// CHECK: [[SIMPLE_LOOP_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// FIXME: It is interesting, why the following "mul 1" was not constant folded? +// CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1 +// CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]] +// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// +// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3 +// CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64 +// CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]] +// Update of the privatized version of linear variable! +// CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]] + a[k]++; + k = k + 3; +// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1 +// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]] + } +// 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: 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 +// CHECK-NEXT: [[K_REF:%.+]] = load i64*, i64** [[K_PRIV_REF]], +// CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[K_REF]] +// + + #pragma omp simd linear(val(k) : 3) +// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]] +// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]], +// CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]] +// CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] + +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID:[0-9]+]] +// CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9 +// CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]] + for (int i = 10; i > 1; i--) { +// CHECK: [[SIMPLE_LOOP_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// FIXME: It is interesting, why the following "mul 1" was not constant folded? +// CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1 +// CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]] +// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// +// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3 +// CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64 +// CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]] +// Update of the privatized version of linear variable! +// CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]] + a[k]++; + k = k + 3; +// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1 +// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]] + } +// 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: 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 +// CHECK-NEXT: [[K_REF:%.+]] = load i64*, i64** [[K_PRIV_REF]], +// CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[K_REF]] +// + #pragma omp simd linear(uval(k) : 3) +// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]] +// CHECK: [[K0LOAD:%.+]] = load i64, i64* [[VAL_ADDR]] +// CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] + +// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID:[0-9]+]] +// CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV]], 9 +// CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP_BODY:.+]], label %[[SIMPLE_LOOP_END:[^,]+]] + for (int i = 10; i > 1; i--) { +// CHECK: [[SIMPLE_LOOP_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV_0:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// FIXME: It is interesting, why the following "mul 1" was not constant folded? +// CHECK-NEXT: [[IV_1:%.+]] = mul nsw i32 [[IV_0]], 1 +// CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV_1]] +// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// +// CHECK-NEXT: [[LIN0_1:%.+]] = load i64, i64* [[LIN0]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[LIN_MUL1:%.+]] = mul nsw i32 [[IV_2]], 3 +// CHECK-NEXT: [[LIN_EXT1:%.+]] = sext i32 [[LIN_MUL1]] to i64 +// CHECK-NEXT: [[LIN_ADD1:%.+]] = add nsw i64 [[LIN0_1]], [[LIN_EXT1]] +// Update of the privatized version of linear variable! +// CHECK-NEXT: store i64 [[LIN_ADD1]], i64* [[K_PRIVATIZED:%[^,]+]] + a[k]++; + k = k + 3; +// CHECK: [[IV_2:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV_2]], 1 +// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP_ID]] +// br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP_ID]] + } +// CHECK: [[SIMPLE_LOOP_END]] +// +// Update linear vars after loop, as the loop was operating on a private version. +// CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]] +// CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27 +// CHECK-NEXT: store i64 [[LIN_ADD2]], i64* [[VAL_ADDR]] +// +} + // TERM_DEBUG-LABEL: bar int bar() {return 0;}; diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp index 56ff201d112d..e34f0a15b20c 100644 --- a/test/OpenMP/simd_collapse_messages.cpp +++ b/test/OpenMP/simd_collapse_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp 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 simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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 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]; @@ -41,7 +41,7 @@ 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 (1) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp 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 simd collapse (2) // expected-note {{as specified in 'collapse' clause}} foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}} @@ -63,7 +63,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp index ca26db0d1447..7cc5ba81f78b 100644 --- a/test/OpenMP/simd_lastprivate_messages.cpp +++ b/test/OpenMP/simd_lastprivate_messages.cpp @@ -66,7 +66,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (int k = 0; k < argc; ++k) ++k; @@ -118,7 +118,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp simd lastprivate(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd lastprivate(i) @@ -134,7 +134,7 @@ int main(int argc, char **argv) { S5 g(5); S3 m; int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} for (i = 0; i < argc; ++i) foo(); @@ -210,7 +210,11 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} +#pragma omp simd lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); + static int t; +#pragma omp simd lastprivate(t) // OK for (i = 0; i < argc; ++i) foo(); return 0; diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp index 6fac26290b4e..792f78aa3db6 100644 --- a/test/OpenMP/simd_linear_messages.cpp +++ b/test/OpenMP/simd_linear_messages.cpp @@ -102,16 +102,26 @@ template int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp simd linear // expected-error {{expected '(' after 'linear'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (uval( // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (ref() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (foo() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear () // expected-error {{expected expression}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp simd linear (val argc // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (val(argc, // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; @@ -121,15 +131,15 @@ template int foomain(I argc, C **argv) { 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 simd linear (a, b:B::ib) + #pragma omp simd linear (val(a, b):B::ib) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(e, g) + #pragma omp simd linear(ref(e, g)) // expected-error 2 {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'ref'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(i) + #pragma omp simd linear(uval(i)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { @@ -138,7 +148,9 @@ template int foomain(I argc, C **argv) { #pragma omp simd linear(v:i) for (int k = 0; k < argc; ++k) { i = k; v += i; } } - #pragma omp simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type}} + #pragma omp simd linear(ref(j)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(uval(j)) for (int k = 0; k < argc; ++k) ++k; int v = 0; #pragma omp simd linear(v:j) @@ -156,6 +168,20 @@ namespace C { using A::x; } +void linear_modifiers(int argc) { + int &f = argc; + #pragma omp simd linear(f) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(val(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(uval(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(ref(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(foo(f)) // expected-error {{expected one of 'ref', val' or 'uval' modifiers}} + for (int k = 0; k < argc; ++k) ++k; +} + int f; int main(int argc, char **argv) { double darr[100]; @@ -167,7 +193,7 @@ int main(int argc, char **argv) { S4 e(4); // expected-note {{'e' defined here}} S5 g(5); // expected-note {{'g' defined here}} int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp simd linear(f) linear(f) // expected-error {{linear variable cannot be linear}} expected-note {{defined as linear}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear // expected-error {{expected '(' after 'linear'}} @@ -176,6 +202,12 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear () // expected-error {{expected expression}} for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (ref()) // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (foo()) // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -194,24 +226,24 @@ int main(int argc, char **argv) { 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 simd linear(e, g) + #pragma omp simd linear(val(e, g)) for (int k = 0; k < argc; ++k) ++k; #pragma omp 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 simd linear(i) + #pragma omp simd linear(val(i)) for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(i : 4) + #pragma omp simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}} for (int k = 0; k < argc; ++k) { ++k; i += 4; } } - #pragma omp simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type 'int &'}} + #pragma omp simd linear(ref(j)) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(i) for (int k = 0; k < argc; ++k) ++k; - foomain(argc,argv); + foomain(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} return 0; } diff --git a/test/OpenMP/simd_loop_messages.cpp b/test/OpenMP/simd_loop_messages.cpp index bd7dd5bf52d1..96b4cafc6bd8 100644 --- a/test/OpenMP/simd_loop_messages.cpp +++ b/test/OpenMP/simd_loop_messages.cpp @@ -1,6 +1,7 @@ // 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; @@ -45,32 +46,32 @@ int test_iteration_spaces() { for (double 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}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (int &ref = ii; ref < 10; ref++) { } - // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (int i; i < 10; i++) c[i] = a[i]; - // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (int i = 0, j = 0; i < 10; ++i) c[i] = a[i]; - // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (;ii < 10; ++ii) c[ii] = a[ii]; // expected-warning@+3 {{expression result unused}} - // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (ii + 1;ii < 10; ++ii) c[ii] = a[ii]; - // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (c[ii] = 0;ii < 10; ++ii) c[ii] = a[ii]; @@ -252,6 +253,7 @@ int test_iteration_spaces() { #pragma omp parallel { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be threadprivate or thread local, predetermined as linear}} #pragma omp simd for (sii = 0; sii < 10; sii+=1) c[sii] = a[sii]; @@ -364,7 +366,7 @@ int test_with_random_access_iterator() { #pragma omp simd for (GoodIter I = begin; I < end; ++I) ++I; - // expected-error@+2 {{variable must be of integer or random access iterator type}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (GoodIter &I = begin; I < end; ++I) ++I; @@ -393,7 +395,7 @@ int test_with_random_access_iterator() { #pragma omp simd for (begin = GoodIter(1,2); begin < end; ++begin) ++begin; - // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} + // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (++begin; begin < end; ++begin) ++begin; diff --git a/test/OpenMP/simd_metadata.c b/test/OpenMP/simd_metadata.c index e7e35dd54d74..6ed660747dcb 100644 --- a/test/OpenMP/simd_metadata.c +++ b/test/OpenMP/simd_metadata.c @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -fopenmp -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=X86 // RUN: %clang_cc1 -fopenmp -triple x86_64-unknown-unknown -target-feature +avx -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=X86-AVX // RUN: %clang_cc1 -fopenmp -triple x86_64-unknown-unknown -target-feature +avx512f -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=X86-AVX512 +// RUN: %clang_cc1 -fopenmp -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=X86 +// RUN: %clang_cc1 -fopenmp -triple i386-unknown-unknown -target-feature +avx -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=X86-AVX +// RUN: %clang_cc1 -fopenmp -triple i386-unknown-unknown -target-feature +avx512f -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=X86-AVX512 // RUN: %clang_cc1 -fopenmp -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=PPC // RUN: %clang_cc1 -fopenmp -triple powerpc64-unknown-unknown -target-abi elfv1-qpx -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=PPC-QPX @@ -36,8 +39,69 @@ void h1(float *c, float *a, double b[], int size) for (int i = 0; i < size; ++i) { c[i] = a[i] * a[i] + b[i] * b[t]; ++t; + } +// do not emit parallel_loop_access metadata due to usage of safelen clause. +// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}} +#pragma omp simd safelen(16) linear(t) aligned(c:32) aligned(a,b) simdlen(8) +// CHECK: [[C_PTRINT:%.+]] = ptrtoint +// CHECK-NEXT: [[C_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[C_PTRINT]], 31 +// CHECK-NEXT: [[C_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[C_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[C_MASKCOND]]) +// CHECK: [[A_PTRINT:%.+]] = ptrtoint + +// X86-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 +// X86-AVX-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 31 +// X86-AVX512-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 63 +// PPC-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 +// PPC-QPX-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 + +// CHECK-NEXT: [[A_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[A_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[A_MASKCOND]]) +// CHECK: [[B_PTRINT:%.+]] = ptrtoint + +// X86-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 15 +// X86-AVX-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 31 +// X86-AVX512-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 63 +// PPC-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 15 +// PPC-QPX-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 31 + +// CHECK-NEXT: [[B_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[B_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[B_MASKCOND]]) + for (int i = 0; i < size; ++i) { + c[i] = a[i] * a[i] + b[i] * b[t]; + ++t; + } // do not emit parallel_loop_access metadata due to usage of safelen clause. // CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}} +#pragma omp simd linear(t) aligned(c:32) aligned(a,b) simdlen(8) +// CHECK: [[C_PTRINT:%.+]] = ptrtoint +// CHECK-NEXT: [[C_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[C_PTRINT]], 31 +// CHECK-NEXT: [[C_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[C_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[C_MASKCOND]]) +// CHECK: [[A_PTRINT:%.+]] = ptrtoint + +// X86-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 +// X86-AVX-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 31 +// X86-AVX512-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 63 +// PPC-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 +// PPC-QPX-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 + +// CHECK-NEXT: [[A_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[A_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[A_MASKCOND]]) +// CHECK: [[B_PTRINT:%.+]] = ptrtoint + +// X86-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 15 +// X86-AVX-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 31 +// X86-AVX512-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 63 +// PPC-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 15 +// PPC-QPX-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 31 + +// CHECK-NEXT: [[B_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[B_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[B_MASKCOND]]) + for (int i = 0; i < size; ++i) { + c[i] = a[i] * a[i] + b[i] * b[t]; + ++t; +// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}} } } @@ -70,6 +134,9 @@ void h3(float *c, float *a, float *b, int size) // CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_16:![0-9]+]], [[LOOP_VEC_ENABLE:![0-9]+]]} // CHECK: [[LOOP_WIDTH_16]] = !{!"llvm.loop.vectorize.width", i32 16} // CHECK: [[LOOP_VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true} +// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8:![0-9]+]], [[LOOP_VEC_ENABLE]]} +// CHECK: [[LOOP_WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8} +// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8]], [[LOOP_VEC_ENABLE]]} // // Metadata for h2: // CHECK: [[LOOP_H2_HEADER]] = distinct !{[[LOOP_H2_HEADER]], [[LOOP_VEC_ENABLE]]} diff --git a/test/OpenMP/simd_misc_messages.c b/test/OpenMP/simd_misc_messages.c index 0b4dd7f3b533..1e1548291947 100644 --- a/test/OpenMP/simd_misc_messages.c +++ b/test/OpenMP/simd_misc_messages.c @@ -152,20 +152,117 @@ void test_safelen() { #pragma omp simd safelen(foo()) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp simd safelen(-5) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp simd safelen(0) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp simd safelen(5 - 5) for (i = 0; i < 16; ++i) ; } +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp 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 simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp 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 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 simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp 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 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 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 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 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 simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; // expected-error@+1 {{expected '('}} @@ -241,15 +338,15 @@ void test_collapse() { #pragma omp simd collapse(foo()) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp simd collapse(-5) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp simd collapse(0) for (i = 0; i < 16; ++i) ; -// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} #pragma omp simd collapse(5 - 5) for (i = 0; i < 16; ++i) ; @@ -259,12 +356,18 @@ void test_collapse() { 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@+3 {{reduction variable must be shared}} -// expected-error@+2 {{private variable cannot be reduction}} +// 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 parallel +#pragma omp for + for (i = 0; i < 16; ++i) + for (int j = 0; j < 16; ++j) +#pragma omp simd reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; } void test_linear() { @@ -678,3 +781,17 @@ void test_loop_messages() { } } +void linear_modifiers(int argc) { + int f; + #pragma omp simd linear(f) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(val(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(uval(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(ref(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(foo(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; +} + diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp index adef373b6a4e..3442d182ed02 100644 --- a/test/OpenMP/simd_private_messages.cpp +++ b/test/OpenMP/simd_private_messages.cpp @@ -42,7 +42,7 @@ template int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp simd private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -78,7 +78,7 @@ template int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) - #pragma omp simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} + #pragma omp simd private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private(i) for (int k = 0; k < argc; ++k) ++k; @@ -97,7 +97,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp simd private // expected-error {{expected '(' after 'private'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -132,7 +132,7 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) - #pragma omp simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} + #pragma omp simd private(j) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private(i) for (int k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp index aeb2b23bb0ca..e082921cf383 100644 --- a/test/OpenMP/simd_reduction_messages.cpp +++ b/test/OpenMP/simd_reduction_messages.cpp @@ -1,4 +1,6 @@ // 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() { } @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -102,7 +108,7 @@ T tmain(T argc) { #pragma omp 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 simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#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'}} @@ -114,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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'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 {{reduction variable 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 variable 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 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}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -138,7 +144,7 @@ T tmain(T argc) { #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -160,7 +166,7 @@ T tmain(T argc) { #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}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp 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) @@ -227,7 +233,7 @@ int main(int argc, char **argv) { #pragma omp 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 simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp 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 simd reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -239,22 +245,22 @@ int main(int argc, char **argv) { #pragma omp simd reduction(^ : S1) // expected-error {{'S1' 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 {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 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 simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 simd reduction(max : argv[1]) // expected-error {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -263,7 +269,7 @@ int main(int argc, char **argv) { #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp 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')}} @@ -285,7 +291,7 @@ int main(int argc, char **argv) { #pragma omp 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 simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp 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) diff --git a/test/OpenMP/simd_safelen_messages.cpp b/test/OpenMP/simd_safelen_messages.cpp index b7300c337532..aa31b7da9b7f 100644 --- a/test/OpenMP/simd_safelen_messages.cpp +++ b/test/OpenMP/simd_safelen_messages.cpp @@ -22,7 +22,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} #pragma omp 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 positive integer value}} + // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} #pragma omp 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 simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} @@ -30,7 +30,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} #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 positive integer value}} + // 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}} #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]; @@ -41,7 +41,7 @@ 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 (4) for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; - #pragma omp simd safelen (N) // expected-error {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp 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; } @@ -61,7 +61,7 @@ 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@+3 {{expression is not an integral constant expression}} // 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 positive integer value}} + // 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}} diff --git a/test/OpenMP/simd_simdlen_messages.cpp b/test/OpenMP/simd_simdlen_messages.cpp new file mode 100644 index 000000000000..91656f87b583 --- /dev/null +++ b/test/OpenMP/simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp 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 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 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 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 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 simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp 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 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 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 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 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp simd simdlen(simdlen(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/single_codegen.cpp b/test/OpenMP/single_codegen.cpp index 327f6fafa834..61a93a5a1b73 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 -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 -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 -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 @@ -38,7 +38,7 @@ int main() { // CHECK-DAG: [[C_ADDR:%.+]] = alloca [[TEST_CLASS_TY]] char a; char a2[2]; - TestClass c; + TestClass &c = tc; // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]]) // CHECK-DAG: [[DID_IT:%.+]] = alloca i32, @@ -81,8 +81,7 @@ int main() { // CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: store i8* [[A_ADDR]], i8** [[A_PTR_REF]], // CHECK: [[C_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[C_PTR_REF_VOID_PTR:%.+]] = bitcast [[TEST_CLASS_TY]]* [[C_ADDR]] to i8* -// CHECK: store i8* [[C_PTR_REF_VOID_PTR]], i8** [[C_PTR_REF]], +// CHECK: store i8* {{.+}}, i8** [[C_PTR_REF]], // CHECK: [[TC_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 // CHECK: [[TC_THREADPRIVATE_ADDR_VOID_PTR:%.+]] = call{{.*}} i8* @__kmpc_threadprivate_cached // CHECK: [[TC_THREADPRIVATE_ADDR:%.+]] = bitcast i8* [[TC_THREADPRIVATE_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]* diff --git a/test/OpenMP/single_firstprivate_codegen.cpp b/test/OpenMP/single_firstprivate_codegen.cpp index 01eaea318119..cc72addb5f45 100644 --- a/test/OpenMP/single_firstprivate_codegen.cpp +++ b/test/OpenMP/single_firstprivate_codegen.cpp @@ -30,7 +30,6 @@ struct 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]+}} } -// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } template T tmain() { @@ -64,36 +63,49 @@ S var(3); // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( -// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp single firstprivate(g) +#pragma omp single firstprivate(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: %{{.+}} = alloca [[CAP_MAIN_TY:%.+]], // LAMBDA: call i32 @__kmpc_single( // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* {{.*}} + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] g = 1; + sivar = 17; // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 17, 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: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_end_single( - // LAMBDA: call i32 @__kmpc_cancel_barrier( + // LAMBDA: call void @__kmpc_barrier( [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 31; // 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: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[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]+}} 31, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -104,40 +116,55 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* -// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) +// BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp single firstprivate(g) +#pragma omp single firstprivate(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR_REF:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR1_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store i{{[0-9]+}}* [[SIVAR_REF]], i{{[0-9]+}}** %{{.+}}, + // BLOCKS: [[SIVAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}, // BLOCKS: call i32 @__kmpc_single( // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // 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]], g = 1; + sivar = 37; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 37, i{{[0-9]+}}* [[SIVAR1_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]+}}* [[SIVAR1_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_end_single( - // BLOCKS: call i32 @__kmpc_cancel_barrier( + // BLOCKS: call void @__kmpc_barrier( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 31; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 31, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } }(); return 0; #else -#pragma omp single firstprivate(t_var, vec, s_arr, var) nowait +#pragma omp single firstprivate(t_var, vec, s_arr, var, sivar) nowait { { vec[0] = t_var; s_arr[0] = var; + sivar = 41; } } return tmain(); @@ -151,6 +178,7 @@ int main() { // 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: call i32 @__kmpc_single( // firstprivate t_var(t_var) @@ -178,6 +206,10 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// firstprivate isvar +// CHEC: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], +// CHEC: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]], + // ~(firstprivate var), ~(firstprivate s_arr) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* @@ -192,36 +224,36 @@ 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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] 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]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[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]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// 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: [[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: [[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]]** % + // 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 i32 @__kmpc_single( + // firstprivate t_var(t_var) -// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], // 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]], // firstprivate vec(vec) -// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], // 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]], // firstprivate s_arr(s_arr) -// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_REF]], // 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_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]] @@ -233,8 +265,6 @@ int main() { // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] // firstprivate var(var) -// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_REF_PTR]], // 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]]) @@ -245,8 +275,7 @@ int main() { // CHECK: call void @__kmpc_end_single( -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) -// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: ret void #endif diff --git a/test/OpenMP/single_firstprivate_messages.cpp b/test/OpenMP/single_firstprivate_messages.cpp index 6f21a42208f4..32de9fdc8806 100644 --- a/test/OpenMP/single_firstprivate_messages.cpp +++ b/test/OpenMP/single_firstprivate_messages.cpp @@ -65,7 +65,7 @@ int foomain(int argc, char **argv) { I e(4); C g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp single firstprivate // expected-error {{expected '(' after 'firstprivate'}} foo(); @@ -109,13 +109,13 @@ int foomain(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp single' directive into a parallel or another task region?}} -#pragma omp single firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}} foo(); v += i; } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp single firstprivate(j) foo(); #pragma omp parallel #pragma omp single firstprivate(i) @@ -148,7 +148,7 @@ int main(int argc, char **argv) { S3 m; S6 n(2); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp parallel #pragma omp single firstprivate // expected-error {{expected '(' after 'firstprivate'}} foo(); @@ -220,7 +220,7 @@ int main(int argc, char **argv) { #pragma omp single firstprivate(xa) // OK: may be firstprivate foo(); #pragma omp parallel -#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp single firstprivate(j) foo(); #pragma omp parallel #pragma omp single firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} @@ -232,7 +232,7 @@ int main(int argc, char **argv) { { int v = 0; int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp single' directive into a parallel or another task region?}} -#pragma omp single firstprivate(i) // expected-error {{private variable cannot be firstprivate}} +#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}} foo(); v += i; } @@ -242,6 +242,9 @@ int main(int argc, char **argv) { #pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}} #pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}} foo(); + static int t; +#pragma omp single firstprivate(t) // OK + foo(); return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } diff --git a/test/OpenMP/single_private_codegen.cpp b/test/OpenMP/single_private_codegen.cpp index e228b1b14887..c98c5ea1dd67 100644 --- a/test/OpenMP/single_private_codegen.cpp +++ b/test/OpenMP/single_private_codegen.cpp @@ -20,9 +20,7 @@ struct S { volatile double g; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i8 } // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } -// CHECK: [[CAP_TMAIN_TY:%.+]] = type { i8 } template T tmain() { S test; @@ -40,34 +38,43 @@ T tmain() { } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) + // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp single private(g) +#pragma omp single private(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, - // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, g = 1; + sivar = 101; // LAMBDA: call {{.*}}i32 @__kmpc_single( // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 101, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[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: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call {{.*}}void @__kmpc_end_single( [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 211; // 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]+}} 211, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -78,27 +85,36 @@ int main() { // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* {{.+}}) + // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) #pragma omp parallel -#pragma omp single private(g) +#pragma omp single private(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, - // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, g = 1; + sivar = 101; // BLOCKS: call {{.*}}i32 @__kmpc_single( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 101, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: double* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 // BLOCKS: call {{.*}}void @__kmpc_end_single( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 203; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 203, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -111,10 +127,11 @@ int main() { S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp single private(t_var, vec, s_arr, s_arr, var, var) +#pragma omp single private(t_var, vec, s_arr, s_arr, var, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 303; } return tmain(); #endif @@ -123,28 +140,30 @@ int main() { // CHECK: define i{{[0-9]+}} @main() // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) -// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* -// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret // -// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK]](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-NOT: alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], // CHECK-NOT: 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: call i32 @__kmpc_single( // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] +// CHECK-NOT: [[SIVAR_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-NOT: [[SIVAR_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]]* @@ -154,11 +173,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]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[TMAIN_MICROTASK:@.+]] to void // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* // CHECK: ret // -// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: define internal void [[TMAIN_MICROTASK]](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_INT_TY]]], diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp index 0e04e0f5aff1..a24cf47cd2a2 100644 --- a/test/OpenMP/single_private_messages.cpp +++ b/test/OpenMP/single_private_messages.cpp @@ -47,7 +47,7 @@ int foomain(I argc, C **argv) { I e(4); I g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp single private // expected-error {{expected '(' after 'private'}} foo(); #pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -84,7 +84,7 @@ int foomain(I argc, C **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp single private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp single private(j) foo(); #pragma omp single private(i) foo(); @@ -103,7 +103,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp single private // expected-error {{expected '(' after 'private'}} foo(); #pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -138,10 +138,13 @@ int main(int argc, char **argv) { } #pragma omp parallel shared(i) #pragma omp parallel private(i) -#pragma omp single private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} +#pragma omp single private(j) foo(); #pragma omp single private(i) foo(); + static int m; +#pragma omp single private(m) // OK + foo(); return 0; } diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp index 6955cf31112e..acf032a22120 100644 --- a/test/OpenMP/target_ast_print.cpp +++ b/test/OpenMP/target_ast_print.cpp @@ -10,39 +10,77 @@ void foo() {} template T tmain(T argc, T *argv) { + T i, j, a[20]; #pragma omp target foo(); -#pragma omp target if (argc > 0) +#pragma omp target if (target:argc > 0) foo(); #pragma omp target if (C) foo(); +#pragma omp target map(i) + foo(); +#pragma omp target map(a[0:10], i) + foo(); +#pragma omp target map(to: i) map(from: j) + foo(); +#pragma omp target map(always,alloc: i) + foo(); return 0; } // CHECK: template int tmain(int argc, int *argv) { +// CHECK-NEXT: int i, j, a[20] // CHECK-NEXT: #pragma omp target // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target if(argc > 0) +// CHECK-NEXT: #pragma omp target if(target: argc > 0) // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target if(5) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: a[0:10],i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(to: i) map(from: j) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(always,alloc: i) +// CHECK-NEXT: foo() // CHECK: template char tmain(char argc, char *argv) { +// CHECK-NEXT: char i, j, a[20] // CHECK-NEXT: #pragma omp target // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target if(argc > 0) +// CHECK-NEXT: #pragma omp target if(target: argc > 0) // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target if(1) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: a[0:10],i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(to: i) map(from: j) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(always,alloc: i) +// CHECK-NEXT: foo() // CHECK: template T tmain(T argc, T *argv) { +// CHECK-NEXT: T i, j, a[20] // CHECK-NEXT: #pragma omp target // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp target if(argc > 0) +// CHECK-NEXT: #pragma omp target if(target: argc > 0) // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target if(C) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: a[0:10],i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(to: i) map(from: j) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(always,alloc: i) +// 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 // CHECK-NEXT: #pragma omp target foo(); @@ -51,6 +89,32 @@ int main (int argc, char **argv) { // CHECK-NEXT: #pragma omp target if(argc > 0) foo(); // CHECK-NEXT: foo(); + +#pragma omp target map(i) if(argc>0) +// CHECK-NEXT: #pragma omp target map(tofrom: i) if(argc > 0) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(i) +// CHECK-NEXT: #pragma omp target map(tofrom: i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(a[0:10], i) +// CHECK-NEXT: #pragma omp target map(tofrom: a[0:10],i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(to: i) map(from: j) +// CHECK-NEXT: #pragma omp target map(to: i) map(from: j) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(always,alloc: i) +// CHECK-NEXT: #pragma omp target map(always,alloc: i) + foo(); +// CHECK-NEXT: foo(); + return tmain(argc, &argc) + tmain(argv[0][0], argv[0]); } diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp new file mode 100644 index 000000000000..bcefa2419dd2 --- /dev/null +++ b/test/OpenMP/target_codegen.cpp @@ -0,0 +1,652 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -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 -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 CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -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 -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 CHECK --check-prefix CHECK-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +// CHECK-DAG: [[TT:%.+]] = type { i64, i8 } +// CHECK-DAG: [[S1:%.+]] = type { double } + +// We have 8 target regions, but only 7 that actually will generate offloading +// code, only 6 will have mapped arguments, and only 4 have all-constant map +// 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: [[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: [[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: [[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: @{{.*}} = private constant i8 0 +// CHECK-DAG: @{{.*}} = private constant i8 0 +// CHECK-DAG: @{{.*}} = private constant i8 0 +// CHECK-DAG: @{{.*}} = private constant i8 0 +// CHECK-DAG: @{{.*}} = private constant i8 0 +// CHECK-DAG: @{{.*}} = private constant i8 0 +// CHECK-DAG: @{{.*}} = private constant i8 0 + +template +struct TT{ + tx X; + ty Y; +}; + +// CHECK: define {{.*}}[[FOO:@.+]]( +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 d; + + // CHECK: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null) + // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 + // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 + // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 + // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] + // CHECK: [[FAIL]] + // CHECK: call void [[HVT0:@.+]]() + // CHECK-NEXT: br label %[[END]] + // CHECK: [[END]] + #pragma omp target + { + } + + // CHECK: store i32 0, i32* [[RHV:%.+]], align 4 + // CHECK: store i32 -1, i32* [[RHV]], align 4 + // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 + // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 + // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}}) + #pragma omp target if(0) + { + a += 1; + } + + // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0)) + // CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0 + // CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0 + // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]] + // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR]], i32 0, i32 [[IDX0]] + // CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]] + // CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]] + // CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8* + // CHECK-DAG: [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8* + + // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 + // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 + // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 + // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] + // CHECK: [[FAIL]] + // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}}) + // CHECK-NEXT: br label %[[END]] + // CHECK: [[END]] + #pragma omp target if(1) + { + aa += 1; + } + + // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10 + // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] + // CHECK: [[IFTHEN]] + // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0)) + // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0 + // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0 + + // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0 + // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0 + // CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]] + // CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]] + // CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8* + // CHECK-DAG: [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8* + + // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1 + // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1 + // CHECK-DAG: store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]] + // CHECK-DAG: store i8* [[P1:%[^,]+]], i8** [[PADDR1]] + // CHECK-DAG: [[BP1]] = inttoptr i[[SZ]] %{{.+}} to i8* + // CHECK-DAG: [[P1]] = inttoptr i[[SZ]] %{{.+}} to i8* + // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 + // CHECK-NEXT: br label %[[IFEND:.+]] + + // CHECK: [[IFELSE]] + // CHECK: store i32 -1, i32* [[RHV]], align 4 + // CHECK-NEXT: br label %[[IFEND:.+]] + + // CHECK: [[IFEND]] + // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 + // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 + // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] + // CHECK: [[FAIL]] + // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}}) + // CHECK-NEXT: br label %[[END]] + // CHECK: [[END]] + #pragma omp target if(n>10) + { + a += 1; + aa += 1; + } + + // We capture 3 VLA sizes in this target region + // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}}, + // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32* + // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]], + // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]], + + // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}}, + // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]], + // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]], + + // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4 + // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]] + // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8 + + // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20 + // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]] + // CHECK: [[TRY]] + // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0)) + // CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0 + // CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0 + // CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0 + + // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]] + // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]] + // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]] + // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]] + // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]] + // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]] + // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]] + // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]] + // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]] + // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]] + // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]] + // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]] + // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]] + // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]] + // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]] + // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]] + // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]] + // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]] + // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]] + // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]] + // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]] + // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]] + // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]] + // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]] + // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]] + // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]] + // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]] + + // The names below are not necessarily consistent with the names used for the + // addresses above as some are repeated. + // CHECK-DAG: [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8* + // CHECK-DAG: [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8* + // CHECK-DAG: store i8* [[BP0]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P0]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8* + // CHECK-DAG: [[P1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8* + // CHECK-DAG: store i8* [[BP1]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P1]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}} + // CHECK-DAG: store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8* + // CHECK-DAG: [[P3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8* + // CHECK-DAG: store i8* [[BP3]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P3]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8* + // CHECK-DAG: [[P4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8* + // CHECK-DAG: store i8* [[BP4]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P4]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP5:%[^,]+]] = bitcast float* %{{.+}} to i8* + // CHECK-DAG: [[P5:%[^,]+]] = bitcast float* %{{.+}} to i8* + // CHECK-DAG: store i8* [[BP5]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P5]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8* + // CHECK-DAG: [[P6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8* + // CHECK-DAG: store i8* [[BP6]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P6]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP7:%[^,]+]] = bitcast double* %{{.+}} to i8* + // CHECK-DAG: [[P7:%[^,]+]] = bitcast double* %{{.+}} to i8* + // CHECK-DAG: store i8* [[BP7]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P7]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}} + + // CHECK-DAG: [[BP8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8* + // CHECK-DAG: [[P8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8* + // CHECK-DAG: store i8* [[BP8]], i8** {{%[^,]+}} + // CHECK-DAG: store i8* [[P8]], i8** {{%[^,]+}} + // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}} + + // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 + // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 + // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 + // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] + + // CHECK: [[FAIL]] + // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}) + // CHECK-NEXT: br label %[[END]] + // CHECK: [[END]] + #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; +} + +// Check that the offloading functions are emitted and that the arguments are +// correct and loaded correctly for the target regions in foo(). + +// CHECK: define internal void [[HVT0]]() + +// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}}) +// Create stack storage and store argument in there. +// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align +// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align +// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32* +// CHECK-64: load i32, i32* [[AA_CADDR]], align +// CHECK-32: load i32, i32* [[AA_ADDR]], align + +// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}}) +// Create stack storage and store argument in there. +// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align +// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align +// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16* +// CHECK: load i16, i16* [[AA_CADDR]], align + +// CHECK: define internal void [[HVT3]] +// Create stack storage and store argument in there. +// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align +// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align +// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align +// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align +// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32* +// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16* +// CHECK-64-DAG:load i32, i32* [[A_CADDR]], align +// CHECK-32-DAG:load i32, i32* [[A_ADDR]], align +// CHECK-DAG: load i16, i16* [[AA_CADDR]], align + +// CHECK: define internal void [[HVT4]] +// 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 i[[SZ]]* [[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]], + +// 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 + +template +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; + } +}; + +// CHECK: define {{.*}}@{{.*}}bar{{.*}} +int bar(int n){ + int a = 0; + + // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}}) + a += foo(n); + + S1 S; + // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}}) + a += S.r1(n); + + // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}}) + a += fstatic(n); + + // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}}) + a += ftemplate(n); + + return a; +} + +// +// CHECK: define {{.*}}[[FS1]] +// +// CHECK: i8* @llvm.stacksave() +// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32* +// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]], +// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]], + +// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]], +// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]], + +// We capture 2 VLA sizes in this target region +// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]] +// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2 + +// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60 +// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]] +// CHECK: [[TRY]] +// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0)) +// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0 +// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0 +// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0 +// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]] +// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]] +// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]] +// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]] +// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]] +// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]] +// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]] +// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]] +// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]] +// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]] +// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]] +// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]] + +// The names below are not necessarily consistent with the names used for the +// addresses above as some are repeated. +// CHECK-DAG: [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8* +// CHECK-DAG: [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8* +// CHECK-DAG: store i8* [[BP0]], i8** {{%[^,]+}} +// CHECK-DAG: store i8* [[P0]], i8** {{%[^,]+}} +// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}} + +// CHECK-DAG: store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}} +// CHECK-DAG: store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}} +// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}} + +// CHECK-DAG: [[BP2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8* +// CHECK-DAG: [[P2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8* +// CHECK-DAG: store i8* [[BP2]], i8** {{%[^,]+}} +// CHECK-DAG: store i8* [[P2]], i8** {{%[^,]+}} +// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}} + +// CHECK-DAG: [[BP3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8* +// CHECK-DAG: [[P3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8* +// CHECK-DAG: store i8* [[BP3]], i8** {{%[^,]+}} +// CHECK-DAG: store i8* [[P3]], i8** {{%[^,]+}} +// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}} + +// CHECK-DAG: [[BP4:%[^,]+]] = bitcast i16* %{{.+}} to i8* +// CHECK-DAG: [[P4:%[^,]+]] = bitcast i16* %{{.+}} to i8* +// CHECK-DAG: store i8* [[BP4]], i8** {{%[^,]+}} +// CHECK-DAG: store i8* [[P4]], i8** {{%[^,]+}} +// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}} + +// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 +// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 +// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 +// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] + +// CHECK: [[FAIL]] +// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}) +// CHECK-NEXT: br label %[[END]] +// CHECK: [[END]] + +// +// CHECK: define {{.*}}[[FSTATIC]] +// +// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50 +// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] +// CHECK: [[IFTHEN]] +// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0)) +// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0 +// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0 + +// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0 +// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0 +// CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]] +// CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]] +// CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8* +// CHECK-DAG: [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8* + +// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1 +// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1 +// CHECK-DAG: store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]] +// CHECK-DAG: store i8* [[P1:%[^,]+]], i8** [[PADDR1]] +// CHECK-DAG: [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8* +// CHECK-DAG: [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8* + +// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2 +// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2 +// CHECK-DAG: store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]] +// CHECK-DAG: store i8* [[P2:%[^,]+]], i8** [[PADDR2]] + +// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3 +// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3 +// CHECK-DAG: store i8* [[BP3:%[^,]+]], i8** [[BPADDR3]] +// CHECK-DAG: store i8* [[P3:%[^,]+]], i8** [[PADDR3]] +// CHECK-DAG: [[BP3]] = bitcast [10 x i32]* %{{.+}} to i8* +// CHECK-DAG: [[P3]] = bitcast [10 x i32]* %{{.+}} to i8* + +// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 +// CHECK-NEXT: br label %[[IFEND:.+]] + +// CHECK: [[IFELSE]] +// CHECK: store i32 -1, i32* [[RHV]], align 4 +// CHECK-NEXT: br label %[[IFEND:.+]] + +// CHECK: [[IFEND]] +// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 +// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 +// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] +// CHECK: [[FAIL]] +// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}) +// CHECK-NEXT: br label %[[END]] +// CHECK: [[END]] + +// +// CHECK: define {{.*}}[[FTEMPLATE]] +// +// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40 +// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]] +// CHECK: [[IFTHEN]] +// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], 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)) +// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0 +// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0 + +// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0 +// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0 +// CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]] +// CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]] +// CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8* +// CHECK-DAG: [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8* + +// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1 +// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1 +// CHECK-DAG: store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]] +// CHECK-DAG: store i8* [[P1:%[^,]+]], i8** [[PADDR1]] +// CHECK-DAG: [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8* +// CHECK-DAG: [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8* + +// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2 +// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2 +// CHECK-DAG: store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]] +// CHECK-DAG: store i8* [[P2:%[^,]+]], i8** [[PADDR2]] +// CHECK-DAG: [[BP2]] = bitcast [10 x i32]* %{{.+}} to i8* +// CHECK-DAG: [[P2]] = bitcast [10 x i32]* %{{.+}} to i8* + +// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4 +// CHECK-NEXT: br label %[[IFEND:.+]] + +// CHECK: [[IFELSE]] +// CHECK: store i32 -1, i32* [[RHV]], align 4 +// CHECK-NEXT: br label %[[IFEND:.+]] + +// CHECK: [[IFEND]] +// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4 +// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 +// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] +// CHECK: [[FAIL]] +// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}) +// CHECK-NEXT: br label %[[END]] +// CHECK: [[END]] + + + +// Check that the offloading functions are emitted and that the arguments are +// correct and loaded correctly for the target regions of the callees of bar(). + +// CHECK: define internal void [[HVT7]] +// Create local storage for each capture. +// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]* +// 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]], +// 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: define internal void [[HVT6]] +// 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]], +// Use captures. +// CHECK-64-DAG: load i32, i32* [[REF_A]] +// CHECK-DAG: load i16, i16* [[REF_AA]] +// CHECK-DAG: load i8, i8* [[REF_AAA]] +// CHECK-32-DAG: load i32, i32* [[LOCAL_A]] +// CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2 + +// CHECK: define internal void [[HVT5]] +// 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]], +// Use captures. +// 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 +#endif diff --git a/test/OpenMP/target_codegen_global_capture.cpp b/test/OpenMP/target_codegen_global_capture.cpp new file mode 100644 index 000000000000..29469cdf71ea --- /dev/null +++ b/test/OpenMP/target_codegen_global_capture.cpp @@ -0,0 +1,287 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -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 -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 CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -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 -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 CHECK --check-prefix CHECK-32 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + + +// CHECK-DAG: [[GA:@.+]] = global double 1.000000e+00 +// CHECK-DAG: [[GB:@.+]] = global double 2.000000e+00 +// CHECK-DAG: [[GC:@.+]] = global double 3.000000e+00 +// CHECK-DAG: [[GD:@.+]] = global double 4.000000e+00 +// CHECK-DAG: [[FA:@.+]] = internal global float 5.000000e+00 +// CHECK-DAG: [[FB:@.+]] = internal global float 6.000000e+00 +// CHECK-DAG: [[FC:@.+]] = internal global float 7.000000e+00 +// CHECK-DAG: [[FD:@.+]] = internal global float 8.000000e+00 +// CHECK-DAG: [[BA:@.+]] = internal global float 9.000000e+00 +// 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 +double Ga = 1.0; +double Gb = 2.0; +double Gc = 3.0; +double Gd = 4.0; + +// CHECK: define {{.*}} @{{.*}}foo{{.*}}( +// 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 +int foo(short a, short b, short c, short d){ + static float Sa = 5.0; + static float Sb = 6.0; + static float Sc = 7.0; + 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-DAG: [[VALLC:%.+]] = load i16, i16* [[LC]], + // CHECK-DAG: [[VALFC:%.+]] = load float, float* @_ZZ3foossssE2Sc, + // CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LD]], + // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* @Gd, + // CHECK-DAG: [[VALFD:%.+]] = load float, float* @_ZZ3foossssE2Sd, + + // 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]]({{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}) + // The parallel region only uses 3 captures. + // CHECK: call {{.*}}@__kmpc_fork_call(%ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}), {{.+}}* %{{.+}}, {{.+}}* %{{.+}}, {{.+}}* %{{.+}}) + // CHECK: call void @.omp_outlined.(i32* %{{.+}}, i32* %{{.+}}, {{.+}}* %{{.+}}, {{.+}}* %{{.+}}, {{.+}}* %{{.+}}) + // Capture d, Gd, Sd, + + // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, + #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; +} + +// CHECK: define {{.*}} @{{.*}}bar{{.*}}( +// 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 +int bar(short a, short b, short c, short d){ + static float Sa = 9.0; + static float Sb = 10.0; + static float Sc = 11.0; + static float Sd = 12.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* @_ZZ3barssssE2Sb, + // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* @Gc, + // CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LLC]], + // CHECK-DAG: [[VALFC:%.+]] = load float, float* @_ZZ3barssssE2Sc, + // CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LLD]], + // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* @Gd, + // CHECK-DAG: [[VALFD:%.+]] = load float, float* @_ZZ3barssssE2Sd, + + // 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; +} + +#endif diff --git a/test/OpenMP/target_data_ast_print.cpp b/test/OpenMP/target_data_ast_print.cpp new file mode 100644 index 000000000000..cdff857e569a --- /dev/null +++ b/test/OpenMP/target_data_ast_print.cpp @@ -0,0 +1,173 @@ +// 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 +T tmain(T argc, T *argv) { + T i, j, b, c, d, e, x[20]; + +#pragma omp target data + i = argc; + +#pragma omp target data if (target data: j > 0) + foo(); + +#pragma omp target data if (b) + foo(); + +#pragma omp target data map(c) + foo(); + +#pragma omp target data map(c) if(b>e) + foo(); + +#pragma omp target data map(x[0:10], c) + foo(); + +#pragma omp target data map(to: c) map(from: d) + foo(); + +#pragma omp target data map(always,alloc: e) + foo(); + +// nesting a target region +#pragma omp target data map(e) +{ + #pragma omp target map(always, alloc: e) + foo(); +} + + return 0; +} + +// CHECK: template 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: i = argc; +// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: c) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: c) if(b > e) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: x[0:10],c) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(to: c) map(from: d) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(always,alloc: e) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: e) +// CHECK-NEXT: { +// CHECK-NEXT: #pragma omp target map(always,alloc: e) +// CHECK-NEXT: foo(); +// CHECK: template 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: i = argc; +// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: c) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: c) if(b > e) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: x[0:10],c) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(to: c) map(from: d) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(always,alloc: e) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: e) +// CHECK-NEXT: { +// CHECK-NEXT: #pragma omp target map(always,alloc: e) +// CHECK-NEXT: foo(); +// CHECK: template 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: i = argc; +// CHECK-NEXT: #pragma omp target data if(target data: j > 0) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data if(b) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: c) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: c) if(b > e) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: x[0:10],c) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(to: c) map(from: d) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(always,alloc: e) +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target data map(tofrom: e) +// CHECK-NEXT: { +// CHECK-NEXT: #pragma omp target map(always,alloc: e) +// CHECK-NEXT: foo(); + +int main (int argc, char **argv) { + int b = argc, c, d, e, f, g, x[20]; + static int a; +// CHECK: static int a; + +#pragma omp target data +// CHECK: #pragma omp target data + a=2; +// CHECK-NEXT: a = 2; +#pragma omp target data if (target data: b) +// CHECK: #pragma omp target data if(target data: b) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target data if (b > g) +// CHECK: #pragma omp target data if(b > g) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target data map(c) +// CHECK-NEXT: #pragma omp target data map(tofrom: c) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target data map(c) if(b>g) +// CHECK-NEXT: #pragma omp target data map(tofrom: c) if(b > g) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target data map(x[0:10], c) +// CHECK-NEXT: #pragma omp target data map(tofrom: x[0:10],c) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target data map(to: c) map(from: d) +// CHECK-NEXT: #pragma omp target data map(to: c) map(from: d) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target data map(always,alloc: e) +// CHECK-NEXT: #pragma omp target data map(always,alloc: e) + foo(); +// CHECK-NEXT: foo(); + +// nesting a target region +#pragma omp target data map(e) +// CHECK-NEXT: #pragma omp target data map(tofrom: e) +{ +// CHECK-NEXT: { + #pragma omp target map(always, alloc: e) +// CHECK-NEXT: #pragma omp target map(always,alloc: e) + foo(); +// CHECK-NEXT: foo(); +} + return tmain(argc, &argc) + tmain(argv[0][0], argv[0]); +} + +#endif diff --git a/test/OpenMP/target_data_device_messages.cpp b/test/OpenMP/target_data_device_messages.cpp new file mode 100644 index 000000000000..9e8e31a28f5b --- /dev/null +++ b/test/OpenMP/target_data_device_messages.cpp @@ -0,0 +1,28 @@ +// 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 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'}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_data_if_messages.cpp b/test/OpenMP/target_data_if_messages.cpp new file mode 100644 index 000000000000..77edefa48b8a --- /dev/null +++ b/test/OpenMP/target_data_if_messages.cpp @@ -0,0 +1,32 @@ +// 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 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}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_data_messages.c b/test/OpenMP/target_data_messages.c new file mode 100644 index 000000000000..cd60d85a9030 --- /dev/null +++ b/test/OpenMP/target_data_messages.c @@ -0,0 +1,27 @@ +// 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) { + L1: + foo(); + #pragma omp target data + { + foo(); + goto L1; // expected-error {{use of undeclared label 'L1'}} + } + goto L2; // expected-error {{use of undeclared label 'L2'}} + #pragma omp target data + L2: + foo(); + + #pragma omp target data(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}} + { + foo(); + } + #pragma omp target unknown // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + { + foo(); + } + return 0; +} diff --git a/test/OpenMP/target_device_messages.cpp b/test/OpenMP/target_device_messages.cpp new file mode 100644 index 000000000000..fb0f2defa42b --- /dev/null +++ b/test/OpenMP/target_device_messages.cpp @@ -0,0 +1,28 @@ +// 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 device // expected-error {{expected '(' after 'device'}} + #pragma omp target device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target device () // expected-error {{expected expression}} + #pragma omp target device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #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 *'}} + #pragma omp target device (argc + argc) + #pragma omp target device (argc), device (argc+1) // expected-error {{directive '#pragma omp target' cannot contain more than one 'device' clause}} + #pragma omp target device (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target 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'}} + foo(); + + return 0; +} diff --git a/test/OpenMP/target_if_messages.cpp b/test/OpenMP/target_if_messages.cpp index 5193b64ff720..4ee7302282f6 100644 --- a/test/OpenMP/target_if_messages.cpp +++ b/test/OpenMP/target_if_messages.cpp @@ -22,6 +22,12 @@ int tmain(T argc, S **argv) { #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if(argc) + #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc) + #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}} + #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}} + #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(); return 0; @@ -40,6 +46,12 @@ int main(int argc, char **argv) { #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(target : argc) + #pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}} + #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}} + #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(); return tmain(argc, argv); diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp new file mode 100644 index 000000000000..2b24c8296406 --- /dev/null +++ b/test/OpenMP/target_map_codegen.cpp @@ -0,0 +1,1015 @@ +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +/// +/// Implicit maps. +/// + +///==========================================================================/// +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -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 -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 CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -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 -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 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] + +// CK1-LABEL: implicit_maps_integer +void implicit_maps_integer (int a){ + int i = a; + + // CK1-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK1-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK1-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK1-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK1-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK1-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK1-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK1-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK1: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + ++i; + } +} + +// CK1: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK1: [[ADDR:%.+]] = alloca i[[sz]], +// CK1: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK1-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK1-64: {{.+}} = load i32, i32* [[CADDR]], +// CK1-32: {{.+}} = load i32, i32* [[ADDR]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -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 -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 CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -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 -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 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] + +// CK2-LABEL: implicit_maps_integer_reference +void implicit_maps_integer_reference (int a){ + int &i = a; + // CK2-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK2-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK2-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK2-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK2-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK2-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK2-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK2-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK2-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK2-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK2: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + ++i; + } +} + +// CK2: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK2: [[ADDR:%.+]] = alloca i[[sz]], +// CK2: [[REF:%.+]] = alloca i32*, +// CK2: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK2-64: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* +// CK2-64: store i32* [[CADDR]], i32** [[REF]], +// CK2-64: [[RVAL:%.+]] = load i32*, i32** [[REF]], +// CK2-64: {{.+}} = load i32, i32* [[RVAL]], +// CK2-32: store i32* [[ADDR]], i32** [[REF]], +// CK2-32: [[RVAL:%.+]] = load i32*, i32** [[REF]], +// CK2-32: {{.+}} = load i32, i32* [[RVAL]], + +#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 -fopenmp -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-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] + +// CK3-LABEL: implicit_maps_parameter +void implicit_maps_parameter (int a){ + + // CK3-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK3-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK3-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK3-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK3-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK3-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK3-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK3-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK3-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK3-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK3-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK3-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK3: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + ++a; + } +} + +// CK3: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK3: [[ADDR:%.+]] = alloca i[[sz]], +// CK3: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK3-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK3-64: {{.+}} = load i32, i32* [[CADDR]], +// CK3-32: {{.+}} = load i32, i32* [[ADDR]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -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 CK4 --check-prefix CK4-64 +// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32 +// RUN: %clang_cc1 -DCK4 -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 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] + +// CK4-LABEL: implicit_maps_nested_integer +void implicit_maps_nested_integer (int a){ + int i = a; + + // The captures in parallel are by reference. Only the capture in target is by + // copy. + + // CK4: call void {{.+}}@__kmpc_fork_call({{.+}} [[KERNELP1:@.+]] to void (i32*, i32*, ...)*), i32* {{.+}}) + // CK4: define internal void [[KERNELP1]](i32* {{[^,]+}}, i32* {{[^,]+}}, i32* {{[^,]+}}) + #pragma omp parallel + { + // CK4-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK4-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK4-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK4-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK4-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK4-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK4-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK4-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK4-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK4-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK4-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK4-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK4: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + #pragma omp parallel + { + ++i; + } + } + } +} + +// CK4: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK4: [[ADDR:%.+]] = alloca i[[sz]], +// CK4: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK4-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK4-64: call void {{.+}}@__kmpc_fork_call({{.+}} [[KERNELP2:@.+]] to void (i32*, i32*, ...)*), i32* [[CADDR]]) +// CK4-32: call void {{.+}}@__kmpc_fork_call({{.+}} [[KERNELP2:@.+]] to void (i32*, i32*, ...)*), i32* [[ADDR]]) +// CK4: define internal void [[KERNELP2]](i32* {{[^,]+}}, i32* {{[^,]+}}, i32* {{[^,]+}}) +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64 +// RUN: %clang_cc1 -DCK5 -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 CK5 --check-prefix CK5-64 +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32 +// RUN: %clang_cc1 -DCK5 -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 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] + +// CK5-LABEL: implicit_maps_nested_integer_and_enum +void implicit_maps_nested_integer_and_enum (int a){ + enum Bla { + SomeEnum = 0x09 + }; + + // Using an enum should not change the mapping information. + int i = a; + + // CK5-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK5-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK5-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK5-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK5-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK5-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK5-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK5-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK5-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK5-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK5-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK5-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK5: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + ++i; + i += SomeEnum; + } +} + +// CK5: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK5: [[ADDR:%.+]] = alloca i[[sz]], +// CK5: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK5-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK5-64: {{.+}} = load i32, i32* [[CADDR]], +// CK5-32: {{.+}} = load i32, i32* [[ADDR]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK6 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64 +// RUN: %clang_cc1 -DCK6 -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 CK6 --check-prefix CK6-64 +// RUN: %clang_cc1 -DCK6 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32 +// RUN: %clang_cc1 -DCK6 -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 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] + +// CK6-LABEL: implicit_maps_host_global +int Gi; +void implicit_maps_host_global (int a){ + // CK6-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK6-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK6-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK6-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK6-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK6-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK6-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK6-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK6-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK6-64-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK6-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK6-64-DAG: store i32 [[GBLVAL:%.+]], i32* [[CADDR]], + // CK6-64-DAG: [[GBLVAL]] = load i32, i32* [[GBL]], + // CK6-32-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[GBLVAL:%.+]], + + // CK6: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + ++Gi; + } +} + +// CK6: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK6: [[ADDR:%.+]] = alloca i[[sz]], +// CK6: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK6-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK6-64: {{.+}} = load i32, i32* [[CADDR]], +// CK6-32: {{.+}} = load i32, i32* [[ADDR]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK7 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64 +// RUN: %clang_cc1 -DCK7 -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 CK7 --check-prefix CK7-64 +// RUN: %clang_cc1 -DCK7 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32 +// RUN: %clang_cc1 -DCK7 -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 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] + +// CK7-LABEL: implicit_maps_double +void implicit_maps_double (int a){ + double d = (double)a; + + // CK7-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK7-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK7-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK7-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK7-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + + // CK7-64-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK7-64-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK7-64-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK7-64-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK7-64-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK7-64-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to double* + // CK7-64-64-DAG: store double {{.+}}, double* [[CADDR]], + + // CK7-32-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK7-32-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK7-32-DAG: [[VALBP]] = bitcast double* [[DECL:%.+]] to i8* + // CK7-32-DAG: [[VALP]] = bitcast double* [[DECL]] to i8* + + // CK7-64: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + // CK7-32: call void [[KERNEL:@.+]](double* [[DECL]]) + #pragma omp target + { + d += 1.0; + } +} + +// CK7-64: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK7-64: [[ADDR:%.+]] = alloca i[[sz]], +// CK7-64: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK7-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to double* +// CK7-64: {{.+}} = load double, double* [[CADDR]], + +// CK7-32: define internal void [[KERNEL]](double* {{.+}}[[ARG:%.+]]) +// CK7-32: [[ADDR:%.+]] = alloca double*, +// CK7-32: store double* [[ARG]], double** [[ADDR]], +// CK7-32: [[REF:%.+]] = load double*, double** [[ADDR]], +// CK7-32: {{.+}} = load double, double* [[REF]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK8 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8 +// RUN: %clang_cc1 -DCK8 -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 CK8 +// RUN: %clang_cc1 -DCK8 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8 +// RUN: %clang_cc1 -DCK8 -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 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] + +// CK8-LABEL: implicit_maps_float +void implicit_maps_float (int a){ + float f = (float)a; + + // CK8-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK8-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK8-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK8-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK8-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK8-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK8-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK8-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK8-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK8-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK8-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to float* + // CK8-DAG: store float {{.+}}, float* [[CADDR]], + + // CK8: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + #pragma omp target + { + f += 1.0; + } +} + +// CK8: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK8: [[ADDR:%.+]] = alloca i[[sz]], +// CK8: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK8: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to float* +// CK8: {{.+}} = load float, float* [[CADDR]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK9 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9 +// RUN: %clang_cc1 -DCK9 -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 CK9 +// RUN: %clang_cc1 -DCK9 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9 +// RUN: %clang_cc1 -DCK9 -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 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] + +// CK9-LABEL: implicit_maps_array +void implicit_maps_array (int a){ + double darr[2] = {(double)a, (double)a}; + + // CK9-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK9-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK9-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK9-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK9-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK9-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK9-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK9-DAG: [[VALBP]] = bitcast [2 x double]* [[DECL:%.+]] to i8* + // CK9-DAG: [[VALP]] = bitcast [2 x double]* [[DECL]] to i8* + + // CK9: call void [[KERNEL:@.+]]([2 x double]* [[DECL]]) + #pragma omp target + { + darr[0] += 1.0; + darr[1] += 1.0; + } +} + +// CK9: define internal void [[KERNEL]]([2 x double]* {{.+}}[[ARG:%.+]]) +// CK9: [[ADDR:%.+]] = alloca [2 x double]*, +// CK9: store [2 x double]* [[ARG]], [2 x double]** [[ADDR]], +// CK9: [[REF:%.+]] = load [2 x double]*, [2 x double]** [[ADDR]], +// CK9: {{.+}} = getelementptr inbounds [2 x double], [2 x double]* [[REF]], i[[sz]] 0, i[[sz]] 0 +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK10 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10 +// RUN: %clang_cc1 -DCK10 -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 CK10 +// RUN: %clang_cc1 -DCK10 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10 +// RUN: %clang_cc1 -DCK10 -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 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-LABEL: implicit_maps_pointer +void implicit_maps_pointer (){ + double *ddyn; + + // CK10-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK10-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK10-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK10-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK10-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK10-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK10-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK10-DAG: [[VALBP]] = bitcast double* [[PTR:%.+]] to i8* + // CK10-DAG: [[VALP]] = bitcast double* [[PTR]] to i8* + + // CK10: call void [[KERNEL:@.+]](double* [[PTR]]) + #pragma omp target + { + ddyn[0] += 1.0; + ddyn[1] += 1.0; + } +} + +// CK10: define internal void [[KERNEL]](double* {{.*}}[[ARG:%.+]]) +// CK10: [[ADDR:%.+]] = alloca double*, +// CK10: store double* [[ARG]], double** [[ADDR]], +// CK10: [[REF:%.+]] = load double*, double** [[ADDR]], +// CK10: {{.+}} = getelementptr inbounds double, double* [[REF]], i[[sz]] 0 + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK11 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -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 CK11 +// RUN: %clang_cc1 -DCK11 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -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 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] + +// CK11-LABEL: implicit_maps_double_complex +void implicit_maps_double_complex (int a){ + double _Complex dc = (double)a; + + // CK11-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK11-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK11-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK11-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK11-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK11-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK11-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK11-DAG: [[VALBP]] = bitcast { double, double }* [[PTR:%.+]] to i8* + // CK11-DAG: [[VALP]] = bitcast { double, double }* [[PTR]] to i8* + + // CK11: call void [[KERNEL:@.+]]({ double, double }* [[PTR]]) + #pragma omp target + { + dc *= dc; + } +} + +// CK11: define internal void [[KERNEL]]({ double, double }* {{.*}}[[ARG:%.+]]) +// CK11: [[ADDR:%.+]] = alloca { double, double }*, +// CK11: store { double, double }* [[ARG]], { double, double }** [[ADDR]], +// CK11: [[REF:%.+]] = load { double, double }*, { double, double }** [[ADDR]], +// CK11: {{.+}} = getelementptr inbounds { double, double }, { double, double }* [[REF]], i32 0, i32 0 +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK12 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64 +// RUN: %clang_cc1 -DCK12 -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 CK12 --check-prefix CK12-64 +// RUN: %clang_cc1 -DCK12 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32 +// RUN: %clang_cc1 -DCK12 -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 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] + +// CK12-LABEL: implicit_maps_float_complex +void implicit_maps_float_complex (int a){ + float _Complex fc = (float)a; + + // CK12-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK12-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK12-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK12-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK12-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + + // CK12-64-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK12-64-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK12-64-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK12-64-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK12-64-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK12-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to { float, float }* + // CK12-64-DAG: store { float, float } {{.+}}, { float, float }* [[CADDR]], + + // CK12-32-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK12-32-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK12-32-DAG: [[VALBP]] = bitcast { float, float }* [[DECL:%.+]] to i8* + // CK12-32-DAG: [[VALP]] = bitcast { float, float }* [[DECL]] to i8* + + // CK12-64: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + // CK12-32: call void [[KERNEL:@.+]]({ float, float }* [[DECL]]) + #pragma omp target + { + fc *= fc; + } +} + +// CK12-64: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK12-64: [[ADDR:%.+]] = alloca i[[sz]], +// CK12-64: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK12-64: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to { float, float }* +// CK12-64: {{.+}} = getelementptr inbounds { float, float }, { float, float }* [[CADDR]], i32 0, i32 0 + +// CK12-32: define internal void [[KERNEL]]({ float, float }* {{.+}}[[ARG:%.+]]) +// CK12-32: [[ADDR:%.+]] = alloca { float, float }*, +// CK12-32: store { float, float }* [[ARG]], { float, float }** [[ADDR]], +// CK12-32: [[REF:%.+]] = load { float, float }*, { float, float }** [[ADDR]], +// CK12-32: {{.+}} = getelementptr inbounds { float, float }, { float, float }* [[REF]], i32 0, i32 0 +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK13 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13 +// RUN: %clang_cc1 -DCK13 -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 CK13 +// RUN: %clang_cc1 -DCK13 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13 +// RUN: %clang_cc1 -DCK13 -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 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] + +// CK13-LABEL: implicit_maps_variable_length_array +void implicit_maps_variable_length_array (int a){ + double vla[2][a]; + + // CK13-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 3, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], i[[sz:64|32]]* [[SGEP:%[^,]+]], {{.+}}[[TYPES]]{{.+}}) + // CK13-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK13-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK13-DAG: [[SGEP]] = getelementptr inbounds {{.+}}[[SS:%[^,]+]], i32 0, i32 0 + + // CK13-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK13-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK13-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[SS]], i32 0, i32 0 + // CK13-DAG: store i8* inttoptr (i[[sz]] 2 to i8*), i8** [[BP0]], + // CK13-DAG: store i8* inttoptr (i[[sz]] 2 to i8*), i8** [[P0]], + // CK13-DAG: store i[[sz]] {{8|4}}, i[[sz]]* [[S0]], + + // CK13-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1 + // CK13-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1 + // CK13-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[SS]], i32 0, i32 1 + // CK13-DAG: store i8* [[VALBP1:%.+]], i8** [[BP1]], + // CK13-DAG: store i8* [[VALP1:%.+]], i8** [[P1]], + // CK13-DAG: [[VALBP1]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK13-DAG: [[VALP1]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK13-DAG: store i[[sz]] {{8|4}}, i[[sz]]* [[S1]], + + // CK13-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 2 + // CK13-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 2 + // CK13-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[SS]], i32 0, i32 2 + // CK13-DAG: store i8* [[VALBP2:%.+]], i8** [[BP2]], + // CK13-DAG: store i8* [[VALP2:%.+]], i8** [[P2]], + // CK13-DAG: store i[[sz]] [[VALS2:%.+]], i[[sz]]* [[S2]], + // CK13-DAG: [[VALBP2]] = bitcast double* [[DECL:%.+]] to i8* + // CK13-DAG: [[VALP2]] = bitcast double* [[DECL]] to i8* + // CK13-DAG: [[VALS2]] = mul nuw i[[sz]] %{{.+}}, 8 + + // CK13: call void [[KERNEL:@.+]](i[[sz]] {{.+}}, i[[sz]] {{.+}}, double* [[DECL]]) + #pragma omp target + { + vla[1][3] += 1.0; + } +} + +// CK13: define internal void [[KERNEL]](i[[sz]] [[VLA0:%.+]], i[[sz]] [[VLA1:%.+]], double* {{.+}}[[ARG:%.+]]) +// CK13: [[ADDR0:%.+]] = alloca i[[sz]], +// CK13: [[ADDR1:%.+]] = alloca i[[sz]], +// CK13: [[ADDR2:%.+]] = alloca double*, +// CK13: store i[[sz]] [[VLA0]], i[[sz]]* [[ADDR0]], +// CK13: store i[[sz]] [[VLA1]], i[[sz]]* [[ADDR1]], +// CK13: store double* [[ARG]], double** [[ADDR2]], +// CK13: {{.+}} = load i[[sz]], i[[sz]]* [[ADDR0]], +// CK13: {{.+}} = load i[[sz]], i[[sz]]* [[ADDR1]], +// CK13: [[REF:%.+]] = load double*, double** [[ADDR2]], +// CK13: {{.+}} = getelementptr inbounds double, double* [[REF]], i[[sz]] %{{.+}} +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK14 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64 +// RUN: %clang_cc1 -DCK14 -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 CK14 --check-prefix CK14-64 +// RUN: %clang_cc1 -DCK14 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32 +// RUN: %clang_cc1 -DCK14 -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 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] + +class SSS { +public: + int a; + double b; + + void foo(int c) { + #pragma omp target + { + a += c; + b += (double)c; + } + } + + SSS(int a, double b) : a(a), b(b) {} +}; + +// CK14-LABEL: implicit_maps_class +void implicit_maps_class (int a){ + SSS sss(a, (double)a); + + // CK14: define {{.*}}void @{{.+}}foo{{.+}}([[ST]]* {{[^,]+}}, i32 {{[^,]+}}) + // CK14-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK14-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK14-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + + // CK14-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK14-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK14-DAG: store i8* [[VALBP0:%.+]], i8** [[BP0]], + // CK14-DAG: store i8* [[VALP0:%.+]], i8** [[P0]], + // CK14-DAG: [[VALBP0]] = bitcast [[ST]]* [[DECL:%.+]] to i8* + // CK14-DAG: [[VALP0]] = bitcast [[ST]]* [[DECL]] to i8* + + // CK14-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1 + // CK14-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1 + // CK14-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK14-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK14-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK14-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK14-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK14-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK14-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK14: call void [[KERNEL:@.+]]([[ST]]* [[DECL]], i[[sz]] {{.+}}) + sss.foo(123); +} + +// CK14: define internal void [[KERNEL]]([[ST]]* [[THIS:%.+]], i[[sz]] [[ARG:%.+]]) +// CK14: [[ADDR0:%.+]] = alloca [[ST]]*, +// CK14: [[ADDR1:%.+]] = alloca i[[sz]], +// CK14: store [[ST]]* [[THIS]], [[ST]]** [[ADDR0]], +// CK14: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR1]], +// CK14: [[REF0:%.+]] = load [[ST]]*, [[ST]]** [[ADDR0]], +// CK14-64: [[CADDR1:%.+]] = bitcast i[[sz]]* [[ADDR1]] to i32* +// CK14-64: {{.+}} = load i32, i32* [[CADDR1]], +// CK14-32: {{.+}} = load i32, i32* [[ADDR1]], +// CK14: {{.+}} = getelementptr inbounds [[ST]], [[ST]]* [[REF0]], i32 0, i32 0 + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK15 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64 +// RUN: %clang_cc1 -DCK15 -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 CK15 --check-prefix CK15-64 +// RUN: %clang_cc1 -DCK15 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32 +// RUN: %clang_cc1 -DCK15 -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 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] + +// 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] + +template +class SSST { +public: + int a; + double b; + int &r; + + void foo(int c) { + #pragma omp target + { + a += c + x; + b += (double)(c + x); + r += x; + } + } + template + void bar(int c) { + #pragma omp target + { + a += c + x + y; + b += (double)(c + x + y); + r += x + y; + } + } + + SSST(int a, double b, int &r) : a(a), b(b), r(r) {} +}; + +// CK15-LABEL: implicit_maps_templated_class +void implicit_maps_templated_class (int a){ + SSST<123> ssst(a, (double)a, a); + + // CK15: define {{.*}}void @{{.+}}foo{{.+}}([[ST]]* {{[^,]+}}, i32 {{[^,]+}}) + // CK15-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK15-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK15-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + + // CK15-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK15-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK15-DAG: store i8* [[VALBP0:%.+]], i8** [[BP0]], + // CK15-DAG: store i8* [[VALP0:%.+]], i8** [[P0]], + // CK15-DAG: [[VALBP0]] = bitcast [[ST]]* [[DECL:%.+]] to i8* + // CK15-DAG: [[VALP0]] = bitcast [[ST]]* [[DECL]] to i8* + + // CK15-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1 + // CK15-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1 + // CK15-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK15-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK15-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK15-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK15-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK15-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK15-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK15: call void [[KERNEL:@.+]]([[ST]]* [[DECL]], i[[sz]] {{.+}}) + ssst.foo(456); + + // CK15: define {{.*}}void @{{.+}}bar{{.+}}([[ST]]* {{[^,]+}}, i32 {{[^,]+}}) + // CK15-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 2, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES2]]{{.+}}, {{.+}}[[TYPES2]]{{.+}}) + // CK15-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK15-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + + // CK15-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK15-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK15-DAG: store i8* [[VALBP0:%.+]], i8** [[BP0]], + // CK15-DAG: store i8* [[VALP0:%.+]], i8** [[P0]], + // CK15-DAG: [[VALBP0]] = bitcast [[ST]]* [[DECL:%.+]] to i8* + // CK15-DAG: [[VALP0]] = bitcast [[ST]]* [[DECL]] to i8* + + // CK15-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 1 + // CK15-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 1 + // CK15-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK15-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK15-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK15-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK15-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK15-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK15-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK15: call void [[KERNEL2:@.+]]([[ST]]* [[DECL]], i[[sz]] {{.+}}) + ssst.bar<210>(789); +} + +// CK15: define internal void [[KERNEL]]([[ST]]* [[THIS:%.+]], i[[sz]] [[ARG:%.+]]) +// CK15: [[ADDR0:%.+]] = alloca [[ST]]*, +// CK15: [[ADDR1:%.+]] = alloca i[[sz]], +// CK15: store [[ST]]* [[THIS]], [[ST]]** [[ADDR0]], +// CK15: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR1]], +// CK15: [[REF0:%.+]] = load [[ST]]*, [[ST]]** [[ADDR0]], +// CK15-64: [[CADDR1:%.+]] = bitcast i[[sz]]* [[ADDR1]] to i32* +// CK15-64: {{.+}} = load i32, i32* [[CADDR1]], +// CK15-32: {{.+}} = load i32, i32* [[ADDR1]], +// CK15: {{.+}} = getelementptr inbounds [[ST]], [[ST]]* [[REF0]], i32 0, i32 0 + +// CK15: define internal void [[KERNEL2]]([[ST]]* [[THIS:%.+]], i[[sz]] [[ARG:%.+]]) +// CK15: [[ADDR0:%.+]] = alloca [[ST]]*, +// CK15: [[ADDR1:%.+]] = alloca i[[sz]], +// CK15: store [[ST]]* [[THIS]], [[ST]]** [[ADDR0]], +// CK15: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR1]], +// CK15: [[REF0:%.+]] = load [[ST]]*, [[ST]]** [[ADDR0]], +// CK15-64: [[CADDR1:%.+]] = bitcast i[[sz]]* [[ADDR1]] to i32* +// CK15-64: {{.+}} = load i32, i32* [[CADDR1]], +// CK15-32: {{.+}} = load i32, i32* [[ADDR1]], +// CK15: {{.+}} = getelementptr inbounds [[ST]], [[ST]]* [[REF0]], i32 0, i32 0 + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK16 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64 +// RUN: %clang_cc1 -DCK16 -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 CK16 --check-prefix CK16-64 +// RUN: %clang_cc1 -DCK16 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32 +// RUN: %clang_cc1 -DCK16 -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 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] + +template +int foo(int d) { + int res = d; + #pragma omp target + { + res += y; + } + return res; +} +// CK16-LABEL: implicit_maps_templated_function +void implicit_maps_templated_function (int a){ + int i = a; + + // CK16: define {{.*}}i32 @{{.+}}foo{{.+}}(i32 {{[^,]+}}) + // CK16-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK16-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK16-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + + // CK16-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK16-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK16-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK16-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK16-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK16-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK16-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK16-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK16-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK16: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + i = foo<543>(i); +} +// CK16: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK16: [[ADDR:%.+]] = alloca i[[sz]], +// CK16: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK16-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK16-64: {{.+}} = load i32, i32* [[CADDR]], +// CK16-32: {{.+}} = load i32, i32* [[ADDR]], + +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK17 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17 +// RUN: %clang_cc1 -DCK17 -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 CK17 +// RUN: %clang_cc1 -DCK17 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17 +// RUN: %clang_cc1 -DCK17 -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 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] + +class SSS { +public: + int a; + double b; +}; + +// CK17-LABEL: implicit_maps_struct +void implicit_maps_struct (int a){ + SSS s = {a, (double)a}; + + // CK17-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK17-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK17-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + // CK17-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK17-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK17-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK17-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK17-DAG: [[VALBP]] = bitcast [[ST]]* [[DECL:%.+]] to i8* + // CK17-DAG: [[VALP]] = bitcast [[ST]]* [[DECL]] to i8* + + // CK17: call void [[KERNEL:@.+]]([[ST]]* [[DECL]]) + #pragma omp target + { + s.a += 1; + s.b += 1.0; + } +} + +// CK17: define internal void [[KERNEL]]([[ST]]* {{.+}}[[ARG:%.+]]) +// CK17: [[ADDR:%.+]] = alloca [[ST]]*, +// CK17: store [[ST]]* [[ARG]], [[ST]]** [[ADDR]], +// CK17: [[REF:%.+]] = load [[ST]]*, [[ST]]** [[ADDR]], +// CK17: {{.+}} = getelementptr inbounds [[ST]], [[ST]]* [[REF]], i32 0, i32 0 +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK18 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 +// RUN: %clang_cc1 -DCK18 -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 CK18 --check-prefix CK18-64 +// RUN: %clang_cc1 -DCK18 -verify -fopenmp -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 +// RUN: %clang_cc1 -DCK18 -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 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] + +template +int foo(T d) { + #pragma omp target + { + d += (T)1; + } + return d; +} +// CK18-LABEL: implicit_maps_template_type_capture +void implicit_maps_template_type_capture (int a){ + int i = a; + + // CK18: define {{.*}}i32 @{{.+}}foo{{.+}}(i32 {{[^,]+}}) + // CK18-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}) + // CK18-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0 + // CK18-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 + + // CK18-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 + // CK18-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 + // CK18-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]], + // CK18-DAG: store i8* [[VALP:%.+]], i8** [[P1]], + // CK18-DAG: [[VALBP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK18-DAG: [[VALP]] = inttoptr i[[sz]] [[VAL:%.+]] to i8* + // CK18-DAG: [[VAL]] = load i[[sz]], i[[sz]]* [[ADDR:%.+]], + // CK18-64-DAG: [[CADDR:%.+]] = bitcast i[[sz]]* [[ADDR]] to i32* + // CK18-64-DAG: store i32 {{.+}}, i32* [[CADDR]], + + // CK18: call void [[KERNEL:@.+]](i[[sz]] [[VAL]]) + i = foo(i); +} +// CK18: define internal void [[KERNEL]](i[[sz]] [[ARG:%.+]]) +// CK18: [[ADDR:%.+]] = alloca i[[sz]], +// CK18: store i[[sz]] [[ARG]], i[[sz]]* [[ADDR]], +// CK18-64: [[CADDR:%.+]] = bitcast i64* [[ADDR]] to i32* +// CK18-64: {{.+}} = load i32, i32* [[CADDR]], +// CK18-32: {{.+}} = load i32, i32* [[ADDR]], + +#endif +#endif diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp new file mode 100644 index 000000000000..d61e766c6b4b --- /dev/null +++ b/test/OpenMP/target_map_messages.cpp @@ -0,0 +1,207 @@ +// 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 // 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 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'}} + 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}} + foo(); +#pragma omp target map(S2::S2s) + foo(); +#pragma omp target map(S2::S2sc) + foo(); +#pragma omp target map(x) + foo(); +#pragma omp target map(to: x) + foo(); +#pragma omp target map(to: to) + foo(); +#pragma omp target map(to) + 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}} + foo(); +#pragma omp target 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}} + 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}} + 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 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 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(to: x) + foo(); +#pragma omp target map(to: to) + foo(); +#pragma omp target map(to) + 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}} + foo(); +#pragma omp target 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}} + 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}} + 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 map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}} + foo(); + + return tmain(argc)+tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} +} + diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp index 5fd41038ad29..723139b08183 100644 --- a/test/OpenMP/task_ast_print.cpp +++ b/test/OpenMP/task_ast_print.cpp @@ -33,11 +33,12 @@ T tmain(T argc, T *argv) { T b = argc, c, d, e, f, g; static T a; S s; -#pragma omp task untied depend(in : argc) + T arr[argc]; +#pragma omp task untied depend(in : argc, argv[b:argc], arr[:]) if (task : argc > 0) a = 2; -#pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S::TS > 0) +#pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S::TS > 0) priority(argc) foo(); -#pragma omp task if (C) mergeable +#pragma omp task if (C) mergeable priority(C) foo(); return 0; } @@ -46,31 +47,34 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: int b = argc, c, d, e, f, g; // CHECK-NEXT: static int a; // CHECK-NEXT: S s; -// CHECK-NEXT: #pragma omp task untied depend(in : argc) +// CHECK-NEXT: int arr[argc]; +// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) +// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) priority(argc) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp task if(5) mergeable +// CHECK-NEXT: #pragma omp task if(5) mergeable priority(5) // CHECK-NEXT: foo() // CHECK: template long tmain(long argc, long *argv) { // CHECK-NEXT: long b = argc, c, d, e, f, g; // CHECK-NEXT: static long a; // CHECK-NEXT: S s; -// CHECK-NEXT: #pragma omp task untied depend(in : argc) +// CHECK-NEXT: long arr[argc]; +// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) +// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) priority(argc) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp task if(1) mergeable +// CHECK-NEXT: #pragma omp task if(1) mergeable priority(1) // CHECK-NEXT: foo() // CHECK: template T tmain(T argc, T *argv) { // CHECK-NEXT: T b = argc, c, d, e, f, g; // CHECK-NEXT: static T a; // CHECK-NEXT: S s; -// CHECK-NEXT: #pragma omp task untied depend(in : argc) +// CHECK-NEXT: T arr[argc]; +// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) +// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) priority(argc) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp task if(C) mergeable +// CHECK-NEXT: #pragma omp task if(C) mergeable priority(C) // CHECK-NEXT: foo() enum Enum {}; @@ -79,15 +83,16 @@ int main(int argc, char **argv) { long x; int b = argc, c, d, e, f, g; static int a; + int arr[10]; #pragma omp threadprivate(a) Enum ee; // CHECK: Enum ee; -#pragma omp task untied mergeable depend(out:argv[1]) - // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[1]) +#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:]) if(task: argc > 0) priority(f) + // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:]) if(task: argc > 0) priority(f) a = 2; // CHECK-NEXT: a = 2; -#pragma omp task default(none), private(argc, b) firstprivate(argv) if (argc > 0) final(a > 0) depend(inout : a) - // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0) depend(inout : a) +#pragma omp task default(none), private(argc, b) firstprivate(argv) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a]) priority(23) + // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23) foo(); // CHECK-NEXT: foo(); return tmain(b, &b) + tmain(x, &x); diff --git a/test/OpenMP/task_codegen.cpp b/test/OpenMP/task_codegen.cpp index 139ac505a9f6..23dc014aad3b 100644 --- a/test/OpenMP/task_codegen.cpp +++ b/test/OpenMP/task_codegen.cpp @@ -18,12 +18,13 @@ struct S { ~S() {} }; int a; -// CHECK-LABEL : @main +// CHECK-LABEL: @main int main() { // CHECK: [[B:%.+]] = alloca i8 // CHECK: [[S:%.+]] = alloca [2 x [[STRUCT_S]]] char b; S s[2]; + int arr[10][a]; // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T]]* @{{.+}}) // CHECK: [[B_REF:%.+]] = getelementptr inbounds [[STRUCT_SHAREDS]], [[STRUCT_SHAREDS]]* [[CAPTURES:%.+]], i32 0, i32 0 // CHECK: store i8* [[B]], i8** [[B_REF]] @@ -52,33 +53,49 @@ int main() { // 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: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 -// CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64* -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 -// CHECK: store i64 4, i64* -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 -// CHECK: store i8 1, i8* -// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1 -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 +// 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]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 1 +// CHECK: store i64 4, i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 2 +// CHECK: store i8 1, i8* [[T0]] +// CHECK: [[DEP:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES]], i64 0, i64 1 +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 0 // CHECK: ptrtoint i8* [[B]] to i64 -// CHECK: store i64 %{{[^,]+}}, i64* -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 -// CHECK: store i64 1, i64* -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 -// CHECK: store i8 1, i8* -// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 2 -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 +// CHECK: store i64 %{{[^,]+}}, i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 1 +// CHECK: store i64 1, i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 2 +// CHECK: store i8 1, i8* [[T0]] +// CHECK: [[DEP:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES]], i64 0, i64 2 +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 0 // CHECK: ptrtoint [2 x [[STRUCT_S]]]* [[S]] to i64 -// CHECK: store i64 %{{[^,]+}}, i64* -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 -// CHECK: store i64 8, i64* -// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 -// CHECK: store i8 1, i8* -// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 -// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8* -// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 3, i8* %{{[^,]+}}, i32 0, i8* null) -#pragma omp task shared(a, s) depend(in : a, b, s) +// CHECK: store i64 %{{[^,]+}}, i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 1 +// CHECK: store i64 8, i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 2 +// CHECK: store i8 1, i8* [[T0]] +// CHECK: [[IDX1:%.+]] = mul nsw i64 0, [[A_VAL:%.+]] +// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// CHECK: [[IDX1:%.+]] = mul nsw i64 9, [[A_VAL]] +// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// CHECK: [[END1:%.+]] = getelementptr i32, i32* [[END]], i32 1 +// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START]] to i64 +// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END1]] to i64 +// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]] +// CHECK: [[DEP:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 3 +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 0 +// CHECK: [[T1:%.*]] = ptrtoint i32* [[START]] to i64 +// CHECK: store i64 [[T1]], i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 +// CHECK: store i64 [[SIZEOF]], i64* [[T0]] +// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 +// CHECK: store i8 1, i8* [[T0]] +// CHECK: [[DEPS:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES]], i32 0, i32 0 +// CHECK: bitcast [[KMP_DEPEND_INFO]]* [[DEPS]] to i8* +// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 4, i8* %{{[^,]+}}, i32 0, i8* null) +#pragma omp task shared(a, s) depend(in : a, b, s, arr[:]) { a = 15; s[1].a = 10; @@ -94,34 +111,56 @@ int main() { // 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: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i32 0, i64 0 -// CHECK: getelementptr inbounds [1 x [[KMP_DEPEND_INFO]]], [1 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 +// 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 // CHECK: ptrtoint [[STRUCT_S]]* %{{.+}} to i64 // CHECK: store i64 %{{[^,]+}}, i64* // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 // CHECK: store i64 4, i64* // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 -// CHECK: store i8 2, i8* -// CHECK: getelementptr inbounds [1 x [[KMP_DEPEND_INFO]]], [1 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 +// CHECK: store i8 3, i8* +// CHECK: [[IDX1:%.+]] = mul nsw i64 4, [[A_VAL]] +// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// 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 +// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END2]] to i64 +// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]] +// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 1 +// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 +// CHECK: ptrtoint i32* [[START1]] to i64 +// CHECK: store i64 %{{[^,]+}}, i64* +// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 +// CHECK: store i64 [[SIZEOF]], i64* +// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 +// CHECK: store i8 3, i8* +// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 // CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8* -// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 1, i8* %{{[^,]+}}, i32 0, i8* null) -#pragma omp task untied depend(out : s[0]) +// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 2, i8* %{{[^,]+}}, i32 0, i8* null) +#pragma omp task untied depend(out : s[0], arr[4:][b]) { 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: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 +// 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* // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 // CHECK: store i64 4, i64* // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 // CHECK: store i8 3, i8* -// CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i32 0, i64 1 -// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i64 0, i64 1 +// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 1 // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 // CHECK: ptrtoint [[STRUCT_S]]* %{{.+}} to i64 // CHECK: store i64 %{{[^,]+}}, i64* @@ -129,10 +168,34 @@ 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: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 +// CHECK: [[IDX1:%.+]] = mul nsw i64 0, [[A_VAL]] +// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] +// 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: [[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 +// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END2]] to i64 +// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]] +// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 2 +// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0 +// CHECK: ptrtoint i32* [[START1]] to i64 +// CHECK: store i64 %{{[^,]+}}, i64* +// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1 +// CHECK: store i64 [[SIZEOF]], i64* +// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2 +// CHECK: store i8 3, i8* +// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0 // CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8* -// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 2, i8* %{{[^,]+}}, i32 0, i8* null) -#pragma omp task final(true) depend(inout: a, s[1]) +// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 3, i8* %{{[^,]+}}, i32 0, i8* null) +#pragma omp task final(true) depend(inout: a, s[1], arr[:a][3:]) { a = 2; } @@ -157,33 +220,36 @@ 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 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY5:@.+]] to i32 (i32, i8*)*)) +// 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: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]]) -#pragma omp task final(b) + int c __attribute__((aligned(128))); +#pragma omp task final(b) shared(c) { a = 4; + c = 5; } return a; } -// CHECK: define internal i32 [[TASK_ENTRY1]](i32, [[KMP_TASK_T]]{{.*}}*) +// CHECK: define internal i32 [[TASK_ENTRY1]](i32, [[KMP_TASK_T]]{{.*}}* noalias) // CHECK: store i32 15, i32* [[A_PTR:@.+]] // CHECK: [[A_VAL:%.+]] = load i32, i32* [[A_PTR]] // CHECK: [[A_VAL_I8:%.+]] = trunc i32 [[A_VAL]] to i8 // CHECK: store i8 [[A_VAL_I8]], i8* %{{.+}} // CHECK: store i32 10, i32* %{{.+}} -// CHECK: define internal i32 [[TASK_ENTRY2]](i32, [[KMP_TASK_T]]{{.*}}*) +// CHECK: define internal i32 [[TASK_ENTRY2]](i32, [[KMP_TASK_T]]{{.*}}* noalias) // CHECK: store i32 1, i32* [[A_PTR:@.+]] -// CHECK: define internal i32 [[TASK_ENTRY3]](i32, [[KMP_TASK_T]]{{.*}}*) +// CHECK: define internal i32 [[TASK_ENTRY3]](i32, [[KMP_TASK_T]]{{.*}}* noalias) // CHECK: store i32 2, i32* [[A_PTR:@.+]] -// CHECK: define internal i32 [[TASK_ENTRY4]](i32, [[KMP_TASK_T]]{{.*}}*) +// CHECK: define internal i32 [[TASK_ENTRY4]](i32, [[KMP_TASK_T]]{{.*}}* noalias) // CHECK: store i32 3, i32* [[A_PTR:@.+]] -// CHECK: define internal i32 [[TASK_ENTRY5]](i32, [[KMP_TASK_T]]{{.*}}*) +// CHECK: define internal i32 [[TASK_ENTRY5]](i32, [[KMP_TASK_T]]{{.*}}* noalias) // CHECK: store i32 4, i32* [[A_PTR:@.+]] +// CHECK: store i32 5, i32* [[C_PTR:%.+]], align 128 #endif diff --git a/test/OpenMP/task_depend_messages.cpp b/test/OpenMP/task_depend_messages.cpp index 152350cca93a..39bf4847890c 100644 --- a/test/OpenMP/task_depend_messages.cpp +++ b/test/OpenMP/task_depend_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s void foo() { } @@ -14,15 +14,18 @@ class vector { int operator[](int index) { return 0; } }; -int main(int argc, char **argv) { +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 task depend // expected-error {{expected '(' after 'depend'}} #pragma omp task 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 task depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} #pragma omp task 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 task depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} + #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} #pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} #pragma omp task depend (out: ) // expected-error {{expected expression}} #pragma omp task 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}} @@ -33,6 +36,22 @@ int main(int argc, char **argv) { #pragma omp task depend (in : ) // expected-error {{expected expression}} #pragma omp task depend (in : main) // expected-error {{expected variable name, array element or array section}} #pragma omp task depend(in : a[0]) // expected-error{{expected variable name, array element or array section}} + #pragma omp task depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + #pragma omp task 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 task 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 task 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 task 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 task depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + #pragma omp task depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}} + #pragma omp task depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp task depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp task depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + #pragma omp task depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + #pragma omp task depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp task 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 task depend(in : argv[ : argc][1 : argc - 1]) + #pragma omp task depend(in : arr[0]) foo(); return 0; diff --git a/test/OpenMP/task_firstprivate_codegen.cpp b/test/OpenMP/task_firstprivate_codegen.cpp index 89aadbeb6a3f..e2244140d1e1 100644 --- a/test/OpenMP/task_firstprivate_codegen.cpp +++ b/test/OpenMP/task_firstprivate_codegen.cpp @@ -26,18 +26,18 @@ volatile double g; // CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* } // CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]* } -// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [[S_DOUBLE_TY]], [2 x [[S_DOUBLE_TY]]], i32, [2 x i32] +// 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]] } -// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_TMAIN_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 T tmain() { S ttt; S test(ttt); - T t_var = T(); + T t_var __attribute__((aligned(128))) = T(); T vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); @@ -50,22 +50,31 @@ T tmain() { } 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 40, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // 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: [[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: 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: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // LAMBDA: ret -#pragma omp task firstprivate(g) +#pragma omp task firstprivate(g, sivar) { // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -75,13 +84,16 @@ int main() { // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] // LAMBDA: store double* %{{.+}}, double** %{{.+}}, - // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}*) + // 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; }(); } }(); @@ -92,31 +104,45 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 40, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, 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: [[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: 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: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // BLOCKS: ret -#pragma omp task firstprivate(g) +#pragma omp task firstprivate(g, sivar) { // 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: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}*) + // 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; }(); } }(); @@ -128,15 +154,17 @@ int main() { int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp task firstprivate(var, t_var, s_arr, vec, s_arr, var) +#pragma omp task firstprivate(var, t_var, s_arr, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 33; } return tmain(); #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]], @@ -157,13 +185,15 @@ int main() { // 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 1, i64 72, i64 32, 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 1, i64 72, 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. @@ -171,7 +201,7 @@ int main() { // 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 32, i32 8, i1 false) +// 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. @@ -179,14 +209,8 @@ int main() { // CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_MAIN_TY]]* // Constructors for s_arr and var. -// var; -// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 -// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3 -// 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]], - // s_arr; -// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// 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: 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:%[^,]+]], @@ -195,6 +219,12 @@ int main() { // 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{{.+}} 3 +// 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 @@ -207,6 +237,13 @@ int main() { // 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{{.+}} 4 +// CHECK: [[SIVAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[SIVAR_ADDR_REF]], +// 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]], @@ -225,61 +262,69 @@ int main() { // 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) +// 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_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 -// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, -// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], -// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// 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]]*) +// 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: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// 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]]) + +// 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 i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]*) +// 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_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 -// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 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: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) // 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, +// 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]], @@ -302,7 +347,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 56, 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 1, 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. @@ -313,15 +358,15 @@ int main() { // 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]+}} 1 +// 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]], -// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_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 @@ -376,7 +421,7 @@ int main() { // 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]]*) +// 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]*, @@ -398,8 +443,8 @@ int main() { // CHECK: ret -// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]*) -// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// 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]]) diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp index 0126d47c50f9..ef5f3856430a 100644 --- a/test/OpenMP/task_firstprivate_messages.cpp +++ b/test/OpenMP/task_firstprivate_messages.cpp @@ -70,7 +70,8 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; + static int m; #pragma omp task firstprivate // expected-error {{expected '(' after 'firstprivate'}} #pragma omp task firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task firstprivate() // expected-error {{expected expression}} @@ -92,7 +93,8 @@ int main(int argc, char **argv) { foo(); #pragma omp task shared(i) #pragma omp task firstprivate(i) -#pragma omp task firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp task firstprivate(j) +#pragma omp task firstprivate(m) // OK foo(); return 0; diff --git a/test/OpenMP/task_if_codegen.cpp b/test/OpenMP/task_if_codegen.cpp index d08c27f5a408..5992be02a84a 100644 --- a/test/OpenMP/task_if_codegen.cpp +++ b/test/OpenMP/task_if_codegen.cpp @@ -21,14 +21,14 @@ int Arg; // CHECK-LABEL: define void @{{.+}}gtid_test void gtid_test() { -// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void +// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 0, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void #pragma omp parallel -#pragma omp task if (false) +#pragma omp task if (task: false) gtid_test(); // CHECK: ret void } -// CHECK: define internal void [[GTID_TEST_REGION1]](i32* [[GTID_PARAM:%.+]], i +// CHECK: define internal void [[GTID_TEST_REGION1]](i32* noalias [[GTID_PARAM:%.+]], i // CHECK: store i32* [[GTID_PARAM]], i32** [[GTID_ADDR_REF:%.+]], // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_REF]] // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]] @@ -45,13 +45,13 @@ void gtid_test() { template int tmain(T Arg) { -#pragma omp task if (true) +#pragma omp task if (task: true) fn1(); #pragma omp task if (false) fn2(); #pragma omp task if (Arg) fn3(); -#pragma omp task if (Arg) depend(in : Arg) +#pragma omp task if (task: Arg) depend(in : Arg) fn4(); #pragma omp task if (Arg) depend(out : Arg) fn5(); diff --git a/test/OpenMP/task_if_messages.cpp b/test/OpenMP/task_if_messages.cpp index ae6bb13093d9..f3f56d51673a 100644 --- a/test/OpenMP/task_if_messages.cpp +++ b/test/OpenMP/task_if_messages.cpp @@ -22,6 +22,12 @@ int tmain(T argc, S **argv) { #pragma omp task if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if(argc) + #pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc) + #pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}} + #pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}} + #pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); return 0; @@ -40,6 +46,12 @@ int main(int argc, char **argv) { #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task if(task : argc) + #pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}} + #pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}} + #pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} foo(); return tmain(argc, argv); diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp index ec67998afdce..64bf8a40f025 100644 --- a/test/OpenMP/task_messages.cpp +++ b/test/OpenMP/task_messages.cpp @@ -6,7 +6,7 @@ void foo() { #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}} class S { - S(const S &s) { a = s.a + 12; } // expected-note 6 {{implicitly declared private here}} + S(const S &s) { a = s.a + 12; } // expected-note 10 {{implicitly declared private here}} int a; public: @@ -29,7 +29,7 @@ public: template int foo() { T a; - T &b = a; // expected-note 4 {{'b' defined here}} + T &b = a; int r; S1 s1; // expected-error@+1 2 {{call to deleted constructor of 'S1'}} @@ -53,16 +53,11 @@ int foo() { #pragma omp task #pragma omp parallel ++a; -// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}} -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} +// expected-error@+2 {{calling a private constructor of class 'S'}} #pragma omp task - // expected-note@+1 2 {{used here}} ++b; -// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}} -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} #pragma omp task -// expected-error@+2 {{calling a private constructor of class 'S'}} -// expected-note@+1 2 {{used here}} +// 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}} @@ -120,9 +115,9 @@ int foo() { int main(int argc, char **argv) { int a; - int &b = a; // expected-note 2 {{'b' defined here}} + int &b = a; S sa; - S &sb = sa; // expected-note 2 {{'sb' defined here}} + S &sb = sa; int r; #pragma omp task { // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} foo(); @@ -192,13 +187,9 @@ L2: #pragma omp task #pragma omp parallel ++a; -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}} #pragma omp task - // expected-note@+1 {{used here}} ++b; -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}} #pragma omp task -// expected-note@+1 {{used here}} #pragma omp parallel shared(a, b) ++a, ++b; #pragma omp task default(none) @@ -218,14 +209,11 @@ L2: #pragma omp task #pragma omp parallel ++sa; -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} +// expected-error@+2 {{calling a private constructor of class 'S'}} #pragma omp task - // expected-note@+1 {{used here}} ++sb; -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} +// expected-error@+2 2 {{calling a private constructor of class 'S'}} #pragma omp task -// expected-error@+2 {{calling a private constructor of class 'S'}} -// expected-note@+1 {{used here}} #pragma omp parallel shared(sa, sb) ++sa, ++sb; // expected-note@+1 2 {{defined as reduction}} diff --git a/test/OpenMP/task_priority_messages.cpp b/test/OpenMP/task_priority_messages.cpp new file mode 100644 index 000000000000..8a5553eb08c5 --- /dev/null +++ b/test/OpenMP/task_priority_messages.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp task priority // expected-error {{expected '(' after 'priority'}} + #pragma omp task priority ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority () // expected-error {{expected expression}} + #pragma omp task priority (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority (argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} + #pragma omp task priority (argc > 0 ? argv[1][0] : argv[2][argc]) + #pragma omp task priority (foobool(argc)), priority (true) // expected-error {{directive '#pragma omp task' cannot contain more than one 'priority' clause}} + #pragma omp task priority (S) // expected-error {{'S' does not refer to a value}} + #pragma omp task priority (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority(0) + #pragma omp task priority(-1) // expected-error {{argument to 'priority' clause must be a non-negative integer value}} + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp task priority // expected-error {{expected '(' after 'priority'}} + #pragma omp task priority ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority () // expected-error {{expected expression}} + #pragma omp task priority (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority (argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} + #pragma omp task priority (argc > 0 ? argv[1][0] : argv[2][argc]) + #pragma omp task priority (foobool(argc)), priority (true) // expected-error {{directive '#pragma omp task' cannot contain more than one 'priority' clause}} + #pragma omp task priority (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp task priority (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task priority(0) + #pragma omp task priority(-1) // expected-error {{argument to 'priority' clause must be a non-negative integer value}} + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/task_private_codegen.cpp b/test/OpenMP/task_private_codegen.cpp index b29d0d39a1e2..1455fd11a91d 100644 --- a/test/OpenMP/task_private_codegen.cpp +++ b/test/OpenMP/task_private_codegen.cpp @@ -27,16 +27,16 @@ volatile double g; // CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* } // CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } // CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 } -// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [[S_DOUBLE_TY]], [2 x [[S_DOUBLE_TY]]], i32, [2 x i32] +// 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]] } -// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_TMAIN_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 T tmain() { S test; - T t_var = T(); + T t_var __attribute__((aligned(128))) = T(); T vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); @@ -49,18 +49,20 @@ T tmain() { } 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 40, 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 48, 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) +#pragma omp task private(g, sivar) { // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -68,14 +70,20 @@ int main() { // 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, %{{.+}}*) + // 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; }(); } }(); @@ -86,26 +94,34 @@ int main() { // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 40, 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 48, 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) +#pragma omp task private(g, sivar) { // 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, %{{.+}}*) + // 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; }(); } }(); @@ -116,11 +132,14 @@ int main() { int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp task private(var, t_var, s_arr, vec, s_arr, var) +#pragma omp task private(var, t_var, s_arr, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 8; } +#pragma omp task + g+=1; return tmain(); #endif } @@ -152,12 +171,8 @@ int main() { // 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. -// var; -// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 -// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF:%.+]]) - // a_arr; -// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// 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:%.+]]) @@ -165,12 +180,17 @@ int main() { // 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: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]], // Start task. // CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]]) +// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() @@ -183,14 +203,14 @@ int main() { // 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) +// 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_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 -// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, -// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]], -// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1 +// 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]], @@ -199,39 +219,42 @@ int main() { // 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]]*) +// 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: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// 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]]) +// 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 i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]*) +// 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_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 -// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 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: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]]) // CHECK: ret i32 // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() @@ -252,13 +275,13 @@ 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 56, 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 1, 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]+}} 1 +// 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; @@ -306,7 +329,7 @@ int main() { // 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]]*) +// 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]*, @@ -328,8 +351,8 @@ int main() { // CHECK: ret -// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]*) -// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// 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]]) diff --git a/test/OpenMP/task_private_messages.cpp b/test/OpenMP/task_private_messages.cpp index c2c1f519d0c1..6bce1352b13e 100644 --- a/test/OpenMP/task_private_messages.cpp +++ b/test/OpenMP/task_private_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - static float S2s; + static float S2s; // expected-note {{static data member is predetermined as shared}} }; const S2 b; const S2 ba[5]; @@ -64,7 +64,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp task private // expected-error {{expected '(' after 'private'}} #pragma omp task private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task private() // expected-error {{expected expression}} @@ -78,7 +78,7 @@ int main(int argc, char **argv) { #pragma omp task private(ba) #pragma omp task private(ca) // expected-error {{shared variable cannot be private}} #pragma omp task private(da) // expected-error {{shared variable cannot be private}} -#pragma omp task private(S2::S2s) +#pragma omp task private(S2::S2s) // expected-error {{shared variable cannot be private}} #pragma omp task private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp task private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}} #pragma omp task shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} @@ -86,13 +86,16 @@ int main(int argc, char **argv) { #pragma omp task firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} foo(); #pragma omp task private(i) -#pragma omp task private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type 'int &'}} +#pragma omp task private(j) foo(); #pragma omp task firstprivate(i) for (int k = 0; k < 10; ++k) { #pragma omp task private(i) foo(); } + static int m; +#pragma omp task private(m) // OK + foo(); return 0; } diff --git a/test/OpenMP/taskgroup_codegen.cpp b/test/OpenMP/taskgroup_codegen.cpp index c04e4c723b8d..d1bc2aafc7b4 100644 --- a/test/OpenMP/taskgroup_codegen.cpp +++ b/test/OpenMP/taskgroup_codegen.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -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 -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// 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 // expected-no-diagnostics // REQUIRES: x86-registered-target #ifndef HEADER diff --git a/test/OpenMP/taskloop_ast_print.cpp b/test/OpenMP/taskloop_ast_print.cpp new file mode 100644 index 000000000000..06164ab168d9 --- /dev/null +++ b/test/OpenMP/taskloop_ast_print.cpp @@ -0,0 +1,74 @@ +// 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 +T tmain(T argc) { + T b = argc, c, d, e, f, g; + static T a; +// CHECK: static T a; +#pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) + // CHECK-NEXT: #pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp parallel +#pragma omp taskloop private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) shared(g) if (c) final(d) mergeable priority(f) nogroup num_tasks(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) + foo(); + // CHECK-NEXT: #pragma omp parallel + // CHECK-NEXT: #pragma omp taskloop private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) shared(g) if(c) final(d) mergeable priority(f) nogroup num_tasks(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: 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 taskloop if(taskloop: a) default(none) shared(a) final(b) priority(5) nogroup num_tasks(argc) + // CHECK-NEXT: #pragma omp taskloop if(taskloop: a) default(none) shared(a) final(b) priority(5) nogroup num_tasks(argc) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp parallel +#pragma omp taskloop private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) shared(g) if(argc) mergeable priority(argc) grainsize(argc) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + foo(); + // CHECK-NEXT: #pragma omp parallel + // CHECK-NEXT: #pragma omp taskloop private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) shared(g) if(argc) mergeable priority(argc) grainsize(argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: foo(); + return (tmain(argc) + tmain(argv[0][0])); +} + +#endif diff --git a/test/OpenMP/taskloop_collapse_messages.cpp b/test/OpenMP/taskloop_collapse_messages.cpp new file mode 100644 index 000000000000..f33da11f5ed9 --- /dev/null +++ b/test/OpenMP/taskloop_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 // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp taskloop 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 taskloop collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp taskloop'}} + return argc; +} + +int main(int argc, char **argv) { + #pragma omp taskloop 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 taskloop 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 taskloop collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp taskloop 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp taskloop collapse(collapse(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp taskloop collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp taskloop'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/taskloop_final_messages.cpp b/test/OpenMP/taskloop_final_messages.cpp new file mode 100644 index 000000000000..a2d7cdae9673 --- /dev/null +++ b/test/OpenMP/taskloop_final_messages.cpp @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { +#pragma omp taskloop final // expected-error {{expected '(' after 'final'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final() // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc > 0 ? argv[1] : argv[2]) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(foobool(argc)), final(true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'final' clause}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc) + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { +#pragma omp taskloop final // expected-error {{expected '(' after 'final'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final() // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc > 0 ? argv[1] : argv[2]) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(foobool(argc)), final(true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'final' clause}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop final(if (tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_firstprivate_messages.cpp b/test/OpenMP/taskloop_firstprivate_messages.cpp new file mode 100644 index 000000000000..e2e87e4697a5 --- /dev/null +++ b/test/OpenMP/taskloop_firstprivate_messages.cpp @@ -0,0 +1,313 @@ +// 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) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} +}; +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 +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp parallel +#pragma omp taskloop firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop 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 taskloop 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 taskloop firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 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}} + foo(); + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp taskloop firstprivate(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; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp parallel +#pragma omp taskloop firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel +#pragma omp taskloop firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp taskloop'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#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 shared(xa) +#pragma omp taskloop firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp taskloop firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(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}} + 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}} + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp taskloop firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} +} + diff --git a/test/OpenMP/taskloop_grainsize_messages.cpp b/test/OpenMP/taskloop_grainsize_messages.cpp new file mode 100644 index 000000000000..047f925b8250 --- /dev/null +++ b/test/OpenMP/taskloop_grainsize_messages.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp taskloop grainsize // expected-error {{expected '(' after 'grainsize'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (foobool(argc)), grainsize (true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'grainsize' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(0) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(-1) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(argc) num_tasks(argc) // expected-error {{'num_tasks' and 'grainsize' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'grainsize' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp taskloop grainsize // expected-error {{expected '(' after 'grainsize'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (foobool(argc)), grainsize (true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'grainsize' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(0) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(-1) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop grainsize(argc) num_tasks(argc) // expected-error {{'num_tasks' and 'grainsize' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'grainsize' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_lastprivate_messages.cpp b/test/OpenMP/taskloop_lastprivate_messages.cpp new file mode 100644 index 000000000000..e4364448159c --- /dev/null +++ b/test/OpenMP/taskloop_lastprivate_messages.cpp @@ -0,0 +1,287 @@ +// 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 +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp parallel +#pragma omp taskloop lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 taskloop 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 taskloop lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel +#pragma omp taskloop lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp taskloop'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop lastprivate(i) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(xa) +#pragma omp taskloop lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : xa) +#pragma omp taskloop lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp taskloop lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} +} diff --git a/test/OpenMP/taskloop_loop_messages.cpp b/test/OpenMP/taskloop_loop_messages.cpp new file mode 100644 index 000000000000..02518e572f3a --- /dev/null +++ b/test/OpenMP/taskloop_loop_messages.cpp @@ -0,0 +1,738 @@ +// 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; + +// Currently, we cannot use "0" for global register variables. +// register int reg0 __asm__("0"); +int reg0; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; + register int reg; // expected-warning {{'register' storage class specifier is deprecated}} +#pragma omp parallel +#pragma omp taskloop + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp taskloop + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp taskloop + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp taskloop + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (int &ref = ii; ref < 10; ref++) { + } +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (int i; i < 10; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok to skip parenthesises. +#pragma omp taskloop + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop + for (int i = 0; i; i++) + c[i] = a[i]; + +#pragma omp parallel +// 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 taskloop + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop + for (int i = 0; !!i; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop + for (int i = 0; i != 1; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop + for (int i = 0;; i++) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp taskloop + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp taskloop + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp taskloop + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp taskloop + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok - step was converted to integer type. +#pragma omp taskloop + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}} +#pragma omp taskloop firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp taskloop'}} +// expected-note@+1 {{defined as linear}} +#pragma omp taskloop linear(ii) +// expected-error@+1 {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be linear, predetermined as private}} + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +#pragma omp taskloop private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +#pragma omp taskloop lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be threadprivate or thread local, predetermined as private}} +#pragma omp taskloop + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + +#pragma omp parallel + { +#pragma omp taskloop + for (reg0 = 0; reg0 < 10; reg0 += 1) + c[reg0] = a[reg0]; + } + +#pragma omp parallel + { +#pragma omp taskloop + for (reg = 0; reg < 10; reg += 1) + c[reg] = a[reg]; + } + +#pragma omp parallel + { +#pragma omp taskloop + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + +#pragma omp parallel + { +#pragma omp taskloop collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +#pragma omp parallel +// expected-error@+2 {{statement after '#pragma omp taskloop' must be a for loop}} +#pragma omp taskloop + for (auto &item : a) { + item = item + 1; + } + +#pragma omp parallel +// 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 taskloop + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp parallel +#pragma omp taskloop + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template +typename iterator_traits::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 '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@+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 parallel +#pragma omp taskloop + for (GoodIter I = begin; I < end; ++I) + ++I; +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp parallel +#pragma omp taskloop + for (GoodIter I = begin; I >= end; --I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (GoodIter I(begin); I < end; ++I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (GoodIter I(nullptr); I < end; ++I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (GoodIter I(0); I < end; ++I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp parallel +#pragma omp taskloop + for (begin = GoodIter(0); begin < end; ++begin) + ++begin; +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp parallel +#pragma omp taskloop + for (begin = begin0; begin < end; ++begin) + ++begin; +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp parallel +#pragma omp taskloop + for (begin = end; begin < end; ++begin) + ++begin; +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp taskloop + for (GoodIter I = begin; I - I; ++I) + ++I; +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp taskloop + for (GoodIter I = begin; begin < end; ++I) + ++I; +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp taskloop + for (GoodIter I = begin; !I; ++I) + ++I; +#pragma omp parallel +// 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 taskloop + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp parallel +#pragma omp taskloop + for (GoodIter I = begin; I >= end; I = I - 1) + ++I; +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp taskloop + for (GoodIter I = begin; I >= end; I = -I) + ++I; +#pragma omp parallel +// 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 taskloop + for (GoodIter I = begin; I >= end; I = 2 + I) + ++I; +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp taskloop + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; +// In the following example, we cannot update the loop variable using '+=' +// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} +#pragma omp parallel +#pragma omp taskloop + for (Iter0 I = begin0; I < end0; ++I) + ++I; +#pragma omp parallel +// 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 taskloop + for (Iter0 I; I < end0; ++I) + ++I; + Iter1 begin1, end1; +// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp parallel +#pragma omp taskloop + for (Iter1 I = begin1; I < end1; ++I) + ++I; +#pragma omp parallel +// 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 taskloop + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +#pragma omp parallel +// 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 taskloop + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template +class TC { +public: + int dotest_lt(IT begin, IT end) { +#pragma omp parallel +// 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 taskloop + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +#pragma omp parallel +// 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 taskloop + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp parallel +#pragma omp taskloop + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template +int dotest_gt(IT begin, IT end) { +#pragma omp parallel +// 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 taskloop + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +#pragma omp parallel +// 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 taskloop + for (IT I = begin; I >= end; I += ST) { + ++I; + } + +#pragma omp parallel +// 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 taskloop + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp parallel +#pragma omp taskloop + for (IT I = begin; I < end; I += TC::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC t1; + TC t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt' requested here}} + dotest_gt(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp parallel +#pragma omp taskloop + 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 parallel +#pragma omp taskloop + 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 parallel +#pragma omp taskloop + 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 parallel +#pragma omp taskloop + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp parallel +#pragma omp taskloop lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/taskloop_misc_messages.c b/test/OpenMP/taskloop_misc_messages.c new file mode 100644 index 000000000000..f9e084e0edd1 --- /dev/null +++ b/test/OpenMP/taskloop_misc_messages.c @@ -0,0 +1,373 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -triple x86_64-unknown-unknown -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp taskloop'}} +#pragma omp taskloop + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp taskloop'}} +#pragma omp taskloop foo + +void test_no_clause() { + int i; +#pragma omp taskloop + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp taskloop' must be a for loop}} +#pragma omp taskloop + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp parallel +#pragma omp taskloop + 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 parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop' are ignored}} +#pragma omp taskloop foo bar + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{directive '#pragma omp taskloop' cannot contain more than one 'nogroup' clause}} +#pragma omp taskloop nogroup nogroup + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop' are ignored}} +#pragma omp taskloop; + for (i = 0; i < 16; ++i) + ; +// expected-warning@+3 {{extra tokens at the end of '#pragma omp taskloop' are ignored}} +// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp taskloop'}} +#pragma omp parallel +#pragma omp taskloop linear(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop' are ignored}} +#pragma omp taskloop private(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop' are ignored}} +#pragma omp taskloop, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); + +void test_collapse() { + int i; +#pragma omp parallel +// expected-error@+1 {{expected '('}} +#pragma omp taskloop collapse + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop collapse( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop collapse() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop collapse(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop collapse(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-warning@+2 {{extra tokens at the end of '#pragma omp taskloop' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp taskloop collapse 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +#pragma omp taskloop 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 parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}} +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp taskloop collapse(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp taskloop collapse(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp taskloop collapse(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp taskloop collapse(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp taskloop collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_private() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop private( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop private(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop private(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop private() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop private(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp taskloop private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp taskloop private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp taskloop lastprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop lastprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop lastprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop lastprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp taskloop lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp taskloop lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp taskloop firstprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop firstprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop firstprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop firstprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp taskloop firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp taskloop lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop 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 parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp taskloop + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp taskloop + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } + + // expected-warning@+2 {{OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed}} + #pragma omp taskloop + for (__int128 ii = 0; ii < 10; ii++) { + c[ii] = a[ii] + b[ii]; + } +} + diff --git a/test/OpenMP/taskloop_num_tasks_messages.cpp b/test/OpenMP/taskloop_num_tasks_messages.cpp new file mode 100644 index 000000000000..94d74eb41eb0 --- /dev/null +++ b/test/OpenMP/taskloop_num_tasks_messages.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp taskloop num_tasks // expected-error {{expected '(' after 'num_tasks'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (foobool(argc)), num_tasks (true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'num_tasks' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(0) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(-1) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(argc) grainsize(argc) // expected-error {{'grainsize' and 'num_tasks' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'num_tasks' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp taskloop num_tasks // expected-error {{expected '(' after 'num_tasks'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (foobool(argc)), num_tasks (true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'num_tasks' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(0) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(-1) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop num_tasks(argc) grainsize(argc) // expected-error {{'grainsize' and 'num_tasks' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'num_tasks' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_priority_messages.cpp b/test/OpenMP/taskloop_priority_messages.cpp new file mode 100644 index 000000000000..6c1584570eb9 --- /dev/null +++ b/test/OpenMP/taskloop_priority_messages.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp taskloop priority // expected-error {{expected '(' after 'priority'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (foobool(argc)), priority (true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'priority' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority(0) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority(-1) // expected-error {{argument to 'priority' clause must be a non-negative integer value}} + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp taskloop priority // expected-error {{expected '(' after 'priority'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (foobool(argc)), priority (true) // expected-error {{directive '#pragma omp taskloop' cannot contain more than one 'priority' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority(0) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop priority(-1) // expected-error {{argument to 'priority' clause must be a non-negative integer value}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_private_messages.cpp b/test/OpenMP/taskloop_private_messages.cpp new file mode 100644 index 000000000000..3d00d3f252b3 --- /dev/null +++ b/test/OpenMP/taskloop_private_messages.cpp @@ -0,0 +1,195 @@ +// 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) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp taskloop private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop shared(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp taskloop 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 taskloop private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp taskloop private(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) { + S4 e(4); + S5 g(5); + int i; + int &j = i; +#pragma omp taskloop private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop 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 taskloop private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop shared(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp taskloop private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp taskloop private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int si; +#pragma omp taskloop private(si) // OK + for(int k = 0; k < argc; ++k) + si = k + 1; + + return 0; +} + diff --git a/test/OpenMP/taskloop_simd_aligned_messages.cpp b/test/OpenMP/taskloop_simd_aligned_messages.cpp new file mode 100644 index 000000000000..b62af044c60f --- /dev/null +++ b/test/OpenMP/taskloop_simd_aligned_messages.cpp @@ -0,0 +1,202 @@ +// 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 taskloop simd aligned(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp taskloop simd aligned(B::ib:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop 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 taskloop simd aligned(z:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop 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 taskloop 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 taskloop simd aligned(B,rp,::z: X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop simd aligned(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp taskloop 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 taskloop simd aligned(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +// expected-note@+1 {{'num' defined here}} +template 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 taskloop 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 taskloop simd aligned(num:4) + for (i = 0; i < num; ++i); + return T(); +} + +template int test_warn() { + int *ind2 = 0; + // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}} + #pragma omp taskloop 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 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 taskloop simd aligned // expected-error {{expected '(' after 'aligned'}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd aligned () // expected-error {{expected expression}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd aligned (argv[1]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop 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 taskloop simd aligned(i) + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int *v = 0; + I i; + #pragma omp taskloop simd aligned(v:16) + for (I k = 0; k < argc; ++k) { i = k; v += 2; } + } + float *f; + #pragma omp taskloop 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 taskloop simd aligned(f:j) + for (I k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp taskloop 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 taskloop simd aligned // expected-error {{expected '(' after 'aligned'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd aligned () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop simd aligned (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd aligned (a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd aligned(h) + for (int k = 0; k < argc; ++k) ++k; + int *pargc = &argc; + foomain(pargc,argv); + return 0; +} + diff --git a/test/OpenMP/taskloop_simd_ast_print.cpp b/test/OpenMP/taskloop_simd_ast_print.cpp new file mode 100644 index 000000000000..3e3b7e4bec2a --- /dev/null +++ b/test/OpenMP/taskloop_simd_ast_print.cpp @@ -0,0 +1,75 @@ +// 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 +T tmain(T argc) { + T b = argc, c, d, e, f, g; + T *ptr; + static T a; +// CHECK: static T a; +#pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) + // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp parallel +#pragma omp taskloop simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) shared(g) if (c) final(d) mergeable priority(f) simdlen(N) nogroup num_tasks(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) + foo(); + // CHECK-NEXT: #pragma omp parallel + // CHECK-NEXT: #pragma omp taskloop simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) shared(g) if(c) final(d) mergeable priority(f) simdlen(N) nogroup num_tasks(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: 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 taskloop simd if(taskloop: a) default(none) shared(a) final(b) priority(5) safelen(8) linear(b), aligned(argv) nogroup num_tasks(argc) + // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: a) default(none) shared(a) final(b) priority(5) safelen(8) linear(b) aligned(argv) nogroup num_tasks(argc) + for (int i = 0; i < 2; ++i) + a = 2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: a = 2; +#pragma omp parallel +#pragma omp taskloop simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) shared(g) if(argc) mergeable priority(argc) simdlen(16) grainsize(argc) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + foo(); + // CHECK-NEXT: #pragma omp parallel + // CHECK-NEXT: #pragma omp taskloop simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) shared(g) if(argc) mergeable priority(argc) simdlen(16) grainsize(argc) + // CHECK-NEXT: for (int i = 0; i < 10; ++i) + // CHECK-NEXT: for (int j = 0; j < 10; ++j) + // CHECK-NEXT: foo(); + return (tmain(argc) + tmain(argv[0][0])); +} + +#endif diff --git a/test/OpenMP/taskloop_simd_collapse_messages.cpp b/test/OpenMP/taskloop_simd_collapse_messages.cpp new file mode 100644 index 000000000000..d178c0834d62 --- /dev/null +++ b/test/OpenMP/taskloop_simd_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 // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp taskloop 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 taskloop simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp taskloop simd'}} + return argc; +} + +int main(int argc, char **argv) { + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp taskloop simd collapse(collapse(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp taskloop simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp taskloop simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/taskloop_simd_final_messages.cpp b/test/OpenMP/taskloop_simd_final_messages.cpp new file mode 100644 index 000000000000..c6580fbaa9b4 --- /dev/null +++ b/test/OpenMP/taskloop_simd_final_messages.cpp @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { +#pragma omp taskloop simd final // expected-error {{expected '(' after 'final'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final() // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc > 0 ? argv[1] : argv[2]) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(foobool(argc)), final(true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'final' clause}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc) + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { +#pragma omp taskloop simd final // expected-error {{expected '(' after 'final'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final() // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc > 0 ? argv[1] : argv[2]) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(foobool(argc)), final(true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'final' clause}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp taskloop simd final(if (tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp new file mode 100644 index 000000000000..83946695204b --- /dev/null +++ b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp @@ -0,0 +1,313 @@ +// 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) {} // expected-note 2 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + S3(S3 &s3) : a(s3.a) {} // expected-note 2 {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} +}; +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 +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; +#pragma omp parallel +#pragma omp taskloop simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop 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 taskloop 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 taskloop simd firstprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 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}} + foo(); + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp taskloop simd firstprivate(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; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; +#pragma omp parallel +#pragma omp taskloop simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel +#pragma omp taskloop simd firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd safelen(5) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#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 shared(xa) +#pragma omp taskloop simd firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp taskloop simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(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}} + 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}} + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp taskloop simd firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} +} + diff --git a/test/OpenMP/taskloop_simd_grainsize_messages.cpp b/test/OpenMP/taskloop_simd_grainsize_messages.cpp new file mode 100644 index 000000000000..45ccb31824fa --- /dev/null +++ b/test/OpenMP/taskloop_simd_grainsize_messages.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp taskloop simd grainsize // expected-error {{expected '(' after 'grainsize'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (foobool(argc)), grainsize (true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'grainsize' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(0) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(-1) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(argc) num_tasks(argc) // expected-error {{'num_tasks' and 'grainsize' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'grainsize' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp taskloop simd grainsize // expected-error {{expected '(' after 'grainsize'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (foobool(argc)), grainsize (true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'grainsize' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(0) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(-1) // expected-error {{argument to 'grainsize' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd grainsize(argc) num_tasks(argc) // expected-error {{'num_tasks' and 'grainsize' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'grainsize' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp new file mode 100644 index 000000000000..ed1bdf5a6e3e --- /dev/null +++ b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp @@ -0,0 +1,287 @@ +// 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 +int foomain(int argc, char **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp parallel +#pragma omp taskloop simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop 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 taskloop 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 taskloop simd lastprivate(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd safelen(5) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop 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 taskloop simd' directive may not be lastprivate, predetermined as linear}} + foo(); +#pragma omp parallel private(xa) +#pragma omp taskloop simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : xa) +#pragma omp taskloop simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(j) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + static int si; +#pragma omp taskloop simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} +} diff --git a/test/OpenMP/taskloop_simd_linear_messages.cpp b/test/OpenMP/taskloop_simd_linear_messages.cpp new file mode 100644 index 000000000000..c9a82b9dc148 --- /dev/null +++ b/test/OpenMP/taskloop_simd_linear_messages.cpp @@ -0,0 +1,249 @@ +// 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 taskloop simd linear(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp taskloop 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 taskloop simd linear(B:ib) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp taskloop simd linear(z:B:ib) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop simd linear(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop simd linear(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop simd linear(B,::z, X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop simd linear(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp taskloop simd linear(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp taskloop simd linear(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +template 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 taskloop simd linear(ind2:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template int test_warn() { + int ind2 = 0; + // expected-warning@+1 {{zero linear step (ind2 should probably be const)}} + #pragma omp taskloop 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 int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; + #pragma omp taskloop simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (uval( // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (ref() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (foo() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (val argc // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (val(argc, // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (argc : 5) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd linear (val(a, b):B::ib) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(ref(e, g)) // expected-error 2 {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'ref'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(uval(i)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int v = 0; + int i; + #pragma omp taskloop simd linear(v:i) + for (int k = 0; k < argc; ++k) { i = k; v += i; } + } + #pragma omp taskloop simd linear(ref(j)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(uval(j)) + for (int k = 0; k < argc; ++k) ++k; + int v = 0; + #pragma omp taskloop simd linear(v:j) + for (int k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp taskloop 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; +} + +void linear_modifiers(int argc) { + int &f = argc; + #pragma omp taskloop simd linear(f) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(val(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(uval(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(ref(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(foo(f)) // expected-error {{expected one of 'ref', val' or 'uval' modifiers}} + for (int k = 0; k < argc; ++k) ++k; +} + +int f; +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 taskloop simd linear(f) linear(f) // expected-error {{linear variable cannot be linear}} expected-note {{defined as linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (ref()) // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (foo()) // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd linear(a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd linear(val(e, g)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop 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 taskloop simd linear(val(i)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}} + for (int k = 0; k < argc; ++k) { ++k; i += 4; } + } + #pragma omp taskloop simd linear(ref(j)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp taskloop simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + foomain(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} + return 0; +} + diff --git a/test/OpenMP/taskloop_simd_loop_messages.cpp b/test/OpenMP/taskloop_simd_loop_messages.cpp new file mode 100644 index 000000000000..47318721102f --- /dev/null +++ b/test/OpenMP/taskloop_simd_loop_messages.cpp @@ -0,0 +1,739 @@ +// 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; + +// Currently, we cannot use "0" for global register variables. +// register int reg0 __asm__("0"); +int reg0; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; + register int reg; // expected-warning {{'register' storage class specifier is deprecated}} +#pragma omp parallel +#pragma omp taskloop simd + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop simd + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop simd + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop simd + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp taskloop simd + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp taskloop simd + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp taskloop simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp taskloop simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (int &ref = ii; ref < 10; ref++) { + } +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (int i; i < 10; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok to skip parenthesises. +#pragma omp taskloop simd + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop simd + for (int i = 0; i; i++) + c[i] = a[i]; + +#pragma omp parallel +// 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 taskloop simd + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop simd + for (int i = 0; !!i; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop simd + for (int i = 0; i != 1; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp taskloop simd + for (int i = 0;; i++) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp taskloop simd + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp taskloop simd + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp taskloop simd + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp taskloop simd + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok - step was converted to integer type. +#pragma omp taskloop simd + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp taskloop simd + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// 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 taskloop simd + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}} +#pragma omp taskloop simd firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +#pragma omp taskloop simd linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +// expected-note@+3 {{defined as private}} +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be private, predetermined as linear}} +#pragma omp parallel +#pragma omp taskloop simd private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +// expected-note@+3 {{defined as lastprivate}} +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be lastprivate, predetermined as linear}} +#pragma omp parallel +#pragma omp taskloop simd lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be threadprivate or thread local, predetermined as linear}} +#pragma omp taskloop simd + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + +#pragma omp parallel + { +#pragma omp taskloop simd + for (reg0 = 0; reg0 < 10; reg0 += 1) + c[reg0] = a[reg0]; + } + +#pragma omp parallel + { +#pragma omp taskloop simd + for (reg = 0; reg < 10; reg += 1) + c[reg] = a[reg]; + } + +#pragma omp parallel + { +#pragma omp taskloop simd + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + +#pragma omp parallel + { +#pragma omp taskloop simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +#pragma omp parallel +// expected-error@+2 {{statement after '#pragma omp taskloop simd' must be a for loop}} +#pragma omp taskloop simd + for (auto &item : a) { + item = item + 1; + } + +#pragma omp parallel +// 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 taskloop simd + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp parallel +#pragma omp taskloop simd + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template +typename iterator_traits::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 '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@+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 parallel +#pragma omp taskloop simd + for (GoodIter I = begin; I < end; ++I) + ++I; +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp parallel +#pragma omp taskloop simd + for (GoodIter I = begin; I >= end; --I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (GoodIter I(begin); I < end; ++I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (GoodIter I(nullptr); I < end; ++I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (GoodIter I(0); I < end; ++I) + ++I; +#pragma omp parallel +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp parallel +#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@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp parallel +#pragma omp taskloop simd + for (begin = begin0; begin < end; ++begin) + ++begin; +#pragma omp parallel +// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp taskloop simd + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp parallel +#pragma omp taskloop simd + for (begin = end; begin < end; ++begin) + ++begin; +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp taskloop simd + for (GoodIter I = begin; I - I; ++I) + ++I; +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp taskloop simd + for (GoodIter I = begin; begin < end; ++I) + ++I; +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +#pragma omp taskloop simd + for (GoodIter I = begin; !I; ++I) + ++I; +#pragma omp parallel +// 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 taskloop simd + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp parallel +#pragma omp taskloop simd + for (GoodIter I = begin; I >= end; I = I - 1) + ++I; +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp taskloop simd + for (GoodIter I = begin; I >= end; I = -I) + ++I; +#pragma omp parallel +// 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 taskloop simd + for (GoodIter I = begin; I >= end; I = 2 + I) + ++I; +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} +#pragma omp taskloop simd + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; +// In the following example, we cannot update the loop variable using '+=' +// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} +#pragma omp parallel +#pragma omp taskloop simd + for (Iter0 I = begin0; I < end0; ++I) + ++I; +#pragma omp parallel +// 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 taskloop simd + for (Iter0 I; I < end0; ++I) + ++I; + Iter1 begin1, end1; +// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} +#pragma omp parallel +#pragma omp taskloop simd + for (Iter1 I = begin1; I < end1; ++I) + ++I; +#pragma omp parallel +// 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 taskloop simd + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +#pragma omp parallel +// 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 taskloop simd + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template +class TC { +public: + int dotest_lt(IT begin, IT end) { +#pragma omp parallel +// 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 taskloop simd + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +#pragma omp parallel +// 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 taskloop simd + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp parallel +#pragma omp taskloop simd + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template +int dotest_gt(IT begin, IT end) { +#pragma omp parallel +// 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 taskloop simd + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +#pragma omp parallel +// 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 taskloop simd + for (IT I = begin; I >= end; I += ST) { + ++I; + } + +#pragma omp parallel +// 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 taskloop simd + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp parallel +#pragma omp taskloop simd + for (IT I = begin; I < end; I += TC::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC t1; + TC t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt' requested here}} + dotest_gt(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop 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 parallel +#pragma omp taskloop simd + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp parallel +#pragma omp taskloop simd lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/taskloop_simd_misc_messages.c b/test/OpenMP/taskloop_simd_misc_messages.c new file mode 100644 index 000000000000..61c7b107d496 --- /dev/null +++ b/test/OpenMP/taskloop_simd_misc_messages.c @@ -0,0 +1,372 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -triple x86_64-unknown-unknown -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp taskloop simd'}} +#pragma omp taskloop simd + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp taskloop simd'}} +#pragma omp taskloop simd foo + +void test_no_clause() { + int i; +#pragma omp taskloop simd + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp taskloop simd' must be a for loop}} +#pragma omp taskloop simd + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp parallel +#pragma omp taskloop 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 parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} +#pragma omp taskloop simd foo bar + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{directive '#pragma omp taskloop simd' cannot contain more than one 'nogroup' clause}} +#pragma omp taskloop simd nogroup nogroup + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} +#pragma omp taskloop simd; + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} +#pragma omp parallel +#pragma omp taskloop simd linear(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} +#pragma omp taskloop simd private(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} +#pragma omp taskloop simd, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); + +void test_collapse() { + int i; +#pragma omp parallel +// expected-error@+1 {{expected '('}} +#pragma omp taskloop simd collapse + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop simd collapse( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd collapse() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop simd collapse(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-warning@+2 {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp taskloop simd collapse 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +#pragma omp taskloop 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 parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp taskloop simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}} +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp taskloop simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp taskloop simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp taskloop simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp taskloop simd collapse(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}} +#pragma omp taskloop simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_private() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp taskloop simd private( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop simd private(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop simd private(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd private() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd private(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp taskloop simd private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp taskloop simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop simd private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd lastprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp taskloop simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd firstprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop simd firstprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp taskloop simd firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd firstprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp taskloop simd firstprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp taskloop simd firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop simd lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp taskloop 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 parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp taskloop simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp taskloop simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } + + // expected-warning@+2 {{OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed}} + #pragma omp taskloop simd + for (__int128 ii = 0; ii < 10; ii++) { + c[ii] = a[ii] + b[ii]; + } +} + diff --git a/test/OpenMP/taskloop_simd_num_tasks_messages.cpp b/test/OpenMP/taskloop_simd_num_tasks_messages.cpp new file mode 100644 index 000000000000..f26ee79a8740 --- /dev/null +++ b/test/OpenMP/taskloop_simd_num_tasks_messages.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp taskloop simd num_tasks // expected-error {{expected '(' after 'num_tasks'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (foobool(argc)), num_tasks (true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'num_tasks' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(0) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(-1) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(argc) grainsize(argc) // expected-error {{'grainsize' and 'num_tasks' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'num_tasks' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp taskloop simd num_tasks // expected-error {{expected '(' after 'num_tasks'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (foobool(argc)), num_tasks (true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'num_tasks' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(0) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(-1) // expected-error {{argument to 'num_tasks' clause must be a strictly positive integer value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd num_tasks(argc) grainsize(argc) // expected-error {{'grainsize' and 'num_tasks' clause are mutually exclusive and may not appear on the same directive}} expected-note {{'num_tasks' clause is specified here}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_simd_priority_messages.cpp b/test/OpenMP/taskloop_simd_priority_messages.cpp new file mode 100644 index 000000000000..a94798f821a6 --- /dev/null +++ b/test/OpenMP/taskloop_simd_priority_messages.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp taskloop simd priority // expected-error {{expected '(' after 'priority'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (foobool(argc)), priority (true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'priority' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (S) // expected-error {{'S' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority(0) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority(-1) // expected-error {{argument to 'priority' clause must be a non-negative integer value}} + for (int i = 0; i < 10; ++i) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp taskloop simd priority // expected-error {{expected '(' after 'priority'}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority () // expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc > 0 ? argv[1][0] : argv[2][argc]) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (foobool(argc)), priority (true) // expected-error {{directive '#pragma omp taskloop simd' cannot contain more than one 'priority' clause}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority(0) + for (int i = 0; i < 10; ++i) + foo(); + #pragma omp taskloop simd priority(-1) // expected-error {{argument to 'priority' clause must be a non-negative integer value}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/taskloop_simd_private_messages.cpp b/test/OpenMP/taskloop_simd_private_messages.cpp new file mode 100644 index 000000000000..4a9b08a7e9e2 --- /dev/null +++ b/test/OpenMP/taskloop_simd_private_messages.cpp @@ -0,0 +1,195 @@ +// 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) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; +#pragma omp taskloop simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop 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 taskloop simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd shared(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp taskloop 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 taskloop simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +void bar(S4 a[2]) { +#pragma omp parallel +#pragma omp taskloop simd private(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) { + S4 e(4); + S5 g(5); + int i; + int &j = i; +#pragma omp taskloop simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop 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 taskloop simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop 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 taskloop simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd shared(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp taskloop simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp taskloop simd private(j) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp taskloop simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + static int si; +#pragma omp taskloop simd private(si) // OK + for(int k = 0; k < argc; ++k) + si = k + 1; + + return 0; +} + diff --git a/test/OpenMP/taskloop_simd_safelen_messages.cpp b/test/OpenMP/taskloop_simd_safelen_messages.cpp new file mode 100644 index 000000000000..3182c8af80fa --- /dev/null +++ b/test/OpenMP/taskloop_simd_safelen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp taskloop simd safelen(safelen(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/taskloop_simd_simdlen_messages.cpp b/test/OpenMP/taskloop_simd_simdlen_messages.cpp new file mode 100644 index 000000000000..ba3f20e23cfe --- /dev/null +++ b/test/OpenMP/taskloop_simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} + 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}} + #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}} + #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) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp taskloop 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 taskloop 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 taskloop 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 taskloop 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 taskloop 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 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}} + 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 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}} + #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}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + #pragma omp taskloop simd simdlen(simdlen(tmain(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain' requested here}} + return tmain(argc, argv); +} + diff --git a/test/OpenMP/teams_ast_print.cpp b/test/OpenMP/teams_ast_print.cpp index 6cea914c8626..292586ae530d 100644 --- a/test/OpenMP/teams_ast_print.cpp +++ b/test/OpenMP/teams_ast_print.cpp @@ -37,7 +37,7 @@ T tmain(T argc, T *argv) { #pragma omp teams a=2; #pragma omp target -#pragma omp teams default(none), private(argc,b) firstprivate(argv) shared (d) reduction(+:c) reduction(max:e) +#pragma omp teams default(none), private(argc,b) firstprivate(argv) shared (d) reduction(+:c) reduction(max:e) num_teams(C) thread_limit(d*C) foo(); #pragma omp target #pragma omp teams reduction(^:e, f) reduction(&& : g) @@ -53,7 +53,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: #pragma omp teams // CHECK-NEXT: a = 2; // CHECK-NEXT: #pragma omp target -// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(5) thread_limit(d * 5) // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target // CHECK-NEXT: #pragma omp teams reduction(^: e,f) reduction(&&: g) @@ -66,7 +66,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: #pragma omp teams // CHECK-NEXT: a = 2; // CHECK-NEXT: #pragma omp target -// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(1) thread_limit(d * 1) // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target // CHECK-NEXT: #pragma omp teams reduction(^: e,f) reduction(&&: g) @@ -79,7 +79,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: #pragma omp teams // CHECK-NEXT: a = 2; // CHECK-NEXT: #pragma omp target -// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(C) thread_limit(d * C) // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target // CHECK-NEXT: #pragma omp teams reduction(^: e,f) reduction(&&: g) @@ -101,9 +101,9 @@ int main (int argc, char **argv) { a=2; // CHECK-NEXT: a = 2; #pragma omp target -#pragma omp teams default(none), private(argc,b) firstprivate(argv) reduction(| : c, d) reduction(* : e) +#pragma omp teams default(none), private(argc,b) num_teams(f) firstprivate(argv) reduction(| : c, d) reduction(* : e) thread_limit(f+g) // CHECK-NEXT: #pragma omp target -// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) reduction(|: c,d) reduction(*: e) +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) num_teams(f) firstprivate(argv) reduction(|: c,d) reduction(*: e) thread_limit(f + g) foo(); // CHECK-NEXT: foo(); return tmain(b, &b) + tmain(x, &x); diff --git a/test/OpenMP/teams_firstprivate_messages.cpp b/test/OpenMP/teams_firstprivate_messages.cpp index ac5197749bb4..ba12fde86b5c 100644 --- a/test/OpenMP/teams_firstprivate_messages.cpp +++ b/test/OpenMP/teams_firstprivate_messages.cpp @@ -63,7 +63,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp target #pragma omp teams firstprivate // expected-error {{expected '(' after 'firstprivate'}} foo(); @@ -125,7 +125,11 @@ int main(int argc, char **argv) { #pragma omp teams firstprivate(i) foo(); #pragma omp target -#pragma omp teams firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} +#pragma omp teams firstprivate(j) + foo(); + static int m; +#pragma omp target +#pragma omp teams firstprivate(m) // OK foo(); return 0; diff --git a/test/OpenMP/teams_num_teams_messages.cpp b/test/OpenMP/teams_num_teams_messages.cpp new file mode 100644 index 000000000000..01871127bda5 --- /dev/null +++ b/test/OpenMP/teams_num_teams_messages.cpp @@ -0,0 +1,111 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc) { + char **a; +#pragma omp target +#pragma omp teams num_teams(C) + foo(); +#pragma omp target +#pragma omp teams num_teams(T) // expected-error {{'T' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams num_teams // expected-error {{expected '(' after 'num_teams'}} + foo(); +#pragma omp target +#pragma omp teams num_teams( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams num_teams() // expected-error {{expected expression}} + foo(); +#pragma omp target +#pragma omp teams num_teams(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams num_teams(argc)) // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); +#pragma omp target +#pragma omp teams num_teams(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); +#pragma omp target +#pragma omp teams num_teams(argc + argc) + foo(); +#pragma omp target +#pragma omp teams num_teams(argc), num_teams (argc+1) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'num_teams' clause}} + foo(); +#pragma omp target +#pragma omp teams num_teams(S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams num_teams(-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}} + foo(); +#pragma omp target +#pragma omp teams num_teams(-10u) + foo(); +#pragma omp target +#pragma omp teams num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return 0; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams num_teams // expected-error {{expected '(' after 'num_teams'}} + foo(); + +#pragma omp target +#pragma omp teams num_teams ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + +#pragma omp target +#pragma omp teams num_teams () // expected-error {{expected expression}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (argc)) // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (argc + argc) + foo(); + +#pragma omp target +#pragma omp teams num_teams (argc), num_teams (argc+1) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'num_teams' clause}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (-2) // expected-error {{argument to 'num_teams' clause must be a strictly positive integer value}} + foo(); + +#pragma omp target +#pragma omp teams num_teams (-10u) + foo(); + +#pragma omp target +#pragma omp teams num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} +} diff --git a/test/OpenMP/teams_private_messages.cpp b/test/OpenMP/teams_private_messages.cpp index f50060ff29b3..344ef8daf996 100644 --- a/test/OpenMP/teams_private_messages.cpp +++ b/test/OpenMP/teams_private_messages.cpp @@ -13,7 +13,7 @@ class S2 { mutable int a; public: S2():a(0) { } - static float S2s; + static float S2s; // expected-note {{static data member is predetermined as shared}} }; const S2 b; const S2 ba[5]; @@ -55,7 +55,7 @@ int main(int argc, char **argv) { S4 e(4); S5 g(5); int i; - int &j = i; // expected-note {{'j' defined here}} + int &j = i; #pragma omp target #pragma omp teams private // expected-error {{expected '(' after 'private'}} foo(); @@ -96,7 +96,7 @@ int main(int argc, char **argv) { #pragma omp teams private(da) // expected-error {{shared variable cannot be private}} foo(); #pragma omp target - #pragma omp teams private(S2::S2s) + #pragma omp teams private(S2::S2s) // expected-error {{shared variable cannot be private}} foo(); #pragma omp target #pragma omp teams private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} @@ -114,7 +114,7 @@ int main(int argc, char **argv) { #pragma omp teams private(i) foo(); #pragma omp target - #pragma omp teams private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type 'int &'}} + #pragma omp teams private(j) foo(); #pragma omp target #pragma omp teams firstprivate(i) @@ -122,6 +122,10 @@ int main(int argc, char **argv) { #pragma omp parallel private(i) foo(); } + static int m; + #pragma omp target + #pragma omp teams private(m) // OK + foo(); return 0; } diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp index 93c4b141591f..87d03485c17b 100644 --- a/test/OpenMP/teams_reduction_messages.cpp +++ b/test/OpenMP/teams_reduction_messages.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -o - %s +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s void foo() { } @@ -16,7 +18,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; + 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}} @@ -26,6 +28,7 @@ class S3 { int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -54,6 +57,9 @@ 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}} +#if __cplusplus >= 201103L // C++11 or later +// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}} +#endif int a; public: @@ -103,7 +109,7 @@ T tmain(T argc) { #pragma omp teams 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 -#pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#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'}} @@ -115,31 +121,31 @@ 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 {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable 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 3 {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target -#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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}} foo(); #pragma omp target -#pragma omp teams reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#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]'}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2s) +#pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -158,7 +164,7 @@ T tmain(T argc) { #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}} foo(); #pragma omp target -#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) @@ -231,7 +237,7 @@ int main(int argc, char **argv) { #pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target -#pragma omp teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target #pragma omp teams reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -243,31 +249,31 @@ int main(int argc, char **argv) { #pragma omp teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target -#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'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 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target -#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable 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 variable 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 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 -#pragma omp teams reduction(max : argv[1]) // expected-error {{expected variable name}} +#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 variable with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2s) +#pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams 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')}} @@ -289,7 +295,7 @@ int main(int argc, char **argv) { #pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} foo(); #pragma omp target -#pragma omp teams reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) @@ -310,6 +316,10 @@ int main(int argc, char **argv) { #pragma omp target #pragma omp teams reduction(+ : fl) foo(); + static int m; +#pragma omp target +#pragma omp teams reduction(+ : m) // OK + foo(); return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/test/OpenMP/teams_thread_limit_messages.cpp b/test/OpenMP/teams_thread_limit_messages.cpp new file mode 100644 index 000000000000..1cb147c60781 --- /dev/null +++ b/test/OpenMP/teams_thread_limit_messages.cpp @@ -0,0 +1,111 @@ +// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} + +template // expected-note {{declared here}} +T tmain(T argc) { + char **a; +#pragma omp target +#pragma omp teams thread_limit(C) + foo(); +#pragma omp target +#pragma omp teams thread_limit(T) // expected-error {{'T' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams thread_limit // expected-error {{expected '(' after 'thread_limit'}} + foo(); +#pragma omp target +#pragma omp teams thread_limit( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams thread_limit() // expected-error {{expected expression}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(argc)) // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(argc > 0 ? a[1] : a[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(argc + argc) + foo(); +#pragma omp target +#pragma omp teams thread_limit(argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'thread_limit' clause}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}} + foo(); +#pragma omp target +#pragma omp teams thread_limit(-10u) + foo(); +#pragma omp target +#pragma omp teams thread_limit(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return 0; +} + +int main(int argc, char **argv) { +#pragma omp target +#pragma omp teams thread_limit // expected-error {{expected '(' after 'thread_limit'}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit () // expected-error {{expected expression}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (argc)) // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (argc + argc) + foo(); + +#pragma omp target +#pragma omp teams thread_limit (argc), thread_limit (argc+1) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'thread_limit' clause}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (-2) // expected-error {{argument to 'thread_limit' clause must be a strictly positive integer value}} + foo(); + +#pragma omp target +#pragma omp teams thread_limit (-10u) + foo(); + +#pragma omp target +#pragma omp teams thread_limit (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}} + foo(); + + return tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} +} diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp index 7176e0499273..53d7ef708385 100644 --- a/test/OpenMP/threadprivate_codegen.cpp +++ b/test/OpenMP/threadprivate_codegen.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -DBODY -triple x86_64-unknown-unknown -x c++ -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 -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s +// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s // RUN: %clang_cc1 -verify -fopenmp -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=CHECK-TLS // 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 -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-TLS %s +// RUN: %clang_cc1 -fopenmp -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-TLS %s // expected-no-diagnostics // REQUIRES: x86-registered-target @@ -177,11 +177,11 @@ struct S5 { // CHECK-TLS-DAG: [[ST_S4_ST_GUARD:@_ZGVN2STI2S4E2stE]] = linkonce_odr thread_local global i64 0 // CHECK-TLS-DAG: @__tls_guard = internal thread_local global i8 0 // CHECK-TLS-DAG: @__dso_handle = external global i8 -// CHECK-TLS-DAG: [[GS1_TLS_INIT:@_ZTHL3gs1]] = internal alias void ()* @__tls_init -// CHECK-TLS-DAG: [[ARR_X_TLS_INIT:@_ZTH5arr_x]] = alias void ()* @__tls_init -// CHECK-TLS-DAG: [[ST_INT_ST_TLS_INIT:@_ZTHN2STIiE2stE]] = linkonce_odr alias void ()* @__tls_init -// CHECK-TLS-DAG: [[ST_FLOAT_ST_TLS_INIT:@_ZTHN2STIfE2stE]] = linkonce_odr alias void ()* @__tls_init -// CHECK-TLS-DAG: [[ST_S4_ST_TLS_INIT:@_ZTHN2STI2S4E2stE]] = linkonce_odr alias void ()* @__tls_init +// CHECK-TLS-DAG: [[GS1_TLS_INIT:@_ZTHL3gs1]] = internal alias void (), void ()* @__tls_init +// CHECK-TLS-DAG: [[ARR_X_TLS_INIT:@_ZTH5arr_x]] = alias void (), void ()* @__tls_init +// CHECK-TLS-DAG: [[ST_INT_ST_TLS_INIT:@_ZTHN2STIiE2stE]] = linkonce_odr alias void (), void ()* @__tls_init +// CHECK-TLS-DAG: [[ST_FLOAT_ST_TLS_INIT:@_ZTHN2STIfE2stE]] = linkonce_odr alias void (), void ()* @__tls_init +// CHECK-TLS-DAG: [[ST_S4_ST_TLS_INIT:@_ZTHN2STI2S4E2stE]] = linkonce_odr alias void (), void ()* @__tls_init struct Static { static S3 s; @@ -939,11 +939,11 @@ int foobar() { // CHECK-TLS: define internal void @__tls_init() // CHECK-TLS: [[GRD:%.*]] = load i8, i8* @__tls_guard // CHECK-TLS-NEXT: [[IS_INIT:%.*]] = icmp eq i8 [[GRD]], 0 -// CHECK-TLS-NEXT: store i8 1, i8* @__tls_guard // CHECK-TLS-NEXT: br i1 [[IS_INIT]], label %[[INIT_LABEL:[^,]+]], label %[[DONE_LABEL:[^,]+]]{{.*}} // CHECK-TLS: [[INIT_LABEL]] +// CHECK-TLS-NEXT: store i8 1, i8* @__tls_guard // CHECK-TLS: call void [[GS1_CXX_INIT]] -// CHECK-TLS-NOT call void [[GS2_CXX_INIT]] +// CHECK-TLS-NOT: call void [[GS2_CXX_INIT]] // CHECK-TLS: call void [[ARR_X_CXX_INIT]] // CHECK-TLS: call void [[ST_S4_ST_CXX_INIT]] // CHECK-TLS: [[DONE_LABEL]] diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp index 39a4431f0c5b..f71d58bc52a4 100644 --- a/test/OpenMP/threadprivate_messages.cpp +++ b/test/OpenMP/threadprivate_messages.cpp @@ -96,7 +96,10 @@ class TempClass { static __thread int t; // expected-note {{'t' defined here}} #pragma omp threadprivate (t) // expected-error {{variable 't' cannot be threadprivate because it is thread-local}} -register int reg0 __asm__("0"); // expected-note {{'reg0' defined here}} +// Register "0" is currently an invalid register for global register variables. +// Use "esp" instead of "0". +// register int reg0 __asm__("0"); +register int reg0 __asm__("esp"); // expected-note {{'reg0' defined here}} #pragma omp threadprivate (reg0) // expected-error {{variable 'reg0' cannot be threadprivate because it is a global named register variable}} int o; // expected-note {{candidate found by name lookup is 'o'}} -- cgit v1.2.3