> Am 15.11.2025 um 11:51 schrieb Andrew Pinski <[email protected]>:
>
> 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?
I think removing mergephi in early stage3 is ok.
Richard
> 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