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.

gcc.dg/tree-ssa/ssa-lim-{19,22}.c shows we're lacking a guessed profile
and reflecting __builtin_expect into the IL.

gcc.dg/vect/pr69783.c needs to be analyzed, early LIM prevents some
folding it seems

gcc.dg/vect/vect-simd-17.c shows cunrolli and OMP SIMD vectorization
interact badly (I filed PR122711), early LIM adds one extra case

gfortran.dg/vect/O3-pr49957.f needs to be analyzed, somehow early LIM
prevents dependence analysis, likely similar to gcc.dg/vect/pr69783.c

gfortran.dg/vect/fast-math-pr37021.f90 shows that post-IPA local
PTA gets worse results when LIM1 moves pointer arithmetic as
arithmetic on unsigned due to avoiding UB, this results in 'nonlocal'
getting in though conservative offset handling, dropping restrict info.
This might be due to the lack of a copied loop header.

Otherwise bootstrapped and tested on x86_64-unknown-linux-gnu.

I'm putting this on hold for now, some of the above issues need to
be resolved first.

        PR ipa/118570
        PR tree-optimization/121685
        PR tree-optimization/121744
        * 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::gate_p): Run early LIM only when -fexpensive-optimizations
        is enabled.
        (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.
        ...
        * g++.dg/tree-ssa/pr117123.C: Expect 2 ifs, ifcombine can now
        merge two.
        * gcc.dg/loop-unswitch-1.c: Remove over-simplified test.
        * gcc.dg/tree-ssa/ssa-lim-13.c: Start with 2nd lim pass.
---
 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/pr117123.C      |  2 +-
 gcc/testsuite/g++.dg/tree-ssa/pr33615.C       |  4 +--
 gcc/testsuite/g++.dg/tree-ssa/restrict1.C     |  4 +--
 gcc/testsuite/gcc.dg/loop-unswitch-1.c        | 36 -------------------
 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    |  8 ++---
 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                       | 36 ++++++++++++++-----
 gcc/tree-ssa-loop-manip.h                     |  2 +-
 56 files changed, 141 insertions(+), 158 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.dg/loop-unswitch-1.c

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 fac04cd86c7..70df4c2692e 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 940365cd549..b1e01381139 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 _\[0-9\]+ = \\\*_" 2 
"lim2" } } */
+/* { dg-final { scan-tree-dump-times "Moving statement _\[0-9\]+ = \\\*_" 2 
"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/pr117123.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr117123.C
index 2aa2810de95..3f7c77bbcc3 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr117123.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr117123.C
@@ -49,4 +49,4 @@ int patatino(int a) {
 }
 
 // { dg-final { scan-tree-dump-not "dont_be_here" "optimized" } }
-// { dg-final { scan-tree-dump-times "if " 3 "optimized" } }
+// { dg-final { scan-tree-dump-times "if " 2 "optimized" } }
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/loop-unswitch-1.c 
b/gcc/testsuite/gcc.dg/loop-unswitch-1.c
deleted file mode 100644
index 196cb64735e..00000000000
--- a/gcc/testsuite/gcc.dg/loop-unswitch-1.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* For PR rtl-optimization/27735  */
-/* { dg-do compile } */
-/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-all 
-fno-finite-loops" } */
-
-void set_color(void);
-void xml_colorize_line(unsigned int *p, int state)
-{
-  int c;
-  switch(state) 
-    {
-    case 1:
-      goto parse_tag;
-    case 2:
-      goto parse_comment;
-    }
-
-  for(;;) 
-    {
-      c = *p;  
-      if (c == '<' && state == 0) 
-       {
-parse_comment: ;
-         while (*p != '\n') 
-           state = 3;
-parse_tag: ;
-         while (*p != '\n') 
-           state = 0;
-         set_color();
-       }
-      else
-       p++;
-    }
-}
-
-/* Test that we actually unswitched something.  */
-/* { dg-final { scan-tree-dump "unswitching loop" "unswitch" } } */
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..e9b1d21dae2 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-13.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fgimple -fdump-tree-lim2-details" } */
+/* { dg-options "-O2 -fgimple -fdump-tree-lim3-details" } */
 
-int __GIMPLE (ssa,startwith("lim"))
+int __GIMPLE (ssa,startwith("lim2"))
 foo (int x, int n)
 {
   int i;
@@ -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 bc14065b563..b9b066e450a 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 _\[0-9\]+ = n" "lim2" } }
+! { dg-final { scan-tree-dump-not ": dependent" "lim3" } }
+! { dg-final { scan-tree-dump "Moving statement _\[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 c8f4676b6f6..075a7cc7595 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))
@@ -3691,7 +3693,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;
 
@@ -3721,7 +3723,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.  */
@@ -3768,31 +3770,47 @@ 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); }
-  bool gate (function *) final override { return flag_tree_loop_im != 0; }
+  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
+             && (!early_p || flag_expensive_optimizations));
+    }
   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

Reply via email to