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)

Reply via email to