[patch][vect]: move check for safe speculative reads for inbound access [PR126369]
Tamar Christina <[email protected]> Tue, 4 Aug 2026 13:31:49 +0100
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
--yiCAdSuqheFxsQbq
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
As requested this extracts the fix for the DR_SCALAR_KNOWN_BOUNDS out of the
peeling patch.
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.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.
Pushed.
Thanks,
Tamar
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 --git a/gcc/testsuite/gcc.target/aarch64/sve/peeled4.c b/gcc/testsuite/gcc.target/aarch64/sve/peeled4.c
new file mode 100644
index 0000000000000000000000000000000000000000..694de87a0d88f55fa13d710f1ab3b440f7341eee
--- /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 0e0754769ae441a4d5a505636aa0bb6dbc09ad86..0504915ada26a992fe8bdf39b8401d34b1429588 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)
{
--
--yiCAdSuqheFxsQbq
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment; filename="rb20771.patch"
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 0000000000000000000000000000000000000000..694de87a0d88f55fa13d710f1ab3b440f7341eee
--- /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 0e0754769ae441a4d5a505636aa0bb6dbc09ad86..0504915ada26a992fe8bdf39b8401d34b1429588 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)
{
--yiCAdSuqheFxsQbq--