From 6a2892a6d3aef8a1ce26386d626f26e6100099f6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 19 Jun 2019 10:32:09 +0200 Subject: [PATCH] omp-low.c (lower_rec_input_clauses): Handle references properly in inscan clauses. * omp-low.c (lower_rec_input_clauses): Handle references properly in inscan clauses. (lower_omp_scan): Likewise. cp/ * cp-gimplify.c (cp_genericize_r): Handle OMP_CLAUSE_{IN,EX}CLUSIVE like OMP_CLAUSE_SHARED. testsuite/ * g++.dg/vect/simd-3.cc: New test. * g++.dg/vect/simd-4.cc: New test. * g++.dg/vect/simd-5.cc: New test. From-SVN: r272471 --- gcc/ChangeLog | 6 ++ gcc/cp/ChangeLog | 5 + gcc/cp/cp-gimplify.c | 2 + gcc/omp-low.c | 78 +++++++++----- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/vect/simd-3.cc | 120 ++++++++++++++++++++++ gcc/testsuite/g++.dg/vect/simd-4.cc | 122 ++++++++++++++++++++++ gcc/testsuite/g++.dg/vect/simd-5.cc | 153 ++++++++++++++++++++++++++++ 8 files changed, 468 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/simd-3.cc create mode 100644 gcc/testsuite/g++.dg/vect/simd-4.cc create mode 100644 gcc/testsuite/g++.dg/vect/simd-5.cc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 217b0097062..7d337bcab3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-06-19 Jakub Jelinek + + * omp-low.c (lower_rec_input_clauses): Handle references properly + in inscan clauses. + (lower_omp_scan): Likewise. + 2019-06-19 Kugan Vivekanandarajah * tree-ssa-address.c (preferred_mem_scale_factor): Handle when diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7bd47cf4b56..f5dab5493ad 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-06-19 Jakub Jelinek + + * cp-gimplify.c (cp_genericize_r): Handle OMP_CLAUSE_{IN,EX}CLUSIVE + like OMP_CLAUSE_SHARED. + 2019-06-18 Jason Merrill * constexpr.c (cxx_eval_store_expression): Delay target evaluation. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 7b9607dde17..bce01f5098e 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1238,6 +1238,8 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_COPYIN: case OMP_CLAUSE_COPYPRIVATE: + case OMP_CLAUSE_INCLUSIVE: + case OMP_CLAUSE_EXCLUSIVE: /* Don't dereference an invisiref in OpenMP clauses. */ if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) *walk_subtrees = 0; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index b0f1d94abf7..ba85b1914c0 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -5238,10 +5238,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)) { tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c); - x = DECL_VALUE_EXPR (new_var); - SET_DECL_VALUE_EXPR (new_var, nv); + x = DECL_VALUE_EXPR (new_vard); + tree vexpr = nv; + if (new_vard != new_var) + vexpr = build_fold_addr_expr (nv); + SET_DECL_VALUE_EXPR (new_vard, vexpr); lower_omp (&tseq, ctx); - SET_DECL_VALUE_EXPR (new_var, x); + SET_DECL_VALUE_EXPR (new_vard, x); gimple_seq_add_seq (ilist, tseq); OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL; } @@ -5367,20 +5370,23 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, { if (x) { - tree nv = create_tmp_var_raw (TREE_TYPE (new_vard)); + tree nv = create_tmp_var_raw (TREE_TYPE (new_var)); gimple_add_tmp_var (nv); - ctx->cb.decl_map->put (new_var, nv); + ctx->cb.decl_map->put (new_vard, nv); x = lang_hooks.decls.omp_clause_default_ctor (c, nv, build_outer_var_ref (var, ctx)); gimplify_and_add (x, ilist); if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)) { tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c); - SET_DECL_VALUE_EXPR (new_var, nv); - DECL_HAS_VALUE_EXPR_P (new_var) = 1; + tree vexpr = nv; + if (new_vard != new_var) + vexpr = build_fold_addr_expr (nv); + SET_DECL_VALUE_EXPR (new_vard, vexpr); + DECL_HAS_VALUE_EXPR_P (new_vard) = 1; lower_omp (&tseq, ctx); - SET_DECL_VALUE_EXPR (new_var, NULL_TREE); - DECL_HAS_VALUE_EXPR_P (new_var) = 0; + SET_DECL_VALUE_EXPR (new_vard, NULL_TREE); + DECL_HAS_VALUE_EXPR_P (new_vard) = 0; gimple_seq_add_seq (ilist, tseq); } OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL; @@ -5524,10 +5530,12 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, gimplify_assign (ref, x, &llist[1]); } - else if (rvarp == NULL) + else { if (omp_is_reference (var) && is_simd) handle_simd_reference (clause_loc, new_vard, ilist); + if (rvarp) + break; gimplify_assign (new_var, x, ilist); if (is_simd) { @@ -8587,14 +8595,26 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION && OMP_CLAUSE_REDUCTION_INSCAN (c)) { + location_t clause_loc = OMP_CLAUSE_LOCATION (c); tree var = OMP_CLAUSE_DECL (c); tree new_var = lookup_decl (var, octx); tree val = new_var; tree var2 = NULL_TREE; tree var3 = NULL_TREE; - if (DECL_HAS_VALUE_EXPR_P (new_var)) + tree new_vard = new_var; + if (omp_is_reference (var)) + { + new_var = build_simple_mem_ref_loc (clause_loc, new_var); + val = new_var; + } + if (DECL_HAS_VALUE_EXPR_P (new_vard)) { - val = DECL_VALUE_EXPR (new_var); + val = DECL_VALUE_EXPR (new_vard); + if (omp_is_reference (var)) + { + gcc_assert (TREE_CODE (val) == ADDR_EXPR); + val = TREE_OPERAND (val, 0); + } if (TREE_CODE (val) == ARRAY_REF && VAR_P (TREE_OPERAND (val, 0))) { @@ -8618,14 +8638,15 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx) var2 = val; } } + gcc_assert (var2); } else { var2 = build_outer_var_ref (var, octx); if (input_phase && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) { - var3 = maybe_lookup_decl (new_var, octx); - if (var3 == new_var) + var3 = maybe_lookup_decl (new_vard, octx); + if (var3 == new_vard) var3 = NULL_TREE; } } @@ -8646,18 +8667,22 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx) { /* Otherwise, assign to it the identity element. */ gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c); - tree x = (DECL_HAS_VALUE_EXPR_P (new_var) - ? DECL_VALUE_EXPR (new_var) : NULL_TREE); tree ref = build_outer_var_ref (var, octx); - SET_DECL_VALUE_EXPR (new_var, val); + tree x = (DECL_HAS_VALUE_EXPR_P (new_vard) + ? DECL_VALUE_EXPR (new_vard) : NULL_TREE); + if (x) + { + if (omp_is_reference (var)) + val = build_fold_addr_expr_loc (clause_loc, val); + SET_DECL_VALUE_EXPR (new_vard, val); + } SET_DECL_VALUE_EXPR (placeholder, ref); DECL_HAS_VALUE_EXPR_P (placeholder) = 1; lower_omp (&tseq, octx); - SET_DECL_VALUE_EXPR (new_var, x); + if (x) + SET_DECL_VALUE_EXPR (new_vard, x); SET_DECL_VALUE_EXPR (placeholder, NULL_TREE); DECL_HAS_VALUE_EXPR_P (placeholder) = 0; - if (x == NULL_TREE) - DECL_HAS_VALUE_EXPR_P (new_var) = 0; gimple_seq_add_seq (&before, tseq); OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL; } @@ -8665,15 +8690,20 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx) else { gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c); - tree x = (DECL_HAS_VALUE_EXPR_P (new_var) - ? DECL_VALUE_EXPR (new_var) : NULL_TREE); - SET_DECL_VALUE_EXPR (new_var, val); + tree x = (DECL_HAS_VALUE_EXPR_P (new_vard) + ? DECL_VALUE_EXPR (new_vard) : NULL_TREE); + tree vexpr = val; + if (x && omp_is_reference (var)) + vexpr = build_fold_addr_expr_loc (clause_loc, val); + if (x) + SET_DECL_VALUE_EXPR (new_vard, vexpr); SET_DECL_VALUE_EXPR (placeholder, var2); DECL_HAS_VALUE_EXPR_P (placeholder) = 1; lower_omp (&tseq, octx); gimple_seq_add_seq (&before, tseq); OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL; - SET_DECL_VALUE_EXPR (new_var, x); + if (x) + SET_DECL_VALUE_EXPR (new_vard, x); SET_DECL_VALUE_EXPR (placeholder, NULL_TREE); DECL_HAS_VALUE_EXPR_P (placeholder) = 0; x = lang_hooks.decls.omp_clause_assign_op (c, val, var2); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 72f34d8e616..ad8c1ac4fb8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-06-19 Jakub Jelinek + + * g++.dg/vect/simd-3.cc: New test. + * g++.dg/vect/simd-4.cc: New test. + * g++.dg/vect/simd-5.cc: New test. + 2019-06-19 Jakub Jelinek * g++.dg/ubsan/pr63956.C: Adjust expected diagnostics. diff --git a/gcc/testsuite/g++.dg/vect/simd-3.cc b/gcc/testsuite/g++.dg/vect/simd-3.cc new file mode 100644 index 00000000000..d9981719f58 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/simd-3.cc @@ -0,0 +1,120 @@ +// { dg-require-effective-target size32plus } +// { dg-additional-options "-fopenmp-simd" } +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } } */ + +#include "../../gcc.dg/vect/tree-vect.h" + +int r, a[1024], b[1024], q; + +__attribute__((noipa)) void +foo (int *a, int *b, int &r) +{ + #pragma omp simd reduction (inscan, +:r) + for (int i = 0; i < 1024; i++) + { + r += a[i]; + #pragma omp scan inclusive(r) + b[i] = r; + } +} + +__attribute__((noipa)) int +bar (void) +{ + int &s = q; + q = 0; + #pragma omp simd reduction (inscan, +:s) + for (int i = 0; i < 1024; i++) + { + s += 2 * a[i]; + #pragma omp scan inclusive(s) + b[i] = s; + } + return s; +} + +__attribute__((noipa)) void +baz (int *a, int *b, int &r) +{ + #pragma omp simd reduction (inscan, +:r) if (simd: 0) + for (int i = 0; i < 1024; i++) + { + r += a[i]; + #pragma omp scan inclusive(r) + b[i] = r; + } +} + +__attribute__((noipa)) int +qux (void) +{ + int &s = q; + q = 0; + #pragma omp simd reduction (inscan, +:s) simdlen (1) + for (int i = 0; i < 1024; i++) + { + s += 2 * a[i]; + #pragma omp scan inclusive(s) + b[i] = s; + } + return s; +} + +int +main () +{ + int s = 0; + check_vect (); + for (int i = 0; i < 1024; ++i) + { + a[i] = i; + b[i] = -1; + asm ("" : "+g" (i)); + } + foo (a, b, r); + if (r != 1024 * 1023 / 2) + abort (); + for (int i = 0; i < 1024; ++i) + { + s += i; + if (b[i] != s) + abort (); + else + b[i] = 25; + } + if (bar () != 1024 * 1023) + abort (); + s = 0; + for (int i = 0; i < 1024; ++i) + { + s += 2 * i; + if (b[i] != s) + abort (); + else + b[i] = -1; + } + r = 0; + baz (a, b, r); + if (r != 1024 * 1023 / 2) + abort (); + s = 0; + for (int i = 0; i < 1024; ++i) + { + s += i; + if (b[i] != s) + abort (); + else + b[i] = -25; + } + if (qux () != 1024 * 1023) + abort (); + s = 0; + for (int i = 0; i < 1024; ++i) + { + s += 2 * i; + if (b[i] != s) + abort (); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/vect/simd-4.cc b/gcc/testsuite/g++.dg/vect/simd-4.cc new file mode 100644 index 00000000000..8f3198943a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/simd-4.cc @@ -0,0 +1,122 @@ +// { dg-require-effective-target size32plus } +// { dg-additional-options "-fopenmp-simd" } +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } } + +#include "../../gcc.dg/vect/tree-vect.h" + +int r, a[1024], b[1024], q; + +#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0) + +__attribute__((noipa)) void +foo (int *a, int *b, int &r) +{ + #pragma omp simd reduction (inscan, foo:r) + for (int i = 0; i < 1024; i++) + { + r += a[i]; + #pragma omp scan inclusive(r) + b[i] = r; + } +} + +__attribute__((noipa)) int +bar (void) +{ + int &s = q; + q = 0; + #pragma omp simd reduction (inscan, foo:s) + for (int i = 0; i < 1024; i++) + { + s += 2 * a[i]; + #pragma omp scan inclusive(s) + b[i] = s; + } + return s; +} + +__attribute__((noipa)) void +baz (int *a, int *b, int &r) +{ + #pragma omp simd reduction (inscan, foo:r) if (simd: 0) + for (int i = 0; i < 1024; i++) + { + r += a[i]; + #pragma omp scan inclusive(r) + b[i] = r; + } +} + +__attribute__((noipa)) int +qux (void) +{ + int &s = q; + q = 0; + #pragma omp simd reduction (inscan, foo:s) simdlen (1) + for (int i = 0; i < 1024; i++) + { + s += 2 * a[i]; + #pragma omp scan inclusive(s) + b[i] = s; + } + return s; +} + +int +main () +{ + int s = 0; + check_vect (); + for (int i = 0; i < 1024; ++i) + { + a[i] = i; + b[i] = -1; + asm ("" : "+g" (i)); + } + foo (a, b, r); + if (r != 1024 * 1023 / 2) + abort (); + for (int i = 0; i < 1024; ++i) + { + s += i; + if (b[i] != s) + abort (); + else + b[i] = 25; + } + if (bar () != 1024 * 1023) + abort (); + s = 0; + for (int i = 0; i < 1024; ++i) + { + s += 2 * i; + if (b[i] != s) + abort (); + else + b[i] = -1; + } + r = 0; + baz (a, b, r); + if (r != 1024 * 1023 / 2) + abort (); + s = 0; + for (int i = 0; i < 1024; ++i) + { + s += i; + if (b[i] != s) + abort (); + else + b[i] = -25; + } + if (qux () != 1024 * 1023) + abort (); + s = 0; + for (int i = 0; i < 1024; ++i) + { + s += 2 * i; + if (b[i] != s) + abort (); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/vect/simd-5.cc b/gcc/testsuite/g++.dg/vect/simd-5.cc new file mode 100644 index 00000000000..e9755957559 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/simd-5.cc @@ -0,0 +1,153 @@ +// { dg-require-effective-target size32plus } +// { dg-additional-options "-fopenmp-simd" } +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } } + +#include "../../gcc.dg/vect/tree-vect.h" + +struct S { + inline S (); + inline ~S (); + inline S (const S &); + inline S & operator= (const S &); + int s; +}; + +S::S () : s (0) +{ +} + +S::~S () +{ +} + +S::S (const S &x) +{ + s = x.s; +} + +S & +S::operator= (const S &x) +{ + s = x.s; + return *this; +} + +static inline void +ini (S &x) +{ + x.s = 0; +} + +S r, a[1024], b[1024]; + +#pragma omp declare reduction (+: S: omp_out.s += omp_in.s) +#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv)) + +__attribute__((noipa)) void +foo (S *a, S *b, S &r) +{ + #pragma omp simd reduction (inscan, +:r) + for (int i = 0; i < 1024; i++) + { + r.s += a[i].s; + #pragma omp scan inclusive(r) + b[i] = r; + } +} + +__attribute__((noipa)) S +bar (void) +{ + S s; + #pragma omp simd reduction (inscan, plus:s) + for (int i = 0; i < 1024; i++) + { + s.s += 2 * a[i].s; + #pragma omp scan inclusive(s) + b[i] = s; + } + return s; +} + +__attribute__((noipa)) void +baz (S *a, S *b, S &r) +{ + #pragma omp simd reduction (inscan, +:r) simdlen(1) + for (int i = 0; i < 1024; i++) + { + r.s += a[i].s; + #pragma omp scan inclusive(r) + b[i] = r; + } +} + +__attribute__((noipa)) S +qux (void) +{ + S s; + #pragma omp simd if (0) reduction (inscan, plus:s) + for (int i = 0; i < 1024; i++) + { + s.s += 2 * a[i].s; + #pragma omp scan inclusive(s) + b[i] = s; + } + return s; +} + +int +main () +{ + S s; + check_vect (); + for (int i = 0; i < 1024; ++i) + { + a[i].s = i; + b[i].s = -1; + asm ("" : "+g" (i)); + } + foo (a, b, r); + if (r.s != 1024 * 1023 / 2) + abort (); + for (int i = 0; i < 1024; ++i) + { + s.s += i; + if (b[i].s != s.s) + abort (); + else + b[i].s = 25; + } + if (bar ().s != 1024 * 1023) + abort (); + s.s = 0; + for (int i = 0; i < 1024; ++i) + { + s.s += 2 * i; + if (b[i].s != s.s) + abort (); + } + r.s = 0; + baz (a, b, r); + if (r.s != 1024 * 1023 / 2) + abort (); + s.s = 0; + for (int i = 0; i < 1024; ++i) + { + s.s += i; + if (b[i].s != s.s) + abort (); + else + b[i].s = 25; + } + if (qux ().s != 1024 * 1023) + abort (); + s.s = 0; + for (int i = 0; i < 1024; ++i) + { + s.s += 2 * i; + if (b[i].s != s.s) + abort (); + } + return 0; +} -- 2.30.2