diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-07-02 11:03:33 +0200 |
---|---|---|
committer | Kwok Cheung Yeung <kcy@codesourcery.com> | 2021-02-09 10:09:02 -0800 |
commit | 551b4fbc89e84c43a9cd202bc537f428b39aab83 (patch) | |
tree | 5ddf5fa780d7aa975d0e9a3709227fb650f3bf42 | |
parent | b2eabb179a3e2eab5eda2cc0829ba88756252189 (diff) | |
download | gcc-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.omp | 9 | ||||
-rw-r--r-- | gcc/omp-expand.c | 48 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog.omp | 7 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/loop-7.c | 24 |
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) + ; +} |