From 9c3cdb43c2bdaf8a8d2e62db010b04f6086d76b7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 15 Mar 2020 01:27:40 +0100 Subject: [PATCH] tree-nested: Fix handling of *reduction clauses with C array sections [PR93566] tree-nested.c didn't handle C array sections in {,task_,in_}reduction clauses. 2020-03-14 Jakub Jelinek PR middle-end/93566 * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Handle {,in_,task_}reduction clauses with C/C++ array sections. * testsuite/libgomp.c/pr93566.c: New test. --- gcc/ChangeLog | 7 ++ gcc/tree-nested.c | 37 +++++++-- libgomp/ChangeLog | 5 ++ libgomp/testsuite/libgomp.c/pr93566.c | 113 ++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c/pr93566.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91e9467e22e..883e13fa7d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-03-14 Jakub Jelinek + + PR middle-end/93566 + * tree-nested.c (convert_nonlocal_omp_clauses, + convert_local_omp_clauses): Handle {,in_,task_}reduction clauses + with C/C++ array sections. + 2020-03-14 H.J. Lu PR target/89229 diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 2bb11066186..6f696da5332 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -1188,7 +1188,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { struct nesting_info *const info = (struct nesting_info *) wi->info; bool need_chain = false, need_stmts = false; - tree clause, decl; + tree clause, decl, *pdecl; int dummy; bitmap new_suppress; @@ -1197,6 +1197,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) { + pdecl = NULL; switch (OMP_CLAUSE_CODE (clause)) { case OMP_CLAUSE_REDUCTION: @@ -1204,6 +1205,15 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_TASK_REDUCTION: if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) need_stmts = true; + if (TREE_CODE (OMP_CLAUSE_DECL (clause)) == MEM_REF) + { + pdecl = &TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0); + if (TREE_CODE (*pdecl) == POINTER_PLUS_EXPR) + pdecl = &TREE_OPERAND (*pdecl, 0); + if (TREE_CODE (*pdecl) == INDIRECT_REF + || TREE_CODE (*pdecl) == ADDR_EXPR) + pdecl = &TREE_OPERAND (*pdecl, 0); + } goto do_decl_clause; case OMP_CLAUSE_LASTPRIVATE: @@ -1230,7 +1240,9 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_USE_DEVICE_ADDR: case OMP_CLAUSE_IS_DEVICE_PTR: do_decl_clause: - decl = OMP_CLAUSE_DECL (clause); + if (pdecl == NULL) + pdecl = &OMP_CLAUSE_DECL (clause); + decl = *pdecl; if (VAR_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) break; @@ -1239,7 +1251,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_SHARED) OMP_CLAUSE_SHARED_READONLY (clause) = 0; bitmap_set_bit (new_suppress, DECL_UID (decl)); - OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl); + *pdecl = get_nonlocal_debug_decl (info, decl); if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE) need_chain = true; } @@ -1909,7 +1921,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { struct nesting_info *const info = (struct nesting_info *) wi->info; bool need_frame = false, need_stmts = false; - tree clause, decl; + tree clause, decl, *pdecl; int dummy; bitmap new_suppress; @@ -1918,6 +1930,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) { + pdecl = NULL; switch (OMP_CLAUSE_CODE (clause)) { case OMP_CLAUSE_REDUCTION: @@ -1925,6 +1938,15 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_TASK_REDUCTION: if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) need_stmts = true; + if (TREE_CODE (OMP_CLAUSE_DECL (clause)) == MEM_REF) + { + pdecl = &TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0); + if (TREE_CODE (*pdecl) == POINTER_PLUS_EXPR) + pdecl = &TREE_OPERAND (*pdecl, 0); + if (TREE_CODE (*pdecl) == INDIRECT_REF + || TREE_CODE (*pdecl) == ADDR_EXPR) + pdecl = &TREE_OPERAND (*pdecl, 0); + } goto do_decl_clause; case OMP_CLAUSE_LASTPRIVATE: @@ -1951,7 +1973,9 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_USE_DEVICE_ADDR: case OMP_CLAUSE_IS_DEVICE_PTR: do_decl_clause: - decl = OMP_CLAUSE_DECL (clause); + if (pdecl == NULL) + pdecl = &OMP_CLAUSE_DECL (clause); + decl = *pdecl; if (VAR_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) break; @@ -1964,8 +1988,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_SHARED) OMP_CLAUSE_SHARED_READONLY (clause) = 0; bitmap_set_bit (new_suppress, DECL_UID (decl)); - OMP_CLAUSE_DECL (clause) - = get_local_debug_decl (info, decl, field); + *pdecl = get_local_debug_decl (info, decl, field); need_frame = true; } } diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index bff3ae58c9a..5882c8a13f3 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2020-03-14 Jakub Jelinek + + PR middle-end/93566 + * testsuite/libgomp.c/pr93566.c: New test. + 2020-02-21 Frederik Harwath * testsuite/libgomp.oacc-fortran/acc_get_property.f90: Adapt to diff --git a/libgomp/testsuite/libgomp.c/pr93566.c b/libgomp/testsuite/libgomp.c/pr93566.c new file mode 100644 index 00000000000..3334bd571f6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr93566.c @@ -0,0 +1,113 @@ +/* PR middle-end/93566 */ +/* { dg-additional-options "-std=c99" } */ + +extern void abort (void); + +void +foo (int *x) +{ + void nest (void) { + #pragma omp parallel for reduction(+:x[:10]) + for (int i = 0; i < 1024; i++) + for (int j = 0; j < 10; j++) + x[j] += j * i; + } + nest (); + for (int i = 0; i < 10; i++) + if (x[i] != 1023 * 1024 / 2 * i) + abort (); +} + +void +bar (void) +{ + int x[10] = {}; + void nest (void) { + #pragma omp parallel for reduction(+:x[:10]) + for (int i = 0; i < 1024; i++) + for (int j = 0; j < 10; j++) + x[j] += j * i; + } + nest (); + for (int i = 0; i < 10; i++) + if (x[i] != 1023 * 1024 / 2 * i) + abort (); +} + +void +baz (void) +{ + int x[10] = {}; + void nest (void) { + #pragma omp parallel for reduction(+:x[2:5]) + for (int i = 0; i < 1024; i++) + for (int j = 2; j < 7; j++) + x[j] += j * i; + } + nest (); + for (int i = 2; i < 7; i++) + if (x[i] != 1023 * 1024 / 2 * i) + abort (); +} + +void +qux (int *x) +{ + void nest (void) { x++; } + nest (); + #pragma omp parallel for reduction(+:x[:9]) + for (int i = 0; i < 1024; i++) + for (int j = 0; j < 9; j++) + x[j] += j * i; + nest (); + for (int i = 0; i < 9; i++) + if (x[i - 1] != 1023 * 1024 / 2 * i) + abort (); +} + +void +quux (void) +{ + int x[10]; + void nest (void) { for (int i = 0; i < 10; i++) x[i] = 0; } + int nest2 (int i) { return x[i]; } + nest (); + #pragma omp parallel for reduction(+:x[:7]) + for (int i = 0; i < 1024; i++) + for (int j = 0; j < 7; j++) + x[j] += j * i; + for (int i = 0; i < 7; i++) + if (nest2 (i) != 1023 * 1024 / 2 * i) + abort (); +} + +void +corge (void) +{ + int x[10]; + void nest (void) { for (int i = 0; i < 10; i++) x[i] = 0; } + int nest2 (int i) { return x[i]; } + nest (); + #pragma omp parallel for reduction(+:x[2:4]) + for (int i = 0; i < 1024; i++) + for (int j = 2; j < 6; j++) + x[j] += j * i; + for (int i = 2; i < 6; i++) + if (nest2 (i) != 1023 * 1024 / 2 * i) + abort (); +} + +int +main () +{ + int a[10] = {}; + foo (a); + bar (); + baz (); + for (int i = 0; i < 10; i++) + a[i] = 0; + qux (a); + quux (); + corge (); + return 0; +} -- 2.30.2