diff --git a/gcc/testsuite/g++.dg/ipa/devirt-19.C b/gcc/testsuite/g++.dg/ipa/devirt-19.C
index 8277deaabdd..f35bc32f85b 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-19.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-19.C
@@ -2,7 +2,7 @@
    Previously we were failing by considering CLOBBER statement to be
    a type change.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-cp"  } */
+/* { dg-options "-O2 -fdump-ipa-cp -fipa-cp-clone"  } */
 /* { dg-additional-options "-Wno-return-type"  } */
 
 struct A {
@@ -23,9 +23,12 @@ public:
 
 C<int, int> b;
 template <typename T, typename M> const M &C<T, M>::m_fn2(const T &) {
+
   A a = _map.m_fn2();
   a == _map.m_fn1();
   m_fn1();
+  static M m;
+  return m;
 }
 
 void fn1() { b.m_fn2(0); }
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-sra-1.C b/gcc/testsuite/g++.dg/ipa/ipa-sra-1.C
new file mode 100644
index 00000000000..ef7d704b3f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/ipa-sra-1.C
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra"  } */
+
+void fn1(int *, int *, double *, int *, double *);
+int a, c, d, e, f, g, k;
+double *b;
+double h, i;
+void fn2(int *p1, int *p2, double *p3) {
+  int l = 0, j, q, r;
+  double m, n, o, p, s, t, u;
+  --p3;
+  for (; a;) {
+    if (c) {
+      ++*p2;
+      goto L170;
+    }
+    m = n = b[c];
+    p = t = m;
+    for (; j; ++j) {
+      u = 1.;
+      if (k) {
+        s = o;
+        u = -1.;
+      }
+    }
+    i = u * p;
+  L60:
+    p3[1] = s;
+    for (; d;)
+      goto L60;
+    fn1(&f, &g, &h, &l, &p3[1]);
+    o = p3[1];
+  L100:
+    o *= i;
+    if (e)
+      goto L100;
+  L170:;
+  }
+  if (*p1)
+    for (;;) {
+      if (r)
+        q = *p2;
+      d = q - j;
+      r = j;
+    }
+}
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-sra-2.C b/gcc/testsuite/g++.dg/ipa/ipa-sra-2.C
new file mode 100644
index 00000000000..17bd13ad5c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/ipa-sra-2.C
@@ -0,0 +1,19 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-O2 -fipa-sra"  } */
+
+class a {
+  void b();
+  char16_t c;
+  char16_t d;
+};
+void e(a);
+void g();
+void a::b() {
+  char16_t f = d;
+  e(*this);
+  for (;;) {
+    g();
+    if (f)
+      break;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-sra-3.C b/gcc/testsuite/g++.dg/ipa/ipa-sra-3.C
new file mode 100644
index 00000000000..d15ae22cb98
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/ipa-sra-3.C
@@ -0,0 +1,9 @@
+/* { dg-options "-O2 -fipa-sra -fno-inline -fno-ipa-cp"  } */
+
+
+char *a() __attribute__((__malloc__));
+static char *b() {
+  char *c = a();
+  return c;
+}
+int d() { b(); return 4; }
diff --git a/gcc/testsuite/g++.dg/ipa/pr81248.C b/gcc/testsuite/g++.dg/ipa/pr81248.C
index d7796ff7ab7..b79710fc048 100644
--- a/gcc/testsuite/g++.dg/ipa/pr81248.C
+++ b/gcc/testsuite/g++.dg/ipa/pr81248.C
@@ -1,5 +1,5 @@
 // { dg-do compile { target c++17 } }
-// { dg-options "-O2 -fdump-tree-eipa_sra" }
+// { dg-options "-O2 -fdump-ipa-sra" }
 
 
 #include <type_traits>
@@ -37,4 +37,4 @@ int main() {
     f(n2);
 }
 
-// { dg-final { scan-tree-dump-times "Adjusting call" 2 "eipa_sra" } }
+// { dg-final { scan-ipa-dump "Will split parameter 0" "sra" } }
diff --git a/gcc/testsuite/g++.dg/lto/devirt-19_0.C b/gcc/testsuite/g++.dg/lto/devirt-19_0.C
index b43527e324e..7d536515437 100644
--- a/gcc/testsuite/g++.dg/lto/devirt-19_0.C
+++ b/gcc/testsuite/g++.dg/lto/devirt-19_0.C
@@ -1,5 +1,5 @@
 /* { dg-lto-do link } */
-/* { dg-lto-options { "-O2 -fdump-ipa-cp -Wno-return-type -flto -r -nostdlib" } } */
+/* { dg-lto-options { "-O2 -fdump-ipa-cp -fipa-cp-clone -Wno-return-type -flto -r -nostdlib" } } */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel -flto=auto" } */
 #include "../ipa/devirt-19.C"
 /* { dg-final { scan-wpa-ipa-dump-times "Discovered a virtual call to a known target" 1 "cp"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/20040703-wpa.c b/gcc/testsuite/gcc.dg/ipa/20040703-wpa.c
new file mode 100644
index 00000000000..b1a318be886
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/20040703-wpa.c
@@ -0,0 +1,151 @@
+/* With -fwhole-program this is an excelent testcase for inlining IPA-SRAed
+   functions into each other.  */
+/* { dg-do run } */
+/* { dg-options "-O2 -w -fno-ipa-cp -fwhole-program"  } */
+/* { dg-require-effective-target int32plus } */
+
+#define PART_PRECISION (sizeof (cpp_num_part) * 8)
+
+typedef unsigned int cpp_num_part;
+typedef struct cpp_num cpp_num;
+struct cpp_num
+{
+   cpp_num_part high;
+   cpp_num_part low;
+   int unsignedp;  /* True if value should be treated as unsigned.  */
+   int overflow;   /* True if the most recent calculation overflowed.  */
+};
+
+static  int
+num_positive (cpp_num num, unsigned int precision)
+{
+   if (precision > PART_PRECISION)
+     {
+       precision -= PART_PRECISION;
+       return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
+     }
+
+   return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
+}
+
+static cpp_num
+num_trim (cpp_num num, unsigned int precision)
+{
+   if (precision > PART_PRECISION)
+     {
+       precision -= PART_PRECISION;
+       if (precision < PART_PRECISION)
+         num.high &= ((cpp_num_part) 1 << precision) - 1;
+     }
+   else
+     {
+       if (precision < PART_PRECISION)
+         num.low &= ((cpp_num_part) 1 << precision) - 1;
+       num.high = 0;
+     }
+
+   return num;
+}
+
+/* Shift NUM, of width PRECISION, right by N bits.  */
+static cpp_num
+num_rshift (cpp_num num, unsigned int precision, unsigned int n)
+{
+   cpp_num_part sign_mask;
+   int x = num_positive (num, precision);
+
+   if (num.unsignedp || x)
+     sign_mask = 0;
+   else
+     sign_mask = ~(cpp_num_part) 0;
+
+   if (n >= precision)
+     num.high = num.low = sign_mask;
+   else
+     {
+       /* Sign-extend.  */
+       if (precision < PART_PRECISION)
+         num.high = sign_mask, num.low |= sign_mask << precision;
+       else if (precision < 2 * PART_PRECISION)
+         num.high |= sign_mask << (precision - PART_PRECISION);
+
+       if (n >= PART_PRECISION)
+         {
+           n -= PART_PRECISION;
+           num.low = num.high;
+           num.high = sign_mask;
+         }
+
+       if (n)
+         {
+           num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
+           num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
+         }
+     }
+
+   num = num_trim (num, precision);
+   num.overflow = 0;
+   return num;
+}
+                              #define num_zerop(num) ((num.low | num.high) == 0)
+#define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
+
+cpp_num
+num_lshift (cpp_num num, unsigned int precision, unsigned int n)
+{
+   if (n >= precision)
+     {
+       num.overflow = !num.unsignedp && !num_zerop (num);
+       num.high = num.low = 0;
+     }
+   else
+     {
+       cpp_num orig;
+       unsigned int m = n;
+
+       orig = num;
+       if (m >= PART_PRECISION)
+         {
+           m -= PART_PRECISION;
+           num.high = num.low;
+           num.low = 0;
+         }
+       if (m)
+         {
+           num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
+           num.low <<= m;
+         }
+       num = num_trim (num, precision);
+
+       if (num.unsignedp)
+         num.overflow = 0;
+       else
+         {
+           cpp_num maybe_orig = num_rshift (num, precision, n);
+           num.overflow = !num_eq (orig, maybe_orig);
+         }
+     }
+
+   return num;
+}
+
+unsigned int precision = 64;
+unsigned int n = 16;
+
+cpp_num num = { 0, 3, 0, 0 };
+
+int main()
+{
+   cpp_num res = num_lshift (num, 64, n);
+
+   if (res.low != 0x30000)
+     abort ();
+
+   if (res.high != 0)
+     abort ();
+
+   if (res.overflow != 0)
+     abort ();
+
+   exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
index 4db904b419e..4a22e3978f9 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details"  } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra-details"  } */
 
 struct bovid
 {
@@ -36,4 +36,4 @@ main (int argc, char *argv[])
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "About to replace expr" 2 "eipa_sra" } } */
+/* { dg-final { scan-ipa-dump "Will split parameter" "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-10.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-10.c
index 24b64d1234a..b5535cfffff 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-10.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-10.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details"  } */
+/* { dg-options "-O2 -fno-ipa-cp -fipa-sra -fdump-ipa-sra"  } */
 
 extern void consume (int);
 extern int glob, glob1, glob2;
@@ -31,4 +31,4 @@ bar (int a)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "replacing an SSA name of a removed param" 4 "eipa_sra" } } */
+/* { dg-final { scan-ipa-dump "Will remove parameter 0" "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-11.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-11.c
index e91423a62fb..61c02c1c47c 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-11.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-11.c
@@ -1,5 +1,5 @@
-/* { dg-do run } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details"  } */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra-details"  } */
 
 struct bovid
 {
@@ -36,4 +36,4 @@ main (int argc, char *argv[])
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-not "About to replace expr" "eipa_sra" } } */
+/* { dg-final { scan-ipa-dump-not "Will split parameter" "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c
new file mode 100644
index 00000000000..689071e566c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra"  } */
+
+/* Check of a simple and transitive structure split. */
+
+struct S
+{
+  float red;
+  void *blue;
+  int green;
+};
+
+
+void __attribute__((noipa))
+check (float r, int g, int g2)
+{
+  if (r < 7.39 || r > 7.41
+      || g != 6 || g2 != 6)
+    __builtin_abort ();
+}
+
+static void
+__attribute__((noinline))
+foo (struct S s)
+{
+  check (s.red, s.green, s.green);
+}
+
+static void
+__attribute__((noinline))
+bar (struct S s)
+{
+  foo (s);
+}
+
+int
+main (int argc, char *argv[])
+{
+  struct S s;
+
+  s.red = 7.4;
+  s.green = 6;
+  s.blue = &s;
+
+  bar (s);
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 2 "sra" } } */
+/* { dg-final { scan-ipa-dump-times "component at byte offset" 4 "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c
new file mode 100644
index 00000000000..4d4ed74cfd6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c
@@ -0,0 +1,49 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra"  } */
+
+/* Check of a by-reference structure split. */
+
+struct S
+{
+  float red;
+  void *blue;
+  int green;
+};
+
+void __attribute__((noipa))
+check (float r, int g, int g2)
+{
+  if (r < 7.39 || r > 7.41
+      || g != 6 || g2 != 6)
+    __builtin_abort ();
+}
+
+static void
+__attribute__((noinline))
+foo (struct S *s)
+{
+  check (s->red, s->green, s->green);
+}
+
+static void
+__attribute__((noinline))
+bar (struct S *s)
+{
+  foo (s);
+}
+
+int
+main (int argc, char *argv[])
+{
+  struct S s;
+
+  s.red = 7.4;
+  s.green = 6;
+  s.blue = &s;
+
+  bar (&s);
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 2 "sra" } } */
+/* { dg-final { scan-ipa-dump-times "component at byte offset" 4 "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c
new file mode 100644
index 00000000000..01881249d90
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra"  } */
+
+/* Check of a transitive recursive structure split. */
+
+struct S
+{
+  float red;
+  void *blue;
+  int green;
+};
+
+
+static int done = 0;
+
+void __attribute__((noipa))
+check (float r, int g, int g2)
+{
+  if (r < 7.39 || r > 7.41
+      || g != 6 || g2 != 6)
+    __builtin_abort ();
+}
+
+static void __attribute__((noinline)) bar (struct S s);
+
+static void
+__attribute__((noinline))
+foo (struct S s)
+{
+  if (!done)
+    {
+      done = 1;
+      bar (s);
+    }
+  check (s.red, s.green, s.green);
+}
+
+static void
+__attribute__((noinline))
+bar (struct S s)
+{
+  foo (s);
+}
+
+int
+main (int argc, char *argv[])
+{
+  struct S s;
+
+  s.red = 7.4;
+  s.green = 6;
+  s.blue = &s;
+
+  bar (s);
+  return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 2 "sra" } } */
+/* { dg-final { scan-ipa-dump-times "component at byte offset" 4 "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c
new file mode 100644
index 00000000000..6c57c7bcebc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra"  } */
+
+/* Check of a recursive by-reference structure split.  The recursive functions
+   have to be pure right from the start, otherwise the current AA would detect
+   possible modification of data.  */
+
+struct S
+{
+  float red;
+  void *blue;
+  int green;
+};
+
+void __attribute__((noipa))
+check (float r, int g, int g2)
+{
+  if (r < 7.39 || r > 7.41
+      || g != 6 || g2 != 6)
+    __builtin_abort ();
+  return;
+}
+
+static int __attribute__((noinline, pure)) bar (struct S *s, int rec);
+
+static int
+__attribute__((noinline, pure))
+foo (struct S *s , int rec)
+{
+  int t = 0;
+  if (rec)
+    t = bar (s, 0);
+  check (s->red, s->green, s->green);
+  return t;
+}
+
+static int
+__attribute__((noinline, pure))
+bar (struct S *s, int rec)
+{
+  int t = foo (s, rec);
+  return t + t;
+}
+
+volatile int g;
+
+int
+main (int argc, char *argv[])
+{
+  struct S s;
+
+  s.red = 7.4;
+  s.green = 6;
+  s.blue = &s;
+
+  g = bar (&s, 1);
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 2 "sra" } } */
+/* { dg-final { scan-ipa-dump-times "component at byte offset" 4 "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-16.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-16.c
new file mode 100644
index 00000000000..2bffe297c74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-16.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra -fdump-tree-optimized"  } */
+
+/* Testing removal of unused parameters in recursive calls.  */
+
+extern int work_1 (int);
+extern int work_2 (int);
+
+static int __attribute__((noinline))
+foo (int l, int w1, int w2, int useless, int useless2);
+
+
+static int __attribute__((noinline))
+bar_1 (int l, int w1, int w2, int useless, int useless2)
+{
+  return work_1 (w1) + foo (l, w1, w2, useless2, useless);
+}
+
+static int __attribute__((noinline))
+baz_1 (int useless, int useless2, int l, int w1, int w2)
+{
+  return bar_1 (l, w1, w2, useless, useless2);
+}
+
+static int __attribute__((noinline))
+bax_1 (int l, int w1, int w2, int useless, int useless2)
+{
+  return baz_1 (useless, useless2, l, w1, w2);
+}
+
+
+
+static int __attribute__((noinline))
+bar_2 (int l, int w1, int w2, int useless, int useless2)
+{
+  return foo (l, w1, w2, useless2 + 5, useless);
+}
+
+static int __attribute__((noinline))
+baz_2 (int useless, int useless2, int l, int w1, int w2)
+{
+  return bar_2 (l, w1, w2, useless, useless2);
+}
+
+
+static int __attribute__((noinline))
+bax_2 (int l, int w1, int w2, int useless, int useless2)
+{
+  return work_2 (w2) + baz_2 (useless, useless2, l, w1, w2);
+}
+
+
+static int __attribute__((noinline))
+ foo (int l, int w1, int w2, int useless, int useless2)
+{
+  int r = 0;
+  if (!l)
+    return r;
+  if (l % 2)
+    r = bax_1 (l - 1, w1, w2, useless, useless2);
+  else
+    r = bax_2 (l - 1, w1, w2, useless, useless2);
+
+  return r;
+}
+
+int
+entry (int l, int w1, int w2, int noneed, int noneed2)
+{
+  return foo (l, w2, w2, noneed2, noneed2 + 4);
+}
+
+/* { dg-final { scan-ipa-dump-times "Will remove parameter" 14 "sra" } } */
+/* { dg-final { scan-tree-dump-not "useless" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-17.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-17.c
new file mode 100644
index 00000000000..9cb6367b374
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-17.c
@@ -0,0 +1,102 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-sra -fdump-tree-optimized"  } */
+
+#define DOIT
+#define DONT
+
+
+extern int extern_leaf (int);
+
+/* ----- 1 ----- */
+#ifdef DOIT
+static int __attribute__((noinline))
+whee_1 (int i, int j)
+{
+  return extern_leaf (i * j) + 1;
+}
+
+static int foo_1 (int i, int j);
+
+static int __attribute__((noinline))
+baz_1 (int i, int j)
+{
+  int a = 5;
+  if (j)
+    a = foo_1 (i, j - 1);
+  return whee_1 (i, j) + a + 1;
+}
+
+static int __attribute__((noinline))
+bar_1 (int i, int j)
+{
+  return baz_1 (i, j) + 1;
+}
+
+static int __attribute__((noinline))
+foo_1 (int i, int j)
+{
+  return bar_1 (i, j) + 1;
+}
+
+static int __attribute__((noinline))
+inter_1 (int i, int j)
+{
+  return foo_1 (i, j) + 1;
+}
+#endif
+
+/* ----- 2 ----- */
+#ifdef DONT
+static int __attribute__((noinline))
+whee_2 (int i, int j)
+{
+  return extern_leaf (i * j) + 2;
+}
+
+static int foo_2 (int i, int j);
+
+static int __attribute__((noinline))
+baz_2 (int i, int j)
+{
+  int a = 6;
+  if (j)
+    a = foo_2 (i, j - 1);
+  return whee_2 (i, j) + a + 2;
+}
+
+static int __attribute__((noinline))
+bar_2 (int i, int j)
+{
+  return baz_2 (i, j) + 2;
+}
+
+static int __attribute__((noinline))
+foo_2 (int i, int j)
+{
+  return bar_2 (i, j) + 2;
+}
+#endif
+
+/* ----- entries ----- */
+#ifdef DOIT
+int
+entry_1 (int i, int j)
+{
+  inter_1 (i, j);
+  return i + j + 1;
+}
+#endif
+
+#ifdef DONT
+int
+entry_2 (int i, int j)
+{
+#ifdef DOIT
+  inter_1 (i, j);
+#endif
+  return i + j + bar_2 (i, j);
+}
+#endif
+
+/* { dg-final { scan-ipa-dump-times "Will remove return value" 5 "sra" } } */
+/* { dg-final { scan-tree-dump-times "return;" 5 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-18.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-18.c
new file mode 100644
index 00000000000..3217b612231
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-18.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-sra"  } */
+
+struct S
+{
+  long a, b;
+};
+
+extern void leaf_a (int );
+extern void leaf_b (int, int);
+extern void leaf_c (int, int);
+
+extern void leaf_sa (struct S);
+
+static void baz (int i, int j, int k, int l, struct S a, struct S b);
+
+extern int gi;
+
+static void  __attribute__((noinline))
+foo (int i, int j, int k, int l, struct S a, struct S b)
+{
+  gi += l;
+  baz (i, j, k, l, a, b);
+}
+
+static void __attribute__((noinline))
+bar (int i, int j, int k, int l, struct S a, struct S b)
+{
+  foo (i, j, k, l, a, b);
+  leaf_sa (b);
+}
+
+
+static void __attribute__((noinline))
+baz (int i, int j, int k, int l, struct S a, struct S b)
+{
+  if (--k)
+    bar (i, j, k, l, a, b);
+  leaf_b (i, k);
+}
+
+void
+entry (int i, int j, int k, int l, struct S a, struct S b)
+{
+  foo (i, j, k, l, a, b);
+}
+
+/* { dg-final { scan-ipa-dump-times "Will remove parameter 1" 3 "sra" } } */
+/* { dg-final { scan-ipa-dump-times "Will remove parameter 4" 3 "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c
new file mode 100644
index 00000000000..adebaa5f5e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2"  } */
+
+typedef int __attribute__((__vector_size__(16))) vectype;
+
+vectype dk();
+vectype k();
+
+int b;
+vectype *j;
+inline int c(vectype *d) {
+  vectype e;
+  vectype f;
+  vectype g = *d;
+  vectype h = g;
+  vectype i = h;
+  f = i == dk();
+  e = f == b;
+  k(e);
+}
+
+static void m(vectype *d) {
+  int l = c(d);
+  if (l)
+    c(j);
+}
+
+void o(void) {
+  vectype n;
+  m(&n);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
index a31945c9c52..95abef7987a 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
@@ -1,5 +1,8 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details"  } */
+/* { dg-options "-O2 -fipa-sra"  } */
+
+/* Functionality no longer available with IPA IPA-SRA.  Test should be removed
+   altogether when committing the branch to trunk.  */
 
 struct bovid
 {
@@ -45,7 +48,3 @@ int main (int argc, char *argv[])
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "About to replace expr cow_.*D.->red with \\*ISRA" "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump "About to replace expr cow_.*D.->green with ISRA" "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump "About to replace expr calf_.*D.->red with \\*ISRA" "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump "About to replace expr calf_.*D.->green with ISRA" "eipa_sra"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-20.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-20.c
new file mode 100644
index 00000000000..a47df4f5c85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-20.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fipa-sra" } */
+
+typedef struct {
+  int a;
+} b;
+typedef struct {
+  double c;
+  double a;
+} d;
+typedef struct {
+  d e;
+  d f;
+} g;
+g h;
+b i, m;
+int j, k, l, n, o;
+static b q(d s) {
+  int r = s.c ?: 0;
+  if (r)
+    if (j)
+      l = j - 2;
+  o = k;
+  n = l;
+  i = m;
+  return m;
+}
+static void t(g s) {
+  {
+    d p = s.e;
+    int r = p.c ?: 0;
+    if (r) {
+      l = j - 2;
+    }
+  }
+  b f = q(s.f);
+}
+void main() { t(h); }
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-21.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-21.c
new file mode 100644
index 00000000000..67806b866fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-21.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int a;
+typedef int b;
+int c, e;
+void i();
+void n(d, ab, f, ae, af, action, ag, ah, ai, g, h, aj, ak, al, j, k, am, an, ao,
+       l, m) int action,
+    ag;
+int f, ae, af;
+int ah, ai;
+int j, k;
+int l, m;
+a aj, am;
+int ak, al, an, ao, g, h;
+char d, ab;
+{
+  if (c)
+    i(e);
+}
+void o(d, ab, action, at, ag, g, h, aj, ak, al, au, av, am, an, ao, aw, ax, ay,
+       az, ba, bb, ai) int action,
+    ag;
+int at, ai;
+int au, av, aw, ax;
+b ay, ba;
+int az, bb;
+int g, h;
+int ak, al, an, ao;
+a aj, am;
+char d, ab;
+{ n(); }
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-22.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-22.c
new file mode 100644
index 00000000000..0d6a3536067
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-22.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra"  } */
+
+struct W
+{
+  int a, b;
+};
+
+union U
+{
+  struct W w;
+  long l;
+};
+
+struct Z
+{
+  int k;
+  union U u;
+};
+
+struct S
+{
+  int i, j;
+  struct Z z;
+  char buf[64];
+};
+
+struct W gw;
+
+
+static long
+__attribute__((noinline))
+foo (struct Z z)
+{
+  return z.u.l;
+}
+
+static long
+__attribute__((noinline))
+bar (struct S s)
+{
+  if (s.i > 100)
+    return s.z.u.w.a;
+  else
+    return  foo (s.z);
+}
+
+volatile long g;
+
+long
+entry (struct S *p)
+{
+  struct S s = *p;
+
+  return bar (s) | 2;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
index 23dec2a661e..203650cfb40 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+/* { dg-options "-O2 -fno-ipa-cp -fipa-sra -fdump-ipa-sra" } */
 
 struct bovid
 {
@@ -34,5 +34,6 @@ void caller (void)
   return;
 }
 
-/* { dg-final { scan-tree-dump "base: z, remove_param" "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump "base: calf, remove_param" "eipa_sra"  } } */
+/* { dg-final { scan-ipa-dump "Will split parameter 0" "sra"  } } */
+/* { dg-final { scan-ipa-dump "Will remove parameter 1" "sra" } } */
+/* { dg-final { scan-ipa-dump "Will remove parameter 2" "sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
index 50ac179b225..fdbd5e5d72d 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+/* { dg-options "-O2 -fipa-sra -fno-ipa-pure-const -fdump-ipa-sra" } */
 
 static int
 __attribute__((noinline))
@@ -61,7 +61,5 @@ void caller (void)
   return;
 }
 
-/* { dg-final { scan-tree-dump "About to replace expr \\*i_.*D. with ISRA" "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump "About to replace expr \\*l_.*D. with ISRA" "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump-times "About to replace expr \*j_.*D. with ISRA" 0 "eipa_sra"  } } */
-/* { dg-final { scan-tree-dump-times "About to replace expr \*k_.*D. with ISRA" 0 "eipa_sra"  } } */
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 2 "sra"  } } */
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
index 3310a6df2e7..8a7568119b1 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+/* { dg-options "-O2 -fipa-sra -fdump-ipa-sra" } */
 
 static int *
 __attribute__((noinline,used))
