On Thu, 27 Aug 2026, Tamar Christina wrote:
> > -----Original Message-----
> > From: Richard Biener <[email protected]>
> > Sent: 27 August 2026 12:03
> > To: [email protected]
> > Cc: Jakub Jelinek <[email protected]>; Tamar Christina
> > <[email protected]>; [email protected]
> > Subject: [PATCH] Remove -ftree-loop-if-convert, tie tree-if-conv.cc to
> > vectorization only
> >
> > The following removes the ability to enable stand-alone loop if-conversion
> > or to disable loop if-conversion even though vectorization runs. This
> > was hardly useful before and testing and coverage of this mode is
> > basically non-existent. Instead phiopt and cselimg are the general
> > if-conversion vehicles.
> >
> > This will allow to more tightly integrate vectorizer loop if-conversion
> > with loop vectorization.
> >
> > I have likely left some dead code removal on the plate and will followup
> > with that if there's consensus on this.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > There's a few more testcases using -ftree-loop-if-convert, I have
> > left those untouched (but no more target specific testcases).
> >
> > Any comments?
> >
> > Thanks,
> > Richard.
> >
> > * common.opt (ftree-loop-if-convert): Mark as ignored.
> > * doc/invoke.texi (ftree-loop-if-convert): Remove.
> > * tree-ssa-phiopt.cc (cond_if_else_store_replacement):
> > Do not check !flag_tree_loop_if_convert.
> > * tree-if-conv.cc (pass_if_conversion::gate): Only
> > run when loop vectorization is enabled on any loop.
> > (pass_if_conversion::execute): Adjust.
> > (tree_if_conversion): Likewise. Simplify as we now
> > always version.
> >
> > * gcc.dg/vect/bb-slp-pattern-2.c: Adjust.
> > * gcc.target/i386/pr45685.c: Likewise.
> > ---
> >
> > -/* { dg-final { scan-assembler-times "cmov" 6 } } */
> > +/* { dg-final { scan-assembler-times "cmov" 6 { xfail *-*-* } } } */
> > diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
> > index 5d8abfb52b5..23b4e4cd63a 100644
> > --- a/gcc/tree-if-conv.cc
> > +++ b/gcc/tree-if-conv.cc
> > @@ -4084,7 +4084,7 @@ tree_if_conversion (class loop *loop, vec<gimple *>
> > *preds)
> > bitmap exit_bbs;
> > edge pe;
> > auto_vec<data_reference_p, 10> refs;
> > - bool loop_versioned;
> > + class loop *vloop, *nloop;
> >
> > again:
> > rloop = NULL;
> > @@ -4094,7 +4094,6 @@ tree_if_conversion (class loop *loop, vec<gimple *>
> > *preds)
> > need_to_predicate = false;
> > need_to_rewrite_undefined = false;
> > any_complicated_phi = false;
> > - loop_versioned = false;
> >
> > /* Apply more aggressive if-conversion when loop or its outer loop were
> > marked with simd pragma. When that's the case, we try to if-convert
> > @@ -4147,8 +4146,7 @@ tree_if_conversion (class loop *loop, vec<gimple *>
> > *preds)
> > }
> > }
> >
> > - if ((flag_tree_loop_vectorize || loop->force_vectorize)
> > - && !loop->dont_vectorize)
> > + if (!loop->dont_vectorize)
> > need_to_lower_bitfields = bitfields_to_lower_p (loop, reads_to_lower,
> > writes_to_lower);
> >
>
> LGTM too FWIW, but is this check not redundant? Since in ::execute
> tree_if_conversion won't be called anymore if loop->dont_vectorize no?
Ah, yes. Also
if ((need_to_predicate || any_complicated_phi)
&& ((!flag_tree_loop_vectorize && !loop->force_vectorize)
|| loop->dont_vectorize))
goto cleanup;
I fixed that and also elided the loop_versioned argument from the
call chain to convert_scalar_cond_reduction. I'll re-test and
post the version I'll push.
Richard.
> Thanks,
> Tamar
>
> > @@ -4158,28 +4156,21 @@ tree_if_conversion (class loop *loop, vec<gimple
> > *> *preds)
> > /* The edge to insert invariant stmts on. */
> > pe = loop_preheader_edge (loop);
> >
> > - /* Since we have no cost model, always version loops unless the user
> > - specified -ftree-loop-if-convert or unless versioning is required.
> > + /* Since we have no cost model, always version loops.
> > Either version this loop, or if the pattern is right for outer-loop
> > vectorization, version the outer loop. In the latter case we will
> > still if-convert the original inner loop. */
> > - if (need_to_lower_bitfields
> > - || need_to_predicate
> > - || any_complicated_phi
> > - || flag_tree_loop_if_convert != 1)
> > - {
> > - class loop *vloop
> > - = (versionable_outer_loop_p (loop_outer (loop))
> > + vloop = (versionable_outer_loop_p (loop_outer (loop))
> > ? loop_outer (loop) : loop);
> > - class loop *nloop = version_loop_for_if_conversion (vloop, preds);
> > - if (nloop == NULL)
> > - goto cleanup;
> > - if (vloop != loop)
> > - {
> > - /* If versionable_outer_loop_p decided to version the
> > - outer loop, version also the inner loop of the non-vectorized
> > - loop copy. So we transform:
> > - loop1
> > + nloop = version_loop_for_if_conversion (vloop, preds);
> > + if (nloop == NULL)
> > + goto cleanup;
> > + if (vloop != loop)
> > + {
> > + /* If versionable_outer_loop_p decided to version the
> > + outer loop, version also the inner loop of the non-vectorized
> > + loop copy. So we transform:
> > + loop1
> > loop2
> > into:
> > if (LOOP_VECTORIZED (1, 3))
> > @@ -4193,18 +4184,15 @@ tree_if_conversion (class loop *loop, vec<gimple
> > *> *preds)
> > loop4 (copy of loop2)
> > else
> > loop5 (copy of loop4) */
> > - gcc_assert (nloop->inner && nloop->inner->next == NULL);
> > - rloop = nloop->inner;
> > - }
> > - else
> > - /* If we versioned loop then make sure to insert invariant
> > - stmts before the .LOOP_VECTORIZED check since the vectorizer
> > - will re-use that for things like runtime alias versioning
> > - whose condition can end up using those invariants. */
> > - pe = single_pred_edge (gimple_bb (preds->last ()));
> > -
> > - loop_versioned = true;
> > + gcc_assert (nloop->inner && nloop->inner->next == NULL);
> > + rloop = nloop->inner;
> > }
> > + else
> > + /* If we versioned loop then make sure to insert invariant
> > + stmts before the .LOOP_VECTORIZED check since the vectorizer
> > + will re-use that for things like runtime alias versioning
> > + whose condition can end up using those invariants. */
> > + pe = single_pred_edge (gimple_bb (preds->last ()));
> >
> > if (need_to_lower_bitfields)
> > {
> > @@ -4236,7 +4224,7 @@ tree_if_conversion (class loop *loop, vec<gimple *>
> > *preds)
> > /* Now all statements are if-convertible. Combine all the basic
> > blocks into one huge basic block doing the if-conversion
> > on-the-fly. */
> > - combine_blocks (loop, loop_versioned);
> > + combine_blocks (loop, true);
> > }
> >
> > std::pair <tree, tree> *name_pair;
> > @@ -4327,9 +4315,7 @@ public:
> > bool
> > pass_if_conversion::gate (function *fun)
> > {
> > - return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
> > - && flag_tree_loop_if_convert != 0)
> > - || flag_tree_loop_if_convert == 1);
> > + return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
> > }
> >
> > unsigned int
> > @@ -4342,9 +4328,8 @@ pass_if_conversion::execute (function *fun)
> >
> > auto_vec<gimple *> preds;
> > for (auto loop : loops_list (cfun, 0))
> > - if (flag_tree_loop_if_convert == 1
> > - || ((flag_tree_loop_vectorize || loop->force_vectorize)
> > - && !loop->dont_vectorize))
> > + if ((flag_tree_loop_vectorize || loop->force_vectorize)
> > + && !loop->dont_vectorize)
> > todo |= tree_if_conversion (loop, &preds);
> >
> > if (todo)
> > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
> > index f8dbd26abc1..fd9aa2bedb4 100644
> > --- a/gcc/tree-ssa-phiopt.cc
> > +++ b/gcc/tree-ssa-phiopt.cc
> > @@ -3947,8 +3947,7 @@ cond_if_else_store_replacement (basic_block
> > then_bb, basic_block else_bb,
> > /* If either vectorization or if-conversion is disabled then do
> > not sink any stores. */
> > if (param_max_stores_to_sink == 0
> > - || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize)
> > - || !flag_tree_loop_if_convert)
> > + || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize))
> > return false;
> >
> > /* Find data references. */
> > --
> > 2.51.0
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)