This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, PR68640] Clear restrict in install_var_field


Hi,

this patch fixes PR68640.

Consider this testcase:
...
int
foo (int *__restrict__ ap)
{
  int *bp = ap;
#pragma omp parallel for
  for (unsigned int idx = 0; idx < N; idx++)
    ap[idx] = bp[idx];
}
...

When declaring a field for restrict pointer ap in the data passing struct for the thread function, we declare that field with restrict.

So, we roughly get the equivalent of:
...
foo.omp_fn (int *restrict ap, int *bp)
{
  for (unsigned int idx = 0; idx < N; idx++)
    ap[idx] = bp[idx];
}

int
foo (int *__restrict__ ap)
{
  int *bp = ap;
  GOMP_parallel (foo.omp_fn, ap, bp, ...);
}
...

That is incorrect, since ap is not restrict in thread function foo.omp_fn, given that we also access *ap via bp.

Atm, this doesn't result in wrong code, but it might result in wrong code when we make restrict interpretation more aggressive.

The patch fixes the problem by clearing the restrict qualifier on pointer types in install_var_field.

Build non-bootstrap c compiler and tested gcc/gomp.exp and target-libgomp/c.exp.

OK for stage3 trunk if bootstrap and reg-test succeeds?

Thanks,
- Tom
Clear restrict in install_var_field

2015-12-02  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/68640
	* omp-low.c (install_var_field): Clear the restrict qualifier on the var
	type.

---
 gcc/omp-low.c                       |  6 ++++++
 gcc/testsuite/gcc.dg/gomp/pr68640.c | 16 ++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index d1d1e3c..ac4a94d 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1389,6 +1389,12 @@ install_var_field (tree var, bool by_ref, int mask, omp_context *ctx,
 	      || !is_gimple_omp_oacc (ctx->stmt));
 
   type = TREE_TYPE (var);
+  /* Prevent redeclaring the var in the split-off function with a restrict
+     pointer type.  Note that we only clear type itself, restrict qualifiers in
+     the pointed-to type will be ignored by points-to analysis.  */
+  if (POINTER_TYPE_P (type))
+    type = build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_RESTRICT);
+
   if (mask & 4)
     {
       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
diff --git a/gcc/testsuite/gcc.dg/gomp/pr68640.c b/gcc/testsuite/gcc.dg/gomp/pr68640.c
new file mode 100644
index 0000000..f333db0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr68640.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -fdump-tree-ealias-all" } */
+
+#define N 1024
+
+int
+foo (int *__restrict__ ap)
+{
+  int *bp = ap;
+#pragma omp parallel for
+  for (unsigned int idx = 0; idx < N; idx++)
+    ap[idx] = bp[idx];
+}
+
+/* { dg-final { scan-tree-dump-times "clique 1 base 1" 2 "ealias" } } */
+/* { dg-final { scan-tree-dump-times "(?n)clique .* base .*" 2 "ealias" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]