This patch resolves an ICE inside the nvptx BE involving reduction
variables which are initialized by the user. E.g.

  #pragma acc parallel reduction(+:var)
  {
    var = 1;

    #pragma acc loop reduction(+:var)
    ...

Currently, the nvptx BE expects the internal function GOACC_REDUCTION to
have a LHS argument containing the reduction variable to be initialized,
however in this case that would be overly aggressive. So when the user
initializes the reduction variable explicitly to an immediate constant,
the optimizer will propagate that value to the reduction initializer
associated with inner the acc loop directly and remove the LHS for the
outer parallel reduction initializer. This shouldn't be a problem here
because during omp lowering, reduction variables are initialized just
outside of the loop. So even if the loop is a empty, the outer parallel
reduction will still be initialized properly.

The other approach I supposed would be to inhibit constant propagation
on reduction on those GOACC internal functions. But that is probably too
restrictive.

I applied this patch to gomp-4_0-branch. Bernd, I believe that trunk may
have a similar problem. If does, is this OK for trunk? I'll hopefully
start working on trunk again in a week or so.

Cesar

2017-05-12  Cesar Philippidis  <ce...@codesourcery.com>

	gcc/
	* config/nvptx/nvptx.c (nvptx_goacc_reduction_init): Don't update
	LHS if it doesn't exist.

	libgomp/
	* testsuite/libgomp.oacc-c-c++-common/par-reduction-3.c: New test.


diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index f790728..bd1236b 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -4948,7 +4948,11 @@ nvptx_goacc_reduction_init (gcall *call)
 	    init = var;
 	}
 
-      gimplify_assign (lhs, init, &seq);
+      /* The LHS may be NULL if a reduction variable on a parallel
+	 construct is initialized to some constant inside the parallel
+	 region.  */
+      if (lhs)
+	gimplify_assign (lhs, init, &seq);
     }
 
   pop_gimplify_context (NULL);
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-reduction-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-reduction-3.c
new file mode 100644
index 0000000..6510143
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-reduction-3.c
@@ -0,0 +1,31 @@
+/* Check a parallel reduction which is are explicitly initialized by
+   the user.  */
+
+/* { dg-do run } */
+
+#include <assert.h>
+
+int
+main ()
+{
+  int n = 10;
+  float accel = 1.0, host = 1.0;
+  int i;
+
+#pragma acc parallel copyin(n) reduction(*:accel)
+  {
+    accel = 1.0;
+#pragma acc loop gang reduction(*:accel)
+    for( i = 1; i <= n; i++)
+      {
+	accel *= 2.0;
+      }
+  }
+
+  for (i = 1; i <= n; i++)
+    host *= 2.0;
+
+  assert (accel == host);
+
+  return 0;
+}

Reply via email to