]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Diagnose non-rectangular loops with invalid steps
authorJakub Jelinek <jakub@redhat.com>
Thu, 2 Jul 2020 09:03:33 +0000 (11:03 +0200)
committerKwok Cheung Yeung <kcy@codesourcery.com>
Tue, 9 Feb 2021 18:09:02 +0000 (10:09 -0800)
THe OpenMP 5 standard requires that if some loop in OpenMP loop nest refers
to some outer loop's iterator variable, then the subtraction of the multiplication
factors for the outer iterator multiplied by the outer increment modulo the
inner increment is 0.  For loops with non-constants in any of these we can't
diagnose it, it would be a task for something like -fsanitize=openmp,
but if all these are constant, we can diagnose it.

2020-07-02  Jakub Jelinek  <jakub@redhat.com>

* omp-expand.c (expand_omp_for): Diagnose non-rectangular loops with
invalid steps - ((m2 - m1) * incr_outer) % incr must be 0 in valid
OpenMP non-rectangular loops.  Use XALLOCAVEC.

* c-c++-common/gomp/loop-7.c: New test.

(cherry picked from commit 9d50112acfc01f85fe0fb6d88b329e6122e817b3)

gcc/ChangeLog.omp
gcc/omp-expand.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/gomp/loop-7.c [new file with mode: 0644]

index 36a69620ef22ceeefc15970c19f78c31ac41a25f..ebe4a1ea05f286dfb0a44e764f49434380707322 100644 (file)
@@ -1,3 +1,12 @@
+2021-02-09  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       Backport from mainline
+       2020-07-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * omp-expand.c (expand_omp_for): Diagnose non-rectangular loops with
+       invalid steps - ((m2 - m1) * incr_outer) % incr must be 0 in valid
+       OpenMP non-rectangular loops.  Use XALLOCAVEC.
+
 2021-02-09  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
        Backport from mainline
index a35ea082a062e7e69a6c3035133ad174d0193a60..7f7c39b67f0cfe624ccae785bc1d626744a22cc7 100644 (file)
@@ -7174,15 +7174,55 @@ expand_omp_for (struct omp_region *region, gimple *inner_stmt)
   struct omp_for_data fd;
   struct omp_for_data_loop *loops;
 
-  loops
-    = (struct omp_for_data_loop *)
-      alloca (gimple_omp_for_collapse (last_stmt (region->entry))
-             * sizeof (struct omp_for_data_loop));
+  loops = XALLOCAVEC (struct omp_for_data_loop,
+                     gimple_omp_for_collapse (last_stmt (region->entry)));
   omp_extract_for_data (as_a <gomp_for *> (last_stmt (region->entry)),
                        &fd, loops);
   region->sched_kind = fd.sched_kind;
   region->sched_modifiers = fd.sched_modifiers;
   region->has_lastprivate_conditional = fd.lastprivate_conditional != 0;
+  if (fd.non_rect && !gimple_omp_for_combined_into_p (fd.for_stmt))
+    {
+      for (int i = fd.first_nonrect; i <= fd.last_nonrect; i++)
+       if ((loops[i].m1 || loops[i].m2)
+           && (loops[i].m1 == NULL_TREE
+               || TREE_CODE (loops[i].m1) == INTEGER_CST)
+           && (loops[i].m2 == NULL_TREE
+               || TREE_CODE (loops[i].m2) == INTEGER_CST)
+           && TREE_CODE (loops[i].step) == INTEGER_CST
+           && TREE_CODE (loops[i - loops[i].outer].step) == INTEGER_CST)
+         {
+           tree t;
+           tree itype = TREE_TYPE (loops[i].v);
+           if (loops[i].m1 && loops[i].m2)
+             t = fold_build2 (MINUS_EXPR, itype, loops[i].m2, loops[i].m1);
+           else if (loops[i].m1)
+             t = fold_build1 (NEGATE_EXPR, itype, loops[i].m1);
+           else
+             t = loops[i].m2;
+           t = fold_build2 (MULT_EXPR, itype, t,
+                            fold_convert (itype,
+                                          loops[i - loops[i].outer].step));
+           if (TYPE_UNSIGNED (itype) && loops[i].cond_code == GT_EXPR)
+             t = fold_build2 (TRUNC_MOD_EXPR, itype,
+                              fold_build1 (NEGATE_EXPR, itype, t),
+                              fold_build1 (NEGATE_EXPR, itype,
+                                           fold_convert (itype,
+                                                         loops[i].step)));
+           else
+             t = fold_build2 (TRUNC_MOD_EXPR, itype, t,
+                              fold_convert (itype, loops[i].step));
+           if (integer_nonzerop (t))
+             error_at (gimple_location (fd.for_stmt),
+                       "invalid OpenMP non-rectangular loop step; "
+                       "%<(%E - %E) * %E%> is not a multiple of loop %d "
+                       "step %qE",
+                       loops[i].m2 ? loops[i].m2 : integer_zero_node,
+                       loops[i].m1 ? loops[i].m1 : integer_zero_node,
+                       loops[i - loops[i].outer].step, i + 1,
+                       loops[i].step);
+         }
+    }
 
   gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
   BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
index 62c4c6033d776361742ba5b608c6c6103c7cf908..4108b4b6113223a5b71aea25ef6160703326331a 100644 (file)
@@ -1,3 +1,10 @@
+2021-02-09  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       Backport from mainline
+       2020-07-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/loop-7.c: New test.
+
 2021-02-09  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/c-c++-common/gomp/loop-7.c b/gcc/testsuite/c-c++-common/gomp/loop-7.c
new file mode 100644 (file)
index 0000000..4c8f27e
--- /dev/null
@@ -0,0 +1,24 @@
+void
+foo (void)
+{
+  #pragma omp for collapse(2)  /* { dg-error "invalid OpenMP non-rectangular loop step" } */
+  for (int i = 0; i < 6; i++)
+    for (int j = 4 * i; j < 7 * i; j += 2)
+      ;
+  #pragma omp for collapse(2)  /* { dg-error "invalid OpenMP non-rectangular loop step" } */
+  for (int i = 0; i < 32; i += 7)
+    for (int j = 3 * i; j < 7 * i; j += 30)
+      ;
+  #pragma omp for collapse(2)
+  for (int i = 0; i < 6; i++)
+    for (int j = 4 * i; j < 6 * i; j += 2)
+      ;
+  #pragma omp for collapse(2)
+  for (int i = 0; i < 6; i += 2)
+    for (int j = 4 * i; j < 7 * i; j += 2)
+      ;
+  #pragma omp for collapse(2)
+  for (int i = 0; i < 6; i += 5)
+    for (int j = 4 * i; j < 7 * i; j += 15)
+      ;
+}