On Fri, Nov 14, 2025 at 7:11 AM Richard Biener <[email protected]> wrote:
>
> The testcases from PR121744 and PR121685 fail to be optimized when
> the method with the access based on 'this' is inlined. The following
> adds an early loop-invariant motion pass to combat this. I have
> added a knob on PHI-motion as I think this is neither wanted early
> nor in the places we call LIM on-demand on a function.
>
> I've mass-edited the testsuite to get rid of UNRESOLVEDs, extra
> fails are the following, sofar not looked at in detail. I'm looking
> for general comments on adding LIM early.
I think it is a good idea until we have better handling of restrict
and this handling.
I only question if we should have it before dse/cd_dce in case we
might be able to remove some empty loops too.
The other thing if we are messing around with passes early on, is
pass_merge_phi is less likely to do anything now (or the stuff it does
now is less like to have an effect on inlining decisions) so does that
make sense to remove it for early if we add LIM early? I am trying to
keep the number of passes the same or less. Or is that for GCC 17
stage 1 when we try to reorg the passes?
Thanks,
Andrew
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu (with the following
> extra FAILs).
>
> +FAIL: c-c++-common/restrict-2.c -std=gnu++17 scan-tree-dump-times lim3
> "Moving statement" 11
> +FAIL: g++.dg/tree-ssa/pr117123.C -std=gnu++17 scan-tree-dump-times
> optimized "if " 3
> +FAIL: gcc.dg/loop-unswitch-1.c scan-tree-dump unswitch "unswitching loop"
> +FAIL: gcc.dg/tree-ssa/loop-25.c scan-tree-dump-times profile_estimate
> "Disambiguating loop" 5
> +XPASS: gcc.dg/tree-ssa/pr111003.c scan-tree-dump-not optimized "foo"
> +FAIL: gcc.dg/tree-ssa/pr83403-2.c scan-tree-dump-times lim3 "Executing store
> motion of" 10
> +FAIL: gcc.dg/tree-ssa/ssa-lim-13.c scan-tree-dump-times lim3 "Moving
> statement" 2
> +FAIL: gcc.dg/tree-ssa/ssa-lim-19.c scan-tree-dump-times lim3 "out of loop 1"
> 3
> +FAIL: gcc.dg/tree-ssa/ssa-lim-19.c scan-tree-dump-times lim3 "out of loop 2"
> 4
> +FAIL: gcc.dg/tree-ssa/ssa-lim-22.c scan-tree-dump-times lim3 "out of loop 1"
> 3
> +FAIL: gcc.dg/tree-ssa/ssa-lim-22.c scan-tree-dump-times lim3 "out of loop 3"
> 4
> +FAIL: gcc.dg/tree-ssa/ssa-lim-3.c scan-tree-dump lim3 "Moving
> statement.*global.x.*out of loop 1"
> +FAIL: gcc.dg/tree-ssa/ssa-lim-7.c scan-tree-dump lim3 "Moving statement"
> +FAIL: gcc.dg/vect/pr69783.c -flto -ffat-lto-objects scan-tree-dump vect
> "improved number of alias checks from [0-9]* to 2"
> +FAIL: gcc.dg/vect/pr69783.c scan-tree-dump vect "improved number of alias
> checks from [0-9]* to 2"
> +FAIL: gcc.dg/vect/slp-9.c -flto -ffat-lto-objects scan-tree-dump-times vect
> "vectorized 1 loops" 1
> +FAIL: gcc.dg/vect/slp-9.c scan-tree-dump-times vect "vectorized 1 loops" 1
> +FAIL: gcc.dg/vect/vect-simd-17.c -flto -ffat-lto-objects scan-tree-dump
> vect "vectorized 1[1-2] loops"
> +FAIL: gcc.dg/vect/vect-simd-17.c scan-tree-dump vect "vectorized 1[1-2]
> loops"
> +FAIL: gfortran.dg/vect/O3-pr49957.f -O scan-tree-dump vect "vectorized 1
> loops"
> +FAIL: gfortran.dg/vect/fast-math-pr37021.f90 -O scan-tree-dump vect
> "vectorized 2 loops"
>
> * passes.def: Add early loop-invariant motion pass.
> * tree-ssa-loop-manip.h (loop_invariant_motion_in_fun): Add flag
> for PHI-motion.
> * tree-ssa-loop-im.cc (pass_lim::set_pass_param): New method.
> (pass_lim::early_p): New member.
> (pass_lim::execute): Do not run store-motion or phi-motion early.
> Exit early when there are no loops.
> (loop_invariant_motion_in_fun): New flag for PHI-motion, pass down.
> (compute_invariantness): Likewise, guard PHI-motion.
> * gimple-loop-iterchange.cc (pass_linterchange::execute): Do
> not perform PHI-motion when doing invariant motion.
> * gimple-loop-jam.cc (tree_loop_unroll_and_jam): Likewise.
>
> * c-c++-common/restrict-2.c: Scan lim3 dump instead of lim2 dump.
> ...
> ---
> gcc/gimple-loop-interchange.cc | 2 +-
> gcc/gimple-loop-jam.cc | 2 +-
> gcc/passes.def | 1 +
> gcc/testsuite/c-c++-common/restrict-2.c | 4 +--
> gcc/testsuite/c-c++-common/restrict-4.c | 4 +--
> gcc/testsuite/g++.dg/opt/pr104515.C | 6 ++--
> gcc/testsuite/g++.dg/opt/pr99728.C | 4 +--
> gcc/testsuite/g++.dg/tree-ssa/pr33615.C | 4 +--
> gcc/testsuite/g++.dg/tree-ssa/restrict1.C | 4 +--
> gcc/testsuite/gcc.dg/pr102385.c | 2 +-
> gcc/testsuite/gcc.dg/tm/pub-safety-1.c | 4 +--
> gcc/testsuite/gcc.dg/tm/reg-promotion.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/loop-32.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/loop-33.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/loop-34.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/loop-35.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/loop-7.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/pr23109.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/pr39612.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-11.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-14.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-18.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-19.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-20.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-21.c | 8 ++---
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-22.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-23.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-24.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-25.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c | 6 ++--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-8.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-9.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c | 4 +--
> gcc/testsuite/gcc.dg/tree-ssa/trapping-1.c | 4 +--
> .../gcc.target/aarch64/sve/trapping-1.c | 2 +-
> gcc/testsuite/gfortran.dg/pr104466.f90 | 6 ++--
> gcc/testsuite/gfortran.dg/pr32921.f | 4 +--
> gcc/tree-ssa-loop-im.cc | 30 ++++++++++++++-----
> gcc/tree-ssa-loop-manip.h | 2 +-
> 54 files changed, 134 insertions(+), 119 deletions(-)
>
> diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
> index 9b6670be575..705c6fffea6 100644
> --- a/gcc/gimple-loop-interchange.cc
> +++ b/gcc/gimple-loop-interchange.cc
> @@ -2109,7 +2109,7 @@ pass_linterchange::execute (function *fun)
> if (changed_p)
> {
> unsigned todo = TODO_update_ssa_only_virtuals;
> - todo |= loop_invariant_motion_in_fun (cfun, false);
> + todo |= loop_invariant_motion_in_fun (cfun, false, false);
> scev_reset ();
> return todo;
> }
> diff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc
> index 5c74f80af4c..790d39a693c 100644
> --- a/gcc/gimple-loop-jam.cc
> +++ b/gcc/gimple-loop-jam.cc
> @@ -641,7 +641,7 @@ tree_loop_unroll_and_jam (void)
> {
> cleanup_tree_cfg ();
> todo &= ~TODO_cleanup_cfg;
> - todo |= loop_invariant_motion_in_fun (cfun, false);
> + todo |= loop_invariant_motion_in_fun (cfun, false, false);
> }
> rewrite_into_loop_closed_ssa (NULL, 0);
> scev_reset ();
> diff --git a/gcc/passes.def b/gcc/passes.def
> index 4807438a9da..9da882413da 100644
> --- a/gcc/passes.def
> +++ b/gcc/passes.def
> @@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see
> NEXT_PASS (pass_dse);
> NEXT_PASS (pass_cd_dce, false /* update_address_taken_p */, true /*
> remove_unused_locals */);
> NEXT_PASS (pass_phiopt, true /* early_p */);
> + NEXT_PASS (pass_lim, true /* early_p */);
> /* Cleanup eh is done before tail recusision to remove empty (only
> clobbers)
> finally blocks which would block tail recursion. */
> NEXT_PASS (pass_cleanup_eh);
> diff --git a/gcc/testsuite/c-c++-common/restrict-2.c
> b/gcc/testsuite/c-c++-common/restrict-2.c
> index ad19fb3f2d5..183a0de347e 100644
> --- a/gcc/testsuite/c-c++-common/restrict-2.c
> +++ b/gcc/testsuite/c-c++-common/restrict-2.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fno-strict-aliasing -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fno-strict-aliasing -fdump-tree-lim3-details" } */
>
> void foo (float * __restrict__ a, float * __restrict__ b, int n, int j)
> {
> @@ -10,4 +10,4 @@ void foo (float * __restrict__ a, float * __restrict__ b,
> int n, int j)
>
> /* We should move the RHS of the store out of the loop. */
>
> -/* { dg-final { scan-tree-dump-times "Moving statement" 11 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving statement" 11 "lim3" } } */
> diff --git a/gcc/testsuite/c-c++-common/restrict-4.c
> b/gcc/testsuite/c-c++-common/restrict-4.c
> index 5806a2a9018..8dd597c5142 100644
> --- a/gcc/testsuite/c-c++-common/restrict-4.c
> +++ b/gcc/testsuite/c-c++-common/restrict-4.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> struct Foo
> {
> @@ -15,4 +15,4 @@ void bar(struct Foo f, int * __restrict__ q)
> }
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion" "lim3" } } */
> diff --git a/gcc/testsuite/g++.dg/opt/pr104515.C
> b/gcc/testsuite/g++.dg/opt/pr104515.C
> index f5455a45aa6..c9f75411094 100644
> --- a/gcc/testsuite/g++.dg/opt/pr104515.C
> +++ b/gcc/testsuite/g++.dg/opt/pr104515.C
> @@ -1,5 +1,5 @@
> // { dg-do compile { target c++11 } }
> -// { dg-options "-O2 -fdump-tree-lim2-details" }
> +// { dg-options "-O2 -fdump-tree-lim3-details" }
>
> using T = int;
> struct Vec {
> @@ -14,5 +14,5 @@ void pop_back_many(Vec& v, unsigned n)
> }
> }
>
> -// { dg-final { scan-tree-dump "Executing store motion of v" "lim2" } }
> -// { dg-final { scan-tree-dump "Re-issueing dependent" "lim2" } }
> +// { dg-final { scan-tree-dump "Executing store motion of v" "lim3" } }
> +// { dg-final { scan-tree-dump "Re-issueing dependent" "lim3" } }
> diff --git a/gcc/testsuite/g++.dg/opt/pr99728.C
> b/gcc/testsuite/g++.dg/opt/pr99728.C
> index d4393231b4c..7ab965253a0 100644
> --- a/gcc/testsuite/g++.dg/opt/pr99728.C
> +++ b/gcc/testsuite/g++.dg/opt/pr99728.C
> @@ -1,6 +1,6 @@
> // PR/99728
> // { dg-do compile }
> -// { dg-options "-O2 -fdump-tree-lim2-details -w -Wno-psabi" }
> +// { dg-options "-O2 -fdump-tree-lim3-details -w -Wno-psabi" }
>
> typedef double __m256d __attribute__((vector_size(sizeof (double) * 4)));
> extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__,
> __artificial__))
> @@ -47,4 +47,4 @@ template void foo<>(s0data_s<Tvsimple> & __restrict__ d,
> unsigned long l, unsigned long il, unsigned long lmax);
>
> // The aggregate copy in the IL should not prevent all store-motion
> -// { dg-final { scan-tree-dump-times "Executing store motion" 4 "lim2" } }
> +// { dg-final { scan-tree-dump-times "Executing store motion" 4 "lim3" } }
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr33615.C
> b/gcc/testsuite/g++.dg/tree-ssa/pr33615.C
> index 13e20e0cd2c..dd2bbb2a068 100644
> --- a/gcc/testsuite/g++.dg/tree-ssa/pr33615.C
> +++ b/gcc/testsuite/g++.dg/tree-ssa/pr33615.C
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fnon-call-exceptions -fdump-tree-lim2-details -w" } */
> +/* { dg-options "-O -fnon-call-exceptions -fdump-tree-lim3-details -w" } */
>
> extern volatile int y;
>
> @@ -16,4 +16,4 @@ foo (double a, int x)
>
> // The expression 1.0 / 0.0 should not be treated as a loop invariant
> // if it may throw an exception.
> -// { dg-final { scan-tree-dump-times "invariant up to" 0 "lim2" } }
> +// { dg-final { scan-tree-dump-times "invariant up to" 0 "lim3" } }
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/restrict1.C
> b/gcc/testsuite/g++.dg/tree-ssa/restrict1.C
> index 3228321e522..718d1ec5c3f 100644
> --- a/gcc/testsuite/g++.dg/tree-ssa/restrict1.C
> +++ b/gcc/testsuite/g++.dg/tree-ssa/restrict1.C
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> struct Foo
> {
> @@ -16,4 +16,4 @@ void bar(Foo f, int * __restrict__ q)
> }
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/pr102385.c b/gcc/testsuite/gcc.dg/pr102385.c
> index f64017ef90c..c210f34c031 100644
> --- a/gcc/testsuite/gcc.dg/pr102385.c
> +++ b/gcc/testsuite/gcc.dg/pr102385.c
> @@ -13,4 +13,4 @@ void e() {
> }
> int main() {return 0;}
> /* { dg-final { scan-tree-dump-not "Invalid sum" "pcom" } } */
> -/* { dg-final { scan-tree-dump-not "Invalid sum" "lim2" } } */
> +/* { dg-final { scan-tree-dump-not "Invalid sum" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tm/pub-safety-1.c
> b/gcc/testsuite/gcc.dg/tm/pub-safety-1.c
> index 59fb43e6edd..3841c08fe29 100644
> --- a/gcc/testsuite/gcc.dg/tm/pub-safety-1.c
> +++ b/gcc/testsuite/gcc.dg/tm/pub-safety-1.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-fgnu-tm -O1 -fdump-tree-lim2" } */
> +/* { dg-options "-fgnu-tm -O1 -fdump-tree-lim3" } */
>
> /* Test that thread visible loads do not get hoisted out of loops if
> the load would not have occurred on each path out of the loop. */
> @@ -20,4 +20,4 @@ void reader()
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Cannot hoist.*DATA_DATA because it is
> in a transaction" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Cannot hoist.*DATA_DATA because it is
> in a transaction" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tm/reg-promotion.c
> b/gcc/testsuite/gcc.dg/tm/reg-promotion.c
> index 47400efd90f..e0e5f62bfb3 100644
> --- a/gcc/testsuite/gcc.dg/tm/reg-promotion.c
> +++ b/gcc/testsuite/gcc.dg/tm/reg-promotion.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-fgnu-tm -O2 -fdump-tree-lim2" } */
> +/* { dg-options "-fgnu-tm -O2 -fdump-tree-lim3" } */
>
> /* Test that `count' is not written to unless p->data>0. */
>
> @@ -20,4 +20,4 @@ void func()
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Cannot hoist conditional load of count
> because it is in a transaction" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Cannot hoist conditional load of count
> because it is in a transaction" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
> index ffeffb4a01e..48fbf0ad493 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O1 -fdump-tree-lim2-details -fallow-store-data-races" } */
> +/* { dg-options "-O1 -fdump-tree-lim3-details -fallow-store-data-races" } */
>
> float a[100];
>
> @@ -17,4 +17,4 @@ void xxx (void)
> /* Store motion may be applied to the assignment to a[k], since sinf
> cannot read nor write the memory. */
>
> -/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c
> b/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c
> index e06a1e4e115..9b69c73a142 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-32.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> int x;
> int a[100];
> @@ -42,4 +42,4 @@ void test3(struct a *A)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 3 "lim2" }
> } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 3 "lim3" }
> } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c
> b/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c
> index 57fd06d38df..98a16fb948a 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-33.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> int x;
> int a[100];
> @@ -36,4 +36,4 @@ void test5(struct a *A, unsigned b)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 4 "lim2" {
> xfail { lp64 || llp64 } } } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 4 "lim3" {
> xfail { lp64 || llp64 } } } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c
> b/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c
> index 4a7b082fe43..26fb281b2a3 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-34.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> int r[6];
>
> @@ -17,4 +17,4 @@ void f (int n)
> }
>
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of r" 6 "lim2"
> } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of r" 6 "lim3"
> } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c
> b/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c
> index ce63f97f657..5f323dc1c32 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> int x;
> int a[100];
> @@ -67,5 +67,5 @@ void test4(struct a *A, unsigned LONG b)
> }
> }
> /* long index not hoisted for avr target PR 36561 */
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 8 "lim2" {
> xfail { avr-*-* msp430-*-* } } } } */
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 6 "lim2" {
> target { avr-*-* msp430-*-* } } } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 8 "lim3" {
> xfail { avr-*-* msp430-*-* } } } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 6 "lim3" {
> target { avr-*-* msp430-*-* } } } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c
> b/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c
> index 08a49352400..e28e4c9b88a 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-7.c
> @@ -1,6 +1,6 @@
> /* PR tree-optimization/19828 */
> /* { dg-do compile } */
> -/* { dg-options "-O1 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O1 -fdump-tree-lim3-details" } */
>
> int cst_fun1 (int) __attribute__((__const__));
> int cst_fun2 (int) __attribute__((__const__));
> @@ -31,4 +31,4 @@ int xxx (void)
> Calls to cst_fun2 and pure_fun2 should not be, since calling
> with k = 0 may be invalid. */
>
> -/* { dg-final { scan-tree-dump-times "Moving statement" 2 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving statement" 2 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c
> index 059f658ea20..a786b017dd4 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -funsafe-math-optimizations -ftrapping-math
> -fdump-tree-recip -fdump-tree-lim2 --param=ranger-recompute-depth=1" } */
> +/* { dg-options "-O2 -funsafe-math-optimizations -ftrapping-math
> -fdump-tree-recip -fdump-tree-lim3 --param=ranger-recompute-depth=1" } */
> /* { dg-warning "'-fassociative-math' disabled" "" { target *-*-* } 0 } */
> /* ranger-recompute-depth prevents the optimizers from being too smart. */
>
> @@ -30,6 +30,6 @@ int main()
> /* LIM only performs the transformation in the no-trapping-math case. In
> the future we will do it for trapping-math as well in recip, check that
> this is not wrongly optimized. */
> -/* { dg-final { scan-tree-dump-not "reciptmp" "lim2" } } */
> +/* { dg-final { scan-tree-dump-not "reciptmp" "lim3" } } */
> /* { dg-final { scan-tree-dump-not "reciptmp" "recip" } } */
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
> index 884f905148f..2f48aaa92c0 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details -Wuninitialized" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details -Wuninitialized" } */
>
> void foo(int *);
> void f2(int dst[3], int R)
> @@ -17,5 +17,5 @@ void f2(int dst[3], int R)
> foo(inter);
> }
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion" 2 "lim2" } } */
> -/* { dg-final { scan-tree-dump-not " = inter\\\[\[0-1\]\\\];" "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion" 2 "lim3" } } */
> +/* { dg-final { scan-tree-dump-not " = inter\\\[\[0-1\]\\\];" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
> index 64f2bbc76fe..d5026f4e4c5 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */
> +/* { dg-options "-O3 -funroll-loops -fdump-tree-lim3-details" } */
> /* { dg-additional-options "--param max-completely-peeled-insns=200" {
> target { s390*-*-* } } } */
> /* { dg-additional-options "--param max-completely-peeled-insns=300" {
> target { arm*-*-* cris-*-* m68k*-*-* } } } */
>
> @@ -7,4 +7,4 @@
>
> #include "pr83403.h"
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 10 "lim2" }
> } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 10 "lim3" }
> } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
> index 3f520720ca2..224f756b3e6 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */
> +/* { dg-options "-O3 -funroll-loops -fdump-tree-lim3-details" } */
> /* { dg-additional-options "--param max-completely-peeled-insns=200" {
> target { s390*-*-* } } } */
> /* { dg-additional-options "--param max-completely-peeled-insns=300" {
> target { arm*-*-* cris-*-* m68k*-*-* } } } */
>
> @@ -7,4 +7,4 @@
>
> #include "pr83403.h"
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 10 "lim2" }
> } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 10 "lim3" }
> } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c
> b/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c
> index 90b9b558622..a35212914e3 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-3.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fno-strict-aliasing -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fno-strict-aliasing -fdump-tree-lim3-details" } */
>
> void f(int * __restrict__ r,
> int a[__restrict__ 16][16],
> @@ -14,4 +14,4 @@ void f(int * __restrict__ r,
>
> /* We should apply store motion to the store to *r. */
>
> -/* { dg-final { scan-tree-dump "Executing store motion of \\\*r" "lim2" } }
> */
> +/* { dg-final { scan-tree-dump "Executing store motion of \\\*r" "lim3" } }
> */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c
> b/gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c
> index fc03c1e9c1c..2e0edabf73c 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fno-strict-aliasing -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fno-strict-aliasing -fdump-tree-lim3-details" } */
>
> static inline __attribute__((always_inline))
> void f(int * __restrict__ r,
> @@ -20,4 +20,4 @@ void g(int *r, int a[16][16], int b[16][16], int i, int j)
>
> /* We should apply store motion to the store to *r. */
>
> -/* { dg-final { scan-tree-dump "Executing store motion of \\\*r" "lim2" } }
> */
> +/* { dg-final { scan-tree-dump "Executing store motion of \\\*r" "lim3" } }
> */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c
> index 4ee704969aa..6a4b8196bd5 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-1.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2" } */
> +/* { dg-options "-O -fdump-tree-lim3" } */
>
> /* This is a variant that does cause fold to place a cast to
> int before testing bit 1. */
> @@ -18,4 +18,4 @@ quantum_toffoli (int control1, int control2, int target,
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c
> index ec609d81c68..afa547c8eac 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-10.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> int *l, *r;
> int test_func(void)
> @@ -27,4 +27,4 @@ int test_func(void)
> return i;
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion of pos" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of pos" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-11.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-11.c
> index f35c0f38e29..53740952c97 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-11.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-11.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fprofile-arcs -fprofile-update=single
> -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fprofile-arcs -fprofile-update=single
> -fdump-tree-lim3-details" } */
> /* { dg-require-profiling "-fprofile-generate" } */
>
> struct thread_param
> @@ -22,4 +22,4 @@ void access_buf(struct thread_param* p)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of
> __gcov0.access_buf\\\[\[12\]\\\] from loop 1" 2 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of
> __gcov0.access_buf\\\[\[12\]\\\] from loop 1" 2 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c
> index c483951395b..c2aaf1b003e 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2" } */
> +/* { dg-options "-O -fdump-tree-lim3" } */
>
> int a[1024];
>
> @@ -23,4 +23,4 @@ void bar (int x, int z)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times " = _\[0-9\]+ ? " 2 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times " = _\[0-9\]+ ? " 2 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c
> index 65aa7457704..8b83fb356da 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fgimple -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fgimple -fdump-tree-lim3-details" } */
>
> int __GIMPLE (ssa,startwith("lim"))
> foo (int x, int n)
> @@ -49,5 +49,5 @@ foo (int x, int n)
> return _6;
> }
>
> -/* { dg-final { scan-tree-dump-times "Moving statement" 2 "lim2" } } */
> -/* { dg-final { scan-tree-dump "ABSU_EXPR" "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving statement" 2 "lim3" } } */
> +/* { dg-final { scan-tree-dump "ABSU_EXPR" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-14.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-14.c
> index 3eb5be8b23f..760d449f54b 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-14.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-14.c
> @@ -29,5 +29,5 @@ int main(void)
> return 0;
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion of \\*p" "lim2" } } */
> -/* { dg-final { scan-tree-dump "Executing store motion of \\*r" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of \\*p" "lim3" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of \\*r" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c
> index 5efb95627ee..2030190d8f9 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-15.c
> @@ -1,6 +1,6 @@
> /* PR/101293 */
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> struct X { int i; int j; };
>
> @@ -15,4 +15,4 @@ void foo(struct X *x, int n)
> }
>
> /* Make sure LIM can handle unifying MEM[x, 4] and MEM[x].j */
> -/* { dg-final { scan-tree-dump "Executing store motion" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c
> index 741582b745f..f35c5bfe388 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-16.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> volatile int flag, bar;
> double foo (double *valp)
> @@ -16,4 +16,4 @@ double foo (double *valp)
> return sum;
> }
>
> -/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c
> index 1c840e554b7..0d5949ac89d 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-17.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> volatile int flag, bar;
> double foo (double *valp)
> @@ -17,4 +17,4 @@ double foo (double *valp)
> return sum;
> }
>
> -/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-18.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-18.c
> index da19806b712..acd859e18a5 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-18.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-18.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fstrict-aliasing -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fstrict-aliasing -fdump-tree-lim3-details" } */
>
> unsigned p;
>
> @@ -16,4 +16,4 @@ void foo (float *q)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-19.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-19.c
> index 51c1913d003..2f7c44d9499 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-19.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-19.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> volatile int x;
> void
> @@ -24,6 +24,6 @@ foo (int *a, int n, int m, int s, int t)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "out of loop 2" 4 "lim2" } } */
> -/* { dg-final { scan-tree-dump-times "out of loop 1" 3 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "out of loop 2" 4 "lim3" } } */
> +/* { dg-final { scan-tree-dump-times "out of loop 1" 3 "lim3" } } */
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c
> index 37639cdbaf7..9ef7bae89a8 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-2.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2" } */
> +/* { dg-options "-O -fdump-tree-lim3" } */
>
> /* This is a variant that doesn't cause fold to place a cast to
> int before testing bit 1. */
> @@ -18,4 +18,4 @@ int size)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "1 <<" 3 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-20.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-20.c
> index bc60a040a70..623a59e292a 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-20.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-20.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> /* Test that `count' is not hoisted out of loop when bb is cold. */
>
> @@ -22,4 +22,4 @@ func (int m)
>
> }
>
> -/* { dg-final { scan-tree-dump-not "Executing store motion of" "lim2" } }
> */
> +/* { dg-final { scan-tree-dump-not "Executing store motion of" "lim3" } }
> */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-21.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-21.c
> index fe29e841f28..79fdaa35803 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-21.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-21.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> /* Test that `data' and 'data1' is not hoisted out of inner loop and outer
> loop
> when it is in cold loop. */
> @@ -31,6 +31,6 @@ func (int m, int n, int k, struct obj *a)
> }
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion of count from loop 2"
> "lim2" } } */
> -/* { dg-final { scan-tree-dump "Executing store motion of \[^ \]*data1 from
> loop 2" "lim2" } } */
> -/* { dg-final { scan-tree-dump-times "Executing store motion of" 2 "lim2" }
> } */
> +/* { dg-final { scan-tree-dump "Executing store motion of count from loop 2"
> "lim3" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of \[^ \]*data1 from
> loop 2" "lim3" } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of" 2 "lim3" }
> } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-22.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-22.c
> index 16ba4ceb8ab..d415ede79a5 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-22.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-22.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> volatile int x;
> volatile int y;
> @@ -26,7 +26,7 @@ foo (int *a, int n, int m, int s, int t)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "out of loop 3" 4 "lim2" } } */
> -/* { dg-final { scan-tree-dump-times "out of loop 1" 3 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "out of loop 3" 4 "lim3" } } */
> +/* { dg-final { scan-tree-dump-times "out of loop 1" 3 "lim3" } } */
>
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-23.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-23.c
> index e7880746422..01d2155579f 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-23.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-23.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> volatile int x;
> void
> @@ -17,5 +17,5 @@ foo (int *a, int n, int k)
> }
> }
>
> -/* { dg-final { scan-tree-dump-not "out of loop 1" "lim2" } } */
> +/* { dg-final { scan-tree-dump-not "out of loop 1" "lim3" } } */
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-24.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-24.c
> index 6b463490a91..ca756c3b37e 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-24.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-24.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details -fdump-tree-optimized" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details -fdump-tree-optimized" } */
>
> extern volatile int *x;
> static int gCrc;
> @@ -20,6 +20,6 @@ void f(int data, int dataSz)
> }
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion of gCrc" "lim2" } } */
> -/* { dg-final { scan-tree-dump-not "Re-issueing" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of gCrc" "lim3" } } */
> +/* { dg-final { scan-tree-dump-not "Re-issueing" "lim3" } } */
> /* { dg-final { scan-tree-dump-times "\\*x" 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-25.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-25.c
> index 3e0f013d1e0..7b90f95bb74 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-25.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-25.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> char x;
>
> @@ -14,5 +14,5 @@ long foo (int n)
>
> /* Because *(long *)&x may trap we have to preserve execution and
> only hoist it from the innermost loop (after the header check). */
> -/* { dg-final { scan-tree-dump-not "out of loop 1" "lim2" } } */
> -/* { dg-final { scan-tree-dump "out of loop 2" "lim2" } } */
> +/* { dg-final { scan-tree-dump-not "out of loop 1" "lim3" } } */
> +/* { dg-final { scan-tree-dump "out of loop 2" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c
> index f059d5a0209..dc7f41a1c44 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-3.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fdump-tree-lim3-details" } */
>
> struct { int x; int y; } global;
> void foo(int n)
> @@ -9,5 +9,5 @@ void foo(int n)
> global.y += global.x*global.x;
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion of global.y" "lim2" }
> } */
> -/* { dg-final { scan-tree-dump "Moving statement.*global.x.*out of loop 1"
> "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of global.y" "lim3" }
> } */
> +/* { dg-final { scan-tree-dump "Moving statement.*global.x.*out of loop 1"
> "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c
> index 21edcd0a0dc..535d627203b 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-6.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> double a[16][64], y[64], x[16];
> void foo(void)
> @@ -10,4 +10,4 @@ void foo(void)
> y[j] = y[j] + a[i][j] * x[i];
> }
>
> -/* { dg-final { scan-tree-dump "Executing store motion of y" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Executing store motion of y" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c
> index 7612e75afae..bf4e8ec8976 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fdump-tree-lim3-details" } */
>
> extern const int srcshift;
>
> @@ -11,4 +11,4 @@ void foo (int *srcdata, int *dstdata)
> dstdata[i] = srcdata[i] << srcshift;
> }
>
> -/* { dg-final { scan-tree-dump "Moving statement" "lim2" } } */
> +/* { dg-final { scan-tree-dump "Moving statement" "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-8.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-8.c
> index 9256b39fb44..fb69af35ec7 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-8.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-8.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fdump-tree-lim3-details" } */
>
> void bar (int);
> void foo (int n, int m)
> @@ -16,4 +16,4 @@ void foo (int n, int m)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Moving PHI node" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving PHI node" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-9.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-9.c
> index a65656f49ee..9d2e8174864 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-9.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-9.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O -fdump-tree-lim2-details" } */
> +/* { dg-options "-O -fdump-tree-lim3-details" } */
>
> void bar (int);
> void foo (int n, int m)
> @@ -16,4 +16,4 @@ void foo (int n, int m)
> }
> }
>
> -/* { dg-final { scan-tree-dump-times "Moving PHI node" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Moving PHI node" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c
> index 94bdd4ab237..6abcb6c490d 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/structopt-1.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim2-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
> int x; int y;
> struct { int x; int y; } global;
> int foo() {
> @@ -10,5 +10,5 @@ int foo() {
> global.y += global.x*global.x;
> }
>
> -/* { dg-final { scan-tree-dump-times "Executing store motion of global.y" 1
> "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "Executing store motion of global.y" 1
> "lim3" } } */
> /* XXX: We should also check for the load motion of global.x, but there is
> no easy way to do this. */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/trapping-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/trapping-1.c
> index ea07562e47e..a3dd4cadca5 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/trapping-1.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/trapping-1.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-lim-details" } */
> +/* { dg-options "-O2 -fdump-tree-lim3-details" } */
>
> /* PR tree-optimization/117234 */
> /* PAREN_EXPR should not be declared as
> @@ -18,4 +18,4 @@ float f1(float a, int t, _Bool *b, float c)
>
> /* There should be 3 `invariant up to level`, two for each `-` and one
> for the PAREN_EXPR. */
> -/* { dg-final { scan-tree-dump-times "invariant up to level" 3 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "invariant up to level" 3 "lim3" } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/trapping-1.c
> b/gcc/testsuite/gcc.target/aarch64/sve/trapping-1.c
> index 1ac7ac708d2..bdedb170d05 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/trapping-1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/trapping-1.c
> @@ -18,4 +18,4 @@ svfloat32_t f(float a, int t, _Bool *b)
> }
>
> /* There should be 1 `invariant up to level`, one for the
> VEC_DUPLICATE_EXPR. */
> -/* { dg-final { scan-tree-dump-times "invariant up to level" 1 "lim2" } } */
> +/* { dg-final { scan-tree-dump-times "invariant up to level" 1 "lim3" } } */
> diff --git a/gcc/testsuite/gfortran.dg/pr104466.f90
> b/gcc/testsuite/gfortran.dg/pr104466.f90
> index ec0e45866be..944c9dba2f9 100644
> --- a/gcc/testsuite/gfortran.dg/pr104466.f90
> +++ b/gcc/testsuite/gfortran.dg/pr104466.f90
> @@ -1,5 +1,5 @@
> ! { dg-do compile }
> -! { dg-options "-std=legacy -O2 --param max-inline-insns-auto=0 --param
> max-inline-insns-single=0 -fdump-tree-lim2-details" }
> +! { dg-options "-std=legacy -O2 --param max-inline-insns-auto=0 --param
> max-inline-insns-single=0 -fdump-tree-lim3-details" }
>
> MODULE mod_param
> integer, parameter :: Ngrids = 1
> @@ -112,5 +112,5 @@
> END
> END
>
> -! { dg-final { scan-tree-dump-not ": dependent" "lim2" } }
> -! { dg-final { scan-tree-dump "Moving statement\[\n\r\]_\[0-9\]+ = n" "lim2"
> } }
> +! { dg-final { scan-tree-dump-not ": dependent" "lim3" } }
> +! { dg-final { scan-tree-dump "Moving statement\[\n\r\]_\[0-9\]+ = n" "lim3"
> } }
> diff --git a/gcc/testsuite/gfortran.dg/pr32921.f
> b/gcc/testsuite/gfortran.dg/pr32921.f
> index 0661208edde..e7264b7a9ca 100644
> --- a/gcc/testsuite/gfortran.dg/pr32921.f
> +++ b/gcc/testsuite/gfortran.dg/pr32921.f
> @@ -1,5 +1,5 @@
> ! { dg-do compile }
> -! { dg-options "-O2 -fdump-tree-lim2" }
> +! { dg-options "-O2 -fdump-tree-lim3" }
> ! gfortran -c -m32 -O2 -S junk.f
> !
> MODULE LES3D_DATA
> @@ -45,4 +45,4 @@
>
> RETURN
> END
> -! { dg-final { scan-tree-dump-times "stride" 4 "lim2" } }
> +! { dg-final { scan-tree-dump-times "stride" 4 "lim3" } }
> diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
> index 0340857058b..0c5647c9c50 100644
> --- a/gcc/tree-ssa-loop-im.cc
> +++ b/gcc/tree-ssa-loop-im.cc
> @@ -1107,10 +1107,11 @@ rewrite_bittest (gimple_stmt_iterator *bsi)
>
> /* Determine the outermost loops in that statements in basic block BB are
> invariant, and record them to the LIM_DATA associated with the
> + statements. If PHI_MOTION is true also try to hoist PHIs and dependent
> statements. */
>
> static void
> -compute_invariantness (basic_block bb)
> +compute_invariantness (basic_block bb, bool phi_motion)
> {
> enum move_pos pos;
> gimple_stmt_iterator bsi;
> @@ -1131,7 +1132,8 @@ compute_invariantness (basic_block bb)
> code and transforming adjacent cond-exprs with the same predicate
> to control flow again. */
> bsi = gsi_start_phis (bb);
> - if (!gsi_end_p (bsi)
> + if (phi_motion
> + && !gsi_end_p (bsi)
> && ((gsi_next (&bsi), gsi_end_p (bsi))
> || (gsi_next (&bsi), gsi_end_p (bsi))))
> for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
> @@ -3685,7 +3687,7 @@ tree_ssa_lim_finalize (void)
> Only perform store motion if STORE_MOTION is true. */
>
> unsigned int
> -loop_invariant_motion_in_fun (function *fun, bool store_motion)
> +loop_invariant_motion_in_fun (function *fun, bool store_motion, bool
> phi_motion)
> {
> unsigned int todo = 0;
>
> @@ -3715,7 +3717,7 @@ loop_invariant_motion_in_fun (function *fun, bool
> store_motion)
> /* For each statement determine the outermost loop in that it is
> invariant and cost for computing the invariant. */
> for (int i = 0; i < n; ++i)
> - compute_invariantness (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
> + compute_invariantness (BASIC_BLOCK_FOR_FN (fun, rpo[i]), phi_motion);
>
> /* Execute store motion. Force the necessary invariants to be moved
> out of the loops as well. */
> @@ -3762,31 +3764,43 @@ class pass_lim : public gimple_opt_pass
> {
> public:
> pass_lim (gcc::context *ctxt)
> - : gimple_opt_pass (pass_data_lim, ctxt)
> + : gimple_opt_pass (pass_data_lim, ctxt), early_p (false)
> {}
>
> /* opt_pass methods: */
> opt_pass * clone () final override { return new pass_lim (m_ctxt); }
> + void set_pass_param (unsigned n, bool param) final override
> + {
> + gcc_assert (n == 0);
> + early_p = param;
> + }
> bool gate (function *) final override { return flag_tree_loop_im != 0; }
> unsigned int execute (function *) final override;
>
> +private:
> + bool early_p;
> }; // class pass_lim
>
> unsigned int
> pass_lim::execute (function *fun)
> {
> + if (number_of_loops (fun) <= 1)
> + return 0;
> +
> in_loop_pipeline = scev_initialized_p ();
> if (!in_loop_pipeline)
> loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
>
> - if (number_of_loops (fun) <= 1)
> - return 0;
> - unsigned int todo = loop_invariant_motion_in_fun (fun,
> flag_move_loop_stores);
> + unsigned int todo = loop_invariant_motion_in_fun (fun,
> + !early_p
> + && flag_move_loop_stores,
> + !early_p);
>
> if (!in_loop_pipeline)
> loop_optimizer_finalize ();
> else
> scev_reset ();
> +
> return todo;
> }
>
> diff --git a/gcc/tree-ssa-loop-manip.h b/gcc/tree-ssa-loop-manip.h
> index 80f680565c0..0eadfc9dc34 100644
> --- a/gcc/tree-ssa-loop-manip.h
> +++ b/gcc/tree-ssa-loop-manip.h
> @@ -51,7 +51,7 @@ extern void tree_transform_and_unroll_loop (class loop *,
> unsigned,
> transform_callback, void *);
> extern void tree_unroll_loop (class loop *, unsigned, tree_niter_desc *);
> extern tree canonicalize_loop_ivs (class loop *, tree *, bool);
> -extern unsigned int loop_invariant_motion_in_fun (function *, bool);
> +extern unsigned int loop_invariant_motion_in_fun (function *, bool, bool);
>
>
> #endif /* GCC_TREE_SSA_LOOP_MANIP_H */
> --
> 2.51.0