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;
+}