https://gcc.gnu.org/g:e375d01bcdf0f985f1daac09e9760079d0fb8211
commit r17-1249-ge375d01bcdf0f985f1daac09e9760079d0fb8211 Author: Tamar Christina <[email protected]> Date: Wed Jun 3 09:37:32 2026 +0100 vect: fix prologue peeling dominator updates [PR125509] In the change to enable vectorization without needing a scalar epilogue I disabled the dominators update for prolog peeling with the assumption that since I don't need to go to rewire the exits when we vectorize the main loop we don't end up with the complicated merge block for which the updates were needed. And indeed no test failed. But it turns out we now get a different form so the updates are still needed. The merge block is still a mess so determining manually who is the new dominator of whom is still quite difficult so I couldn't simplify the updates. This re-enabled dominator updates after prolog peeling. gcc/ChangeLog: PR tree-optimization/125509 * tree-vect-loop-manip.cc (vect_do_peeling): Re-enable dominators update for prolog peeling. gcc/testsuite/ChangeLog: PR tree-optimization/125509 * gcc.dg/vect/pr125509.c: New test. Diff: --- gcc/testsuite/gcc.dg/vect/pr125509.c | 32 ++++++++++++++++++++++++++++++++ gcc/tree-vect-loop-manip.cc | 4 +--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/pr125509.c b/gcc/testsuite/gcc.dg/vect/pr125509.c new file mode 100644 index 000000000000..bd985680a2cb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr125509.c @@ -0,0 +1,32 @@ +/* { dg-add-options vect_early_break } */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_early_break } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */ + +struct a { + char *b; + long c; +} e; +long d; +char f; +static bool g(char *h, long j) { + auto i = h + j - 1; + for (; h != i; h++) + if (*h) + return false; + return f; +} +void k(); +static void l(struct a h) { + if (!g(h.b, h.c)) + if (d) + k(); +} +void m() { + if (e.c != 1) + l(e); +} + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ +/* { dg-final { scan-tree-dump "early break does not require epilog" "vect" } } */ diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 5ce961a1bb07..584d243a403b 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -3506,12 +3506,11 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, /* Peel prolog and put it on preheader edge of loop. */ edge scalar_e = LOOP_VINFO_SCALAR_MAIN_EXIT (loop_vinfo); edge prolog_e = NULL; - bool early_break_peel_p = LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG (loop_vinfo); prolog = slpeel_tree_duplicate_loop_to_edge_cfg (loop, exit_e, scalar_loop, scalar_e, e, &prolog_e, true, NULL, uncounted_p, uncounted_p, - early_break_peel_p); + false); gcc_assert (prolog); prolog->force_vectorize = false; @@ -3678,7 +3677,6 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1, /* Handle any remaining dominator updates needed after inserting the loop skip edge above. */ if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo) - && LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG (loop_vinfo) && prolog_peeling) { /* Adding a skip edge to skip a loop with multiple exits
