> -----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?

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

Reply via email to