aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-07-02 11:03:33 +0200
committerJakub Jelinek <jakub@redhat.com>2020-07-02 11:03:33 +0200
commit9d50112acfc01f85fe0fb6d88b329e6122e817b3 (patch)
tree3f58021fee5ef016001d29f0db4c6589e57553e7
parent6153cfd7a342f131d347de1aea87f352f3ccd4e7 (diff)
downloadgcc-9d50112acfc01f85fe0fb6d88b329e6122e817b3.zip
gcc-9d50112acfc01f85fe0fb6d88b329e6122e817b3.tar.gz
gcc-9d50112acfc01f85fe0fb6d88b329e6122e817b3.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.
-rw-r--r--gcc/omp-expand.c48
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-7.c24
2 files changed, 68 insertions, 4 deletions
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index 0f07e51..b1349d8 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -7122,15 +7122,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/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)
+ ;
+}