@@ -3118,8 +3118,16 @@ check_omp_nesting_restrictions (gimple s
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
&& gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
{
+ c = NULL_TREE;
+ if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
+ {
+ c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
+ if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD)
+ return true;
+ }
error_at (gimple_location (stmt),
- "OpenMP constructs may not be nested inside simd region");
+ "OpenMP constructs other than %<#pragma omp ordered simd%>"
+ " may not be nested inside simd region");
return false;
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
@@ -3337,6 +3345,13 @@ check_omp_nesting_restrictions (gimple s
for (c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
c; c = OMP_CLAUSE_CHAIN (c))
{
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
+ {
+ gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
+ || (ctx == NULL
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD));
+ continue;
+ }
enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
if (kind == OMP_CLAUSE_DEPEND_SOURCE
|| kind == OMP_CLAUSE_DEPEND_SINK)
@@ -0,0 +1,83 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+
+void
+foo (int i, char *j)
+{
+ #pragma omp atomic
+ j[i]++;
+ #pragma omp ordered threads
+ {
+ int t;
+ #pragma omp atomic read
+ t = j[i];
+ if (t != 3)
+ abort ();
+ if (i > 1)
+ {
+ #pragma omp atomic read
+ t = j[i - 1];
+ if (t == 2)
+ abort ();
+ }
+ if (i < 127)
+ {
+ #pragma omp atomic read
+ t = j[i + 1];
+ if (t == 4)
+ abort ();
+ }
+ }
+ #pragma omp atomic
+ j[i]++;
+}
+
+int
+main ()
+{
+ int i;
+ char j[128];
+ #pragma omp parallel
+ {
+ #pragma omp for
+ for (i = 0; i < 128; i++)
+ j[i] = 0;
+ #pragma omp for ordered schedule(dynamic, 1)
+ for (i = 0; i < 128; i++)
+ {
+ #pragma omp atomic
+ j[i]++;
+ #pragma omp ordered threads
+ {
+ int t;
+ #pragma omp atomic read
+ t = j[i];
+ if (t != 1)
+ abort ();
+ if (i > 1)
+ {
+ #pragma omp atomic read
+ t = j[i - 1];
+ if (t == 0)
+ abort ();
+ }
+ if (i < 127)
+ {
+ #pragma omp atomic read
+ t = j[i + 1];
+ if (t == 2)
+ abort ();
+ }
+ }
+ #pragma omp atomic
+ j[i]++;
+ }
+ #pragma omp for ordered schedule(static, 1)
+ for (i = 0; i < 128; i++)
+ foo (i, j);
+ }
+ return 0;
+}
@@ -0,0 +1 @@
+#include "../libgomp.c/ordered-4.c"