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.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

        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.
---
 gcc/testsuite/g++.dg/torture/pr127049.C | 74 +++++++++++++++++++++++++
 gcc/tree-vect-data-refs.cc              |  3 +-
 2 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr127049.C

diff --git a/gcc/testsuite/g++.dg/torture/pr127049.C 
b/gcc/testsuite/g++.dg/torture/pr127049.C
new file mode 100644
index 00000000000..247c3fea97f
--- /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 aab8ca21568..827e0965d9c 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -5354,7 +5354,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,
-- 
2.51.0

Reply via email to