https://gcc.gnu.org/g:df47bc80683a4391e603e50b0d4ad016e6aa71a7
commit r16-9668-gdf47bc80683a4391e603e50b0d4ad016e6aa71a7 Author: Richard Biener <[email protected]> Date: Tue Aug 25 15:46:07 2026 +0200 tree-optimization/127049 - fixup outer loop inner loop DR analysis The following fixes a bogus use of build_fold_indirect_ref to build the reference we analyze for the innermost loop behavior for outer loop vectorization. That yields to references of a somewhat random type and alignment analysis based on that, plus using an INDIRECT_REF will make this DR not analyzable very well. The following changes this to a MEM_REF of the original DR_REF type. PR tree-optimization/127049 * tree-vect-data-refs.cc (vect_analyze_data_refs): Build a MEM_REF of the DR_REF type for analyzing the innermost loop behavior for outer loop vectorization. * g++.dg/torture/pr127049.C: New testcase. (cherry picked from commit 4e37a91129de4dab6ef37a6b432c565def1ba9f4) Diff: --- gcc/testsuite/g++.dg/torture/pr127049.C | 74 +++++++++++++++++++++++++++++++++ gcc/tree-vect-data-refs.cc | 3 +- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/g++.dg/torture/pr127049.C b/gcc/testsuite/g++.dg/torture/pr127049.C new file mode 100644 index 000000000000..247c3fea97fc --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr127049.C @@ -0,0 +1,74 @@ +// { dg-do run } +// { dg-additional-options "-std=c++23" } + +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <span> +#include <vector> +#include <algorithm> + +static constexpr std::size_t D = 3; +static constexpr std::size_t LEAF = 32; +static constexpr float INF = 1e15f; + +struct LeafBucket { + alignas(64) float coords[D][LEAF]; + uint32_t ids[LEAF]; +}; + +struct FatPoint { + float coords[D]; + unsigned payload_id; +}; + +struct Builder { + std::span<FatPoint> temp_pts; + std::span<float> vals; + std::span<std::uint64_t> dims; + std::span<LeafBucket> buckets; + std::size_t B; + + void build(std::size_t start, std::size_t end, std::size_t +node_idx, std::size_t current_buckets) { + const std::size_t size = end - start; + if (size == 0) return; + if (node_idx >= B - 1) { + const std::size_t bucket_idx = node_idx - (B - 1); + for (std::size_t i = 0; i < size; ++i) { + for (std::size_t d = 0; d < D; ++d) + buckets[bucket_idx].coords[d][i] = temp_pts[start + +i].coords[d]; + buckets[bucket_idx].ids[i] = temp_pts[start + +i].payload_id; + } + // Padding-fill loop below is the faulting loop. + for (std::size_t i = size; i < LEAF; ++i) { + for (std::size_t d = 0; d < D; ++d) + buckets[bucket_idx].coords[d][i] = INF; + buckets[bucket_idx].ids[i] = 0xFFFFFFFFu; + } + return; + } + const std::size_t mid = start + current_buckets; + std::nth_element(temp_pts.begin() + start, temp_pts.begin() + +mid, temp_pts.begin() + end, + [](const FatPoint& a, const FatPoint& b){ return +a.coords[0] < b.coords[0]; }); + build(start, mid, 2 * node_idx + 1, 0); + build(mid, end, 2 * node_idx + 2, 0); + } +}; + +int main() { + std::vector<LeafBucket> buckets(1); + std::vector<FatPoint> pts(3); + std::vector<float> vals(0); + std::vector<std::uint64_t> dims(0); + for (std::size_t i = 0; i < 3; ++i) + for (std::size_t d = 0; d < D; ++d) pts[i].coords[d] = (float)i; + Builder b{pts, vals, dims, buckets, 1}; + b.build(0, 3, 0, 1); + return 0; +} diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index ae556d85c7f9..9f74ed5ef0f9 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -5468,7 +5468,8 @@ vect_analyze_data_refs (vec_info *vinfo, bool *fatal) tree init_offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), init, offset); tree init_addr = fold_build_pointer_plus (base, init_offset); - tree init_ref = build_fold_indirect_ref (init_addr); + tree init_ref = build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), + init_addr, build_zero_cst (ptr_type_node)); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location,
