aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-07-02 11:03:33 +0200
committerKwok Cheung Yeung <kcy@codesourcery.com>2021-02-09 10:09:02 -0800
commit551b4fbc89e84c43a9cd202bc537f428b39aab83 (patch)
tree5ddf5fa780d7aa975d0e9a3709227fb650f3bf42
parentb2eabb179a3e2eab5eda2cc0829ba88756252189 (diff)
downloadgcc-551b4fbc89e84c43a9cd202bc537f428b39aab83.zip
gcc-551b4fbc89e84c43a9cd202bc537f428b39aab83.tar.gz
gcc-551b4fbc89e84c43a9cd202bc537f428b39aab83.tar.bz2
openmp: Diagnose non-rectangular loops with invalid steps
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)
-rw-r--r--gcc/ChangeLog.omp9
-rw-r--r--gcc/omp-expand.c48
-rw-r--r--gcc/testsuite/ChangeLog.omp7
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-7.c24
4 files changed, 84 insertions, 4 deletions
diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 36a6962..ebe4a1e 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,6 +1,15 @@
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
2020-06-27 Jakub Jelinek <jakub@redhat.com>
* omp-general.h (struct omp_for_data_loop): Add non_rect_referenced
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index a35ea08..7f7c39b 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 62c4c60..4108b4b 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,6 +1,13 @@
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
2020-06-16 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/loop-6.c: New test.
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
index 0000000..4c8f27e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/loop-7.c
@@ -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)
+ ;
+}