https://gcc.gnu.org/g:d40c46312f41810b39b4a9ad562cde29d97bee8e
commit d40c46312f41810b39b4a9ad562cde29d97bee8e Author: Julian Brown <jul...@codesourcery.com> Date: Tue Jul 11 20:11:33 2023 +0000 OpenMP: Strided/rectangular 'target update' out-of-bounds array lookup fix This patch fixes a bug with the calculation of array bounds in the metadata for noncontiguous 'target update' directives. We record the array base address, a bias and the array length to pass to libgomp -- but at present, we use the 'whole array size' for the last, which means that at runtime we might look up an array with lower bound "base+bias" and upper bound "base+bias+length", which for non-zero bias will overflow the actual bounds of the array on the host and will (sometimes) return an unrelated block instead of the correct one. The fix is to instead calculate a size for the array that encloses the elements to be transferred, and is guaranteed to be entirely within the array (user errors excepted). 2023-07-11 Julian Brown <jul...@codesourcery.com> gcc/ * omp-low.cc (lower_omp_target): Calculate volume enclosing transferred elements instead of using whole array size for noncontiguous 'target update' operations. Diff: --- gcc/ChangeLog.omp | 6 ++++++ gcc/omp-low.cc | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index 1d8f67992e8..1b2266c5c0e 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,9 @@ +2023-07-12 Julian Brown <jul...@codesourcery.com> + + * omp-low.cc (lower_omp_target): Calculate volume enclosing + transferred elements instead of using whole array size for + noncontiguous 'target update' operations. + 2023-07-03 Julian Brown <jul...@codesourcery.com> * gimplify.cc (gimplify_adjust_omp_clauses): Don't gimplify diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index 69da3660e68..0caf5dea05f 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -13998,11 +13998,13 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) tree bias = size_zero_node; tree volume = size_one_node; + tree enclosure = size_one_node; for (i = dims - 1; i >= 0; i--) { tree dim = (*vdim)[i].value; tree index = (*vindex)[i].value; tree stride = (*vstride)[i].value; + tree len = (*vlen)[i].value; /* For the bias we want, e.g.: @@ -14017,6 +14019,20 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) size_binop (MULT_EXPR, volume, index_stride)); volume = size_binop (MULT_EXPR, volume, dim); + + if (i == 0) + { + tree elems_covered = size_binop (MINUS_EXPR, len, + size_one_node); + elems_covered = size_binop (MULT_EXPR, elems_covered, + stride); + elems_covered = size_binop (PLUS_EXPR, elems_covered, + size_one_node); + enclosure = size_binop (MULT_EXPR, enclosure, + elems_covered); + } + else + enclosure = volume; } /* If we don't have a separate span size, use the element size @@ -14024,10 +14040,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) if (!span) span = fold_convert (sizetype, elsize); - /* The size of the whole array -- to make sure we find any - part of the array via splay-tree lookup that might be - mapped on the target at runtime. */ - OMP_CLAUSE_SIZE (oc) = size_binop (MULT_EXPR, arrsize, span); + /* The size of a volume enclosing the elements to be + transferred. */ + OMP_CLAUSE_SIZE (oc) = size_binop (MULT_EXPR, enclosure, span); /* And the bias of the first element we will update. */ OMP_CLAUSE_SIZE (dn) = size_binop (MULT_EXPR, bias, span);