aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-01-16 13:09:27 +0100
committerRichard Biener <rguenther@suse.de>2024-01-17 09:22:32 +0100
commit3359942417b02de88ae84d50aac232ac01ff9e15 (patch)
tree8afe57e0cf97b5b9dafee62a4341779b908cdb9a /gcc
parent0c42d1782e48d8ad578ace2065cce9b3615f97c0 (diff)
downloadgcc-3359942417b02de88ae84d50aac232ac01ff9e15.zip
gcc-3359942417b02de88ae84d50aac232ac01ff9e15.tar.gz
gcc-3359942417b02de88ae84d50aac232ac01ff9e15.tar.bz2
tree-optimization/113371 - avoid prologue peeling for peeled early exits
The following avoids prologue peeling when doing early exit vectorization with the IV exit before the early exit. That's because we it invalidates the invariant that the effective latch of the loop is empty causing wrong continuation to the main loop. In particular this is prone to break virtual SSA form. PR tree-optimization/113371 * tree-vect-data-refs.cc (vect_enhance_data_refs_alignment): Do not peel when LOOP_VINFO_EARLY_BREAKS_VECT_PEELED. * tree-vect-loop-manip.cc (vect_do_peeling): Assert we do not perform prologue peeling when LOOP_VINFO_EARLY_BREAKS_VECT_PEELED. * gcc.dg/vect/pr113371.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr113371.c19
-rw-r--r--gcc/tree-vect-data-refs.cc5
-rw-r--r--gcc/tree-vect-loop-manip.cc3
3 files changed, 24 insertions, 3 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/pr113371.c b/gcc/testsuite/gcc.dg/vect/pr113371.c
new file mode 100644
index 0000000..46c4deb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr113371.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O" } */
+/* { dg-additional-options "-march=silvermont" { target { x86_64-*-* i?86-*-* } } } */
+
+long *BN_uadd_ap;
+
+void
+BN_uadd (int dif, long t1)
+{
+ long *rp;
+ while (dif)
+ {
+ dif--;
+ t1 = *BN_uadd_ap;
+ *rp++ = t1;
+ if (t1)
+ break;
+ }
+}
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 5e86da3..0495842 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -2354,8 +2354,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
/* Check if we can possibly peel the loop. */
if (!vect_can_advance_ivs_p (loop_vinfo)
|| !slpeel_can_duplicate_loop_p (loop, LOOP_VINFO_IV_EXIT (loop_vinfo),
- LOOP_VINFO_IV_EXIT (loop_vinfo))
- || loop->inner)
+ loop_preheader_edge (loop))
+ || loop->inner
+ || LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo))
do_peeling = false;
struct _vect_peel_extended_info peel_for_known_alignment;
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index c7e73f6..8aa9224 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -3262,7 +3262,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
{
e = loop_preheader_edge (loop);
edge exit_e = LOOP_VINFO_IV_EXIT (loop_vinfo);
- gcc_checking_assert (slpeel_can_duplicate_loop_p (loop, exit_e, e));
+ gcc_checking_assert (slpeel_can_duplicate_loop_p (loop, exit_e, e)
+ && !LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo));
/* Peel prolog and put it on preheader edge of loop. */
edge scalar_e = LOOP_VINFO_SCALAR_IV_EXIT (loop_vinfo);