@@ -16,4 +16,4 @@ int *caller (void)
 
   return ox (&a, &b);
 }
-/* { dg-final { scan-tree-dump-times "base: j, remove_param" 0 "eipa_sra"  } } */
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 0 "sra"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c
index 89909f03307..47beb84c5bf 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c
@@ -1,7 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-slim"  } */
+/* { dg-options "-O2 -fipa-sra"  } */
 /* { dg-require-effective-target non_strict_align } */
 
+/* Functionality no longer available with IPA IPA-SRA.  Test should be removed
+   altogether when committing the branch to trunk.  */
+
 struct bovid
 {
   float a;
@@ -30,4 +33,3 @@ int main (int argc, char *argv[])
   return foo (&cow, 0);
 }
 
-/* { dg-final { scan-tree-dump-times "foo " 1 "eipa_sra"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipacost-2.c b/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
index 43f01147091..e0501db1ae5 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining -fdump-tree-optimized -fno-ipa-icf"  } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining -fno-ipa-sra -fdump-tree-optimized -fno-ipa-icf"  } */
 /* { dg-add-options bind_pic_locally } */
 
 int array[100];
@@ -72,7 +72,7 @@ main()
 }
 
 /* { dg-final { scan-ipa-dump-times "Creating a specialized node of i_can_be_propagated_fully2" 1 "cp"  } } */
