[gcc r17-2935] vect: move check for safe speculative reads for inbound access [PR126369]

Tamar Christina via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 14:22:28 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:504b4763fd5080d078f0a7fe55501b003a079206

commit r17-2935-g504b4763fd5080d078f0a7fe55501b003a079206
Author: Tamar Christina <[email protected]>
Date:   Tue Aug 4 15:21:54 2026 +0100

    vect: move check for safe speculative reads for inbound access [PR126369]
    
    It turns out that the DR_SCALAR_KNOWN_BOUNDS check which checks to see that even
    if misaligned but all scalar accesses are in bounds of a known fixed size array
    then we're OK and just need to force masking.
    
    The loop it was placed in would exit early after the first misaligned access and
    so when you have more than one data access in the loop it wouldn't mark the
    other accesses as safe to speculate.
    
    This moves it to its own loop.
    
    gcc/ChangeLog:
    
            PR tree-optimization/126369
            * tree-vect-data-refs.cc (vect_enhance_data_refs_alignment): Move
            DR_SCALAR_KNOWN_BOUNDS safe speculation check.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/126369
            * gcc.target/aarch64/sve/peeled4.c: New test.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/sve/peeled4.c | 27 ++++++++++++++++++++
 gcc/tree-vect-data-refs.cc                     | 35 ++++++++++++++++++--------
 2 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peeled4.c b/gcc/testsuite/gcc.target/aarch64/sve/peeled4.c
new file mode 100644
index 000000000000..694de87a0d88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/peeled4.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mautovec-preference=sve-only -msve-vector-bits=scalable -fdump-tree-vect-details" } */
+
+char a[132];
+char b[128];
+
+unsigned __attribute__ ((noipa))
+f (char x)
+{
+  unsigned ret = 0;
+  for (int i = 1; i < 126; i += 2)
+    {
+      if (a[i - 1] > x || a[i + 2] > x)
+	return 1;
+
+      if (a[i + 4] > x)
+	return 1;
+
+      b[i] = x;
+      b[i + 1] = x + 1;
+    }
+  return ret;
+}
+
+/* { dg-final { scan-tree-dump "vector alignment may not be reachable" "vect" } } */
+/* { dg-final { scan-tree-dump-not "early break not supported: cannot peel for alignment" "vect" } } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 16808ab53be1..92aecc656e13 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -2455,6 +2455,30 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
 	}
     }
 
+  /* See if we can relax the flags on speculative reads for early break.  Do
+     this outside of the other loops below because they can exit early leading
+     to the flag not being cleared for known in bounds cases.  */
+  poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+  if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo))
+    for (auto dr : datarefs)
+      {
+	dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr);
+	if (!vect_relevant_for_alignment_p (dr_info))
+	  continue;
+
+	stmt_vec_info stmt_info = dr_info->stmt;
+
+	/* With variable VF, unsafe speculative read can be avoided for known
+	   inbounds DRs as long as partial vectors are used.  */
+	if (!vf.is_constant ()
+	    && dr_safe_speculative_read_required (stmt_info)
+	    && DR_SCALAR_KNOWN_BOUNDS (dr_info))
+	  {
+	    dr_set_safe_speculative_read_required (stmt_info, false);
+	    LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true;
+	  }
+      }
+
   /* While cost model enhancements are expected in the future, the high level
      view of the code at this time is as follows:
 
@@ -2495,7 +2519,6 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
      - The cost of peeling (the extra runtime checks, the increase
        in code size).  */
 
-  poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   FOR_EACH_VEC_ELT (datarefs, i, dr)
     {
       dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr);
@@ -2505,16 +2528,6 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
       stmt_vec_info stmt_info = dr_info->stmt;
       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
 
-      /* With variable VF, unsafe speculative read can be avoided for known
-	 inbounds DRs as long as partial vectors are used.  */
-      if (!vf.is_constant ()
-	  && dr_safe_speculative_read_required (stmt_info)
-	  && DR_SCALAR_KNOWN_BOUNDS (dr_info))
-	{
-	  dr_set_safe_speculative_read_required (stmt_info, false);
-	  LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true;
-	}
-
       do_peeling = vector_alignment_reachable_p (dr_info, vf);
       if (do_peeling)
         {