The follow adjusts pointer offsets in depend(sink) variables by the
underlying size of the object.
How does this look?
Aldy
commit e0ff9e02210c2796e4eafa905a08897e2d00999f
Author: Aldy Hernandez <al...@redhat.com>
Date: Tue Jul 21 08:02:39 2015 -0700
* tree-pretty-print.c (dump_omp_clause): Pass TYPE_SIGN to
wi::neg_p.
c/
* c-typeck.c (c_finish_omp_clauses): Adjust pointer offsets for
OMP_CLAUSE_DEPEND_SINK.
cp/
* semantics.c (cp_finish_omp_clause_depend_sink): New.
(finish_omp_clauses): Call cp_finish_omp_clause_depend_sink.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index b7714e3..597973b 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -12492,6 +12492,24 @@ c_finish_omp_clauses (tree clauses, bool declare_simd)
if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
{
gcc_assert (TREE_CODE (t) == TREE_LIST);
+ for (; t; t = TREE_CHAIN (t))
+ {
+ tree decl = TREE_VALUE (t);
+ if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
+ {
+ tree offset = TREE_PURPOSE (t);
+ bool neg = wi::neg_p ((wide_int) offset);
+ offset = fold_unary (ABS_EXPR, TREE_TYPE (offset),
offset);
+ tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (c),
+ neg ? MINUS_EXPR : PLUS_EXPR,
+ decl, offset);
+ t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
+ sizetype, t2, decl);
+ if (t2 == error_mark_node)
+ t2 = size_one_node; // ??
+ TREE_PURPOSE (t) = t2;
+ }
+ }
break;
}
if (TREE_CODE (t) == TREE_LIST)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8c05936..2598433 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5532,6 +5532,41 @@ finish_omp_declare_simd_methods (tree t)
}
}
+/* Adjust sink depend clause to take into account pointer offsets. */
+
+static void
+cp_finish_omp_clause_depend_sink (tree sink_clause)
+{
+ tree t = OMP_CLAUSE_DECL (sink_clause);
+ gcc_assert (TREE_CODE (t) == TREE_LIST);
+
+ /* Make sure we don't adjust things twice for templates. */
+ if (processing_template_decl)
+ return;
+
+ for (; t; t = TREE_CHAIN (t))
+ {
+ tree decl = TREE_VALUE (t);
+ if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
+ {
+ tree offset = TREE_PURPOSE (t);
+ bool neg = wi::neg_p ((wide_int) offset);
+ offset = fold_unary (ABS_EXPR, TREE_TYPE (offset), offset);
+ decl = mark_rvalue_use (decl);
+ decl = convert_from_reference (decl);
+ tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (sink_clause),
+ neg ? MINUS_EXPR : PLUS_EXPR,
+ decl, offset);
+ t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause),
+ MINUS_EXPR, sizetype, t2,
+ decl);
+ if (t2 == error_mark_node)
+ t2 = size_one_node; // ??
+ TREE_PURPOSE (t) = t2;
+ }
+ }
+}
+
/* For all elements of CLAUSES, validate them vs OpenMP constraints.
Remove any elements from the list that are invalid. */
@@ -6150,7 +6185,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool
declare_simd)
}
if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
{
- gcc_assert (TREE_CODE (t) == TREE_LIST);
+ cp_finish_omp_clause_depend_sink (c);
break;
}
if (TREE_CODE (t) == TREE_LIST)
diff --git a/gcc/testsuite/c-c++-common/gomp/sink-4.c
b/gcc/testsuite/c-c++-common/gomp/sink-4.c
new file mode 100644
index 0000000..2872404
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/sink-4.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple" } */
+
+/* Test that we adjust pointer offsets for sink variables
+ correctly. */
+
+typedef struct {
+ char stuff[400];
+} foo;
+
+foo *p, *q;
+
+void
+funk ()
+{
+ int i,j;
+#pragma omp parallel for ordered(1)
+ for (p=q; p < q; p--)
+ {
+#pragma omp ordered depend(sink:p+1)
+ void bar ();
+ bar();
+#pragma omp ordered depend(source)
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "depend\\(sink:p\\+400\\)" 1 "gimple" } }
*/
diff --git a/gcc/testsuite/g++.dg/gomp/sink-3.C
b/gcc/testsuite/g++.dg/gomp/sink-3.C
new file mode 100644
index 0000000..83a742e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/sink-3.C
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple" } */
+
+/* Test that we adjust pointer offsets for sink variables
+ correctly. */
+
+typedef struct {
+ char stuff[400];
+} foo;
+
+foo *p, *q, *r;
+
+template<int N>
+void
+funk ()
+{
+ int i,j;
+#pragma omp parallel for ordered(1)
+ for (p=q; p < q; p--)
+ {
+#pragma omp ordered depend(sink:p+1)
+ void bar ();
+ bar();
+#pragma omp ordered depend(source)
+ }
+}
+
+void foobar()
+{
+ funk<3>();
+}
+
+/* { dg-final { scan-tree-dump-times "depend\\(sink:p\\+400\\)" 1 "gimple" } }
*/
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index d3cc245..aab2bfc 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -567,7 +567,8 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc,
int flags)
dump_generic_node (pp, TREE_VALUE (t), spc, flags, false);
if (TREE_PURPOSE (t) != integer_zero_node)
{
- if (!wi::neg_p (TREE_PURPOSE (t)))
+ tree p = TREE_PURPOSE (t);
+ if (!wi::neg_p (p, TYPE_SIGN (TREE_TYPE (p))))
pp_plus (pp);
dump_generic_node (pp, TREE_PURPOSE (t), spc, flags,
false);