From: Jakub Jelinek Date: Thu, 2 Jul 2020 09:03:33 +0000 (+0200) Subject: openmp: Diagnose non-rectangular loops with invalid steps X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=551b4fbc89e84c43a9cd202bc537f428b39aab83;p=thirdparty%2Fgcc.git 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 * 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) --- diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index 36a69620ef22..ebe4a1ea05f2 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,12 @@ +2021-02-09 Kwok Cheung Yeung + + Backport from mainline + 2020-07-02 Jakub Jelinek + + * 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 Backport from mainline diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index a35ea082a062..7f7c39b67f0c 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 (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 62c4c6033d77..4108b4b61132 100644 --- a/gcc/testsuite/ChangeLog.omp +++ b/gcc/testsuite/ChangeLog.omp @@ -1,3 +1,10 @@ +2021-02-09 Kwok Cheung Yeung + + Backport from mainline + 2020-07-02 Jakub Jelinek + + * c-c++-common/gomp/loop-7.c: New test. + 2021-02-09 Kwok Cheung Yeung 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 index 000000000000..4c8f27e76a54 --- /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) + ; +}