While trying to get the following benchmarks to run:
  https://codesign.llnl.gov/lulesh.php

I came across some cases where the code and the compiler differed in its interpretation of the OpenACC spec. Specifically, this occurs for acc data clauses with arrays, like:

#pragma acc data copyin(a[N][M]) copyout(b[N][M])

Here, gcc expects an entire array to be specified as a[0:N][0:M], while the benchmark uses a[N][M]. The latter is interpreted by gcc as a single array element (low bound N, length 1), and produces an error.

As usual, the "spec" isn't super clear but my reading of it tends to agree with gcc's. However, I suspect compatibility with other compilers is more important than what's in that document. I don't have any to test against unfortunately.

In any case, the following patch changes gcc's behaviour, if we think it should be changed. Not fully tested yet, in particular I have some issues with timeouts while running OpenACC offload tests.


Bernd
c/
	* c-parser.c (c_parser_omp_variable_list): When encountering [N] syntax
	rather than [N:M], interpret it as [0:N].
cp/
	* parser.c (cp_parser_omp_var_list_no_open): When encountering [N]
	syntax rather than [N:M], interpret it as [0:N].
libgomp/
	testsuite/libgomp.oacc-c-c++-common/present-3.c: New test.

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 0aba51c..63c7bd7 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -10722,7 +10722,10 @@ c_parser_omp_variable_list (c_parser *parser,
 		      low_bound = expr.value;
 		    }
 		  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
-		    length = integer_one_node;
+		    {
+		      length = low_bound;
+		      low_bound = integer_zero_node;
+		    }
 		  else
 		    {
 		      /* Look for `:'.  */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ca9f8b9..7d374ff 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -30215,7 +30215,10 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 		    parser->colon_corrects_to_scope_p
 		      = saved_colon_corrects_to_scope_p;
 		  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
-		    length = integer_one_node;
+		    {
+		      length = low_bound;
+		      low_bound = integer_zero_node;
+		    }
 		  else
 		    {
 		      /* Look for `:'.  */

diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/present-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/present-3.c
new file mode 100644
index 0000000..c46ecf5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/present-3.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
+
+#include <openacc.h>
+#include <stdlib.h>
+
+#define N 8
+#define M 8
+
+int
+main (int argc, char **argv)
+{
+  float a[N][M], b[N][M];
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      a[i][0] = 4.0;
+      b[i][0] = 0.0;
+    }
+
+#pragma acc data copyin(a[N][M]) copyout(b[N][M])
+  {
+
+#pragma acc parallel present(a[N][M])
+    {
+      int ii;
+
+      for (ii = 0; ii < N; ii++)
+	{
+	  b[ii][0] = a[ii][0];
+	}
+    }
+
+  }
+
+  for (i = 0; i < N; i++)
+    {
+      if (a[i][0] != 4.0)
+	abort ();
+
+      if (b[i][0] != 4.0)
+	abort ();
+    }
+
+  return 0;
+}

Reply via email to