On Mon, Aug 24, 2026 at 3:26 AM Richard Biener <[email protected]> wrote:
>
> The following makes sure to hoist loop invariants after unswitching
> a loop.  Invariant stmts in a loop can make vectorization less
> effective and now confuse it.  While if-conversion moves invariants
> already, when there's nothing to if-convert this isn't done.  This
> follows what loop interchange and unroll-and-jam already do.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
>
> On x86 this will cause
>
> FAIL: gcc.target/i386/pr125238.c scan-assembler movabsq[\\\\t]+\\\\\$858993459
> 4, %r[a-z0-9]+
> FAIL: gcc.target/i386/pr89523-1a.c scan-assembler addr32 vgather
> FAIL: gcc.target/i386/pr89523-1b.c scan-assembler addr32 vgather
>
> all are testisms, I have not quickly figured how to preserve what those
> intended to test, but the patch will reduce the fallout from the
> recent vectorizer changes, so I'll leave those for followups.
>
>         PR tree-optimization/126997
>         * tree-ssa-loop-unswitch.cc (tree_ssa_unswitch_loops):
>         Perform invariant motion when we unswitched a loop.


You had suggested doing this exact thing in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124615#c3 :).

>
>         * gcc.dg/torture/pr126997.c: New testcase.
> ---
>  gcc/testsuite/gcc.dg/torture/pr126997.c | 10 ++++++++++
>  gcc/tree-ssa-loop-unswitch.cc           |  6 +++++-
>  2 files changed, 15 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr126997.c
>
> diff --git a/gcc/testsuite/gcc.dg/torture/pr126997.c 
> b/gcc/testsuite/gcc.dg/torture/pr126997.c
> new file mode 100644
> index 00000000000..5a2d7ab2d0b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr126997.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +
> +unsigned short
> +f (unsigned int hl, unsigned int scheme, unsigned int n)
> +{
> +  unsigned short tot = 0;
> +  for (unsigned short i = 0; i < n; i++)
> +    tot += hl == 1 ? (scheme != 0) : (i == 0);
> +  return tot;
> +}
> diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
> index 6b3c8c4a291..e1650c1f9ae 100644
> --- a/gcc/tree-ssa-loop-unswitch.cc
> +++ b/gcc/tree-ssa-loop-unswitch.cc
> @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "gimple-range.h"
>  #include "dbgcnt.h"
>  #include "cfganal.h"
> +#include "tree-cfgcleanup.h"
>
>  /* This file implements the loop unswitching, i.e. transformation of loops 
> like
>
> @@ -452,7 +453,10 @@ tree_ssa_unswitch_loops (function *fun)
>      clean_up_after_unswitching (ignored_edge_flag);
>
>    if (changed_unswitch || changed_hoist)
> -    return TODO_cleanup_cfg;
> +    cleanup_tree_cfg ();
> +
> +  if (changed_unswitch)
> +    return loop_invariant_motion_in_fun (cfun, false);
>
>    return 0;
>  }
> --
> 2.51.0

Reply via email to