aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-06-19 10:32:09 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-06-19 10:32:09 +0200
commit6a2892a6d3aef8a1ce26386d626f26e6100099f6 (patch)
tree70d4bfa817c70f27aac537b93810c2900938a8e9 /gcc
parent5460b1030c86c2d328335f141dc2972c7ea9fd1e (diff)
downloadgcc-6a2892a6d3aef8a1ce26386d626f26e6100099f6.zip
gcc-6a2892a6d3aef8a1ce26386d626f26e6100099f6.tar.gz
gcc-6a2892a6d3aef8a1ce26386d626f26e6100099f6.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-gimplify.c2
-rw-r--r--gcc/omp-low.c78
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/vect/simd-3.cc120
-rw-r--r--gcc/testsuite/g++.dg/vect/simd-4.cc122
-rw-r--r--gcc/testsuite/g++.dg/vect/simd-5.cc153
8 files changed, 468 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 217b009..7d337bc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (lower_rec_input_clauses): Handle references properly
+ in inscan clauses.
+ (lower_omp_scan): Likewise.
+
2019-06-19 Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
* tree-ssa-address.c (preferred_mem_scale_factor): Handle when
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7bd47cf..f5dab54 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2019-06-19 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_genericize_r): Handle OMP_CLAUSE_{IN,EX}CLUSIVE
+ like OMP_CLAUSE_SHARED.
+
2019-06-18 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_store_expression): Delay target evaluation.
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 7b9607d..bce01f5 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 b0f1d94..ba85b19 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 72f34d8..ad8c1ac 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2019-06-19 Jakub Jelinek <jakub@redhat.com>
+ * 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 <jakub@redhat.com>
+
* g++.dg/ubsan/pr63956.C: Adjust expected diagnostics.
2019-06-19 Jim MacArthur <jim.macarthur@codethink.co.uk>
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 0000000..d998171
--- /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 0000000..8f31989
--- /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 0000000..e975595
--- /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;
+}