-/* { dg-final { scan-ipa-dump-times "Creating a specialized node of i_can_be_propagated_fully/" 1 "cp"  } } */
+/* { dg-final { scan-ipa-dump-times "Creating a specialized node of i_can_be_propagated_fully\[./\]" 1 "cp"  } } */
 /* { dg-final { scan-ipa-dump-not "Creating a specialized node of i_can_not_be_propagated_fully2" "cp"  } } */
 /* { dg-final { scan-ipa-dump-not "Creating a specialized node of i_can_not_be_propagated_fully/" "cp"  } } */
 /* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully \\(" "optimized"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c
index 2005a10dc15..c69a285b287 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c
@@ -1,6 +1,6 @@
 /* Verify that IPA-CP can make edges direct based on aggregate contents.  */
 /* { dg-do compile } */
-/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-cp -fdump-ipa-inline"  } */
+/* { dg-options "-O3 -fno-early-inlining -fno-ipa-sra -fdump-ipa-cp -fdump-ipa-inline"  } */
 
 struct S
 {
diff --git a/gcc/testsuite/gcc.dg/ipa/pr78121.c b/gcc/testsuite/gcc.dg/ipa/pr78121.c
index 4a0ae187256..19d6eda22f8 100644
--- a/gcc/testsuite/gcc.dg/ipa/pr78121.c
+++ b/gcc/testsuite/gcc.dg/ipa/pr78121.c
@@ -13,4 +13,4 @@ static void fn1(c) unsigned char c;
 
 void fn3() { fn1 (267); }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[11, 35\\\]" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[11, 35\\\]" "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp1.c b/gcc/testsuite/gcc.dg/ipa/vrp1.c
index 72a3139851c..e32a13c3d6a 100644
--- a/gcc/testsuite/gcc.dg/ipa/vrp1.c
+++ b/gcc/testsuite/gcc.dg/ipa/vrp1.c
@@ -28,5 +28,5 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\\[6," "cp" } } */
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\\[0, 999\\\]" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[6," "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[0, 999\\\]" "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp2.c b/gcc/testsuite/gcc.dg/ipa/vrp2.c
index c720e5ce8d4..31909bdbf24 100644
--- a/gcc/testsuite/gcc.dg/ipa/vrp2.c
+++ b/gcc/testsuite/gcc.dg/ipa/vrp2.c
@@ -31,5 +31,5 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\\[4," "cp" } } */
-/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\\[0, 11\\\]" "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[4," "cp" } } */
+/* { dg-final { scan-ipa-dump "Setting value range of param 0 \\(now 0\\) \\\[0, 11\\\]" "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp3.c b/gcc/testsuite/gcc.dg/ipa/vrp3.c
index fb5d54aca82..9b1dcf98b25 100644
--- a/gcc/testsuite/gcc.dg/ipa/vrp3.c
+++ b/gcc/testsuite/gcc.dg/ipa/vrp3.c
@@ -27,4 +27,4 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[0, 9\\\]" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) \\\[0, 9\\\]" 2 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp7.c b/gcc/testsuite/gcc.dg/ipa/vrp7.c
index e4e0bc66a64..ca5aa29e975 100644
--- a/gcc/testsuite/gcc.dg/ipa/vrp7.c
+++ b/gcc/testsuite/gcc.dg/ipa/vrp7.c
@@ -29,4 +29,4 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[-10, 9\\\]" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) \\\[-10, 9\\\]" 1 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp8.c b/gcc/testsuite/gcc.dg/ipa/vrp8.c
index 55832b0886e..0ac5fb5277d 100644
--- a/gcc/testsuite/gcc.dg/ipa/vrp8.c
+++ b/gcc/testsuite/gcc.dg/ipa/vrp8.c
@@ -39,4 +39,4 @@ main ()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[-10, 9\\\]" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\(now 0\\) \\\[-10, 9\\\]" 1 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/noreorder.c b/gcc/testsuite/gcc.dg/noreorder.c
index 7d40a2958a4..e413b689dd6 100644
--- a/gcc/testsuite/gcc.dg/noreorder.c
+++ b/gcc/testsuite/gcc.dg/noreorder.c
@@ -13,7 +13,7 @@ static int func2(void);
 
 asm("firstasm");
 
-NOREORDER __attribute__((noinline)) int bozo(void)
+NOREORDER __attribute__((noipa)) int bozo(void)
 {
   f2(3);
   func2();
@@ -21,14 +21,14 @@ NOREORDER __attribute__((noinline)) int bozo(void)
 
 asm("jukjuk");
 
-NOREORDER __attribute__((noinline)) static int func1(void)
+NOREORDER __attribute__((noipa)) static int func1(void)
 {
   f2(1);
 }
 
 asm("barbar");
 
-NOREORDER __attribute__((noinline)) static int func2(void)
+NOREORDER __attribute__((noipa)) static int func2(void)
 {
   func1();
 }
diff --git a/gcc/testsuite/gcc.dg/sso/ipa-sra-1.c b/gcc/testsuite/gcc.dg/sso/ipa-sra-1.c
new file mode 100644
index 00000000000..6712141dd16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sso/ipa-sra-1.c
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-sra" } */
+
+
+struct __attribute__((scalar_storage_order("little-endian"))) LE
+{
+  int i;
+  int j;
+};
+
+struct __attribute__((scalar_storage_order("big-endian"))) BE
+{
+  int i;
+  int j;
+};
+
+struct LE gle;
+struct BE gbe;
+
+#define VAL 0x12345678
+
+void __attribute__((noipa))
+fill (void)
+{
+  gle.i = VAL;
+  gle.j = 0xdeadbeef;
+  gbe.i = VAL;
+  gbe.j = 0x11223344;
+}
+
+static int __attribute__((noinline))
+readLE (struct LE p)
+{
+  return p.i;
+}
+
+static int __attribute__((noinline))
+readBE (struct BE p)
+{
+  return p.i;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int r;
+  fill ();
+
+  r = readLE (gle);
+  if (r != VAL)
+    __builtin_abort ();
+  r = readBE (gbe);
+  if (r != VAL)
+    __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
index 61878b79313..56b7f9fac90 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
@@ -14,7 +14,7 @@ very_long_function(int a)
 int
 blah ()
 {
-  very_long_function (1);
+  return very_long_function (1);
 }
 /* One appearance for dump, one self recursive call and one call from main.  */
 /* { dg-final { scan-tree-dump-times "very_long_function.constprop \\(\\)" 3 "optimized"} } */
