summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/ipa
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/gcc.dg/ipa
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/gcc.dg/ipa')
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-3.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-2.c28
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-3.c35
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-4.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-5.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-6.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-7.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-8.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c50
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c36
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-12.c34
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c62
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c32
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-15.c32
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c28
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-7.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-8.c31
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-9.c17
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c53
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c68
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c34
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa.exp35
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipacost-1.c61
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipacost-2.c65
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-ii-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/ipa/noclone-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr42706.c27
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr45644.c35
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr48195.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pure-const-1.c80
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pure-const-2.c30
44 files changed, 1561 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c b/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c
new file mode 100644
index 000000000..9cd2b09fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-whole-program" } */
+static __attribute__((constructor))
+void empty_constructor()
+{
+}
+/* { dg-final { scan-ipa-dump "Reclaiming functions: empty_constructor" "whole-program" } } */
+/* { dg-final { cleanup-ipa-dump "whole-program" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-1.c b/gcc/testsuite/gcc.dg/ipa/iinline-1.c
new file mode 100644
index 000000000..617c48499
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-1.c
@@ -0,0 +1,26 @@
+/* Verify that simple indirect calls are inlined even without early
+ inlining.. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining" } */
+
+extern void non_existent(int);
+
+static void hooray ()
+{
+ non_existent (1);
+}
+
+static void hiphip (void (*f)())
+{
+ non_existent (2);
+ f ();
+}
+
+int test (void)
+{
+ hiphip (hooray);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in test" "inline" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-2.c b/gcc/testsuite/gcc.dg/ipa/iinline-2.c
new file mode 100644
index 000000000..117818d16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-2.c
@@ -0,0 +1,41 @@
+/* Verify that simple indirect calls are inlined even without early
+ inlining.. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */
+
+extern void non_existent(int);
+
+int __attribute__ ((noinline,noclone)) get_input(void)
+{
+ return 1;
+}
+
+static void hooray ()
+{
+ non_existent (1);
+}
+
+static void hip2 (void (*g)())
+{
+ non_existent (2);
+ g ();
+}
+
+static void hip1 (void (*f)(void (*)()), void (*g)())
+{
+ non_existent (2);
+ f (g);
+}
+
+int main (int argc, int *argv[])
+{
+ int i;
+
+ for (i = 0; i < get_input (); i++)
+ hip1 (hip2, hooray);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in main" "inline" } } */
+/* { dg-final { scan-ipa-dump "hip2\[^\\n\]*inline copy in main" "inline" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-3.c b/gcc/testsuite/gcc.dg/ipa/iinline-3.c
new file mode 100644
index 000000000..b39957162
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-3.c
@@ -0,0 +1,33 @@
+/* Verify that call declarations are not redirected according to indirect
+ inlining edges too early. */
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-early-inlining" } */
+
+extern void abort (void);
+
+int bar (int k)
+{
+ return k+2;
+}
+
+int baz (int k)
+{
+ return k+1;
+}
+
+static int foo (int (*p)(int), int i)
+{
+ return p (i+1);
+}
+
+int (*g)(int) = baz;
+
+int main (int argc, char *argv[])
+{
+ if (foo (bar, 0) != 3)
+ abort ();
+ if (foo (g, 1) != 3)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-1.c
new file mode 100644
index 000000000..e3212853c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+#include <stdio.h>
+int g (int b, int c)
+{
+ printf ("%d %d\n", b, c);
+}
+int f (int a)
+{
+ /* Second parameter of g gets different values. */
+ if (a > 0)
+ g (a, 3);
+ else
+ g (a, 5);
+}
+int main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f (7);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-2.c
new file mode 100644
index 000000000..1d57fb008
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+#include <stdio.h>
+int g (int b, int c)
+{
+ printf ("%d %d\n", b, c);
+}
+int f (int a)
+{
+ /* a is modified. */
+ if (a++ > 0)
+ g (a, 3);
+}
+int main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f (7);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-3.c
new file mode 100644
index 000000000..a3334c345
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-3.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+
+/* Double constants. */
+
+#include <stdio.h>
+void t(void);
+int g (double b, double c)
+{
+ t();
+ return (int)(b+c);
+}
+int f (double a)
+{
+ if (a > 0)
+ g (a, 3.1);
+ else
+ g (a, 3.1);
+}
+int main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f (7.44);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-4.c
new file mode 100644
index 000000000..3cb0cd4d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-4.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+#include <stdio.h>
+int g (int b, int c)
+{
+ printf ("%d %d\n", b, c);
+}
+int f (int a)
+{
+ /* First and second parameter of g gets different values. */
+
+ if (a > 0)
+ g (a, 3);
+ else
+ g (a+1, 5);
+}
+int main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f (7);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "replacing param a with const 7" 1 "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-5.c
new file mode 100644
index 000000000..50af18e2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-5.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+/* Float & short constants. */
+
+#include <stdio.h>
+void t(void);
+int g (float b, short c)
+{
+ t();
+ return c + (int)b;
+}
+int f (float a)
+{
+ t();
+ /* a is modified. */
+ if (a++ > 0)
+ g (a, 3);
+}
+int main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f (7.6);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-6.c b/gcc/testsuite/gcc.dg/ipa/ipa-6.c
new file mode 100644
index 000000000..c7d9b3738
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-6.c
@@ -0,0 +1,33 @@
+/* PR middle-end/29122 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fno-early-inlining" } */
+
+int
+dont_inline (int);
+
+int
+bar (int b, int c)
+{
+ return dont_inline (c);
+}
+
+int
+foo (int a)
+{
+ if (a++ > 0)
+ bar (a, 3);
+
+ foo (7);
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ foo (7);
+ return 0;
+}
+
+
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-7.c
new file mode 100644
index 000000000..6dcc914c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-7.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+#include <stdio.h>
+void send_addr (int *);
+int g (int b, int c)
+{
+ printf ("%d %d\n", b, c);
+}
+int f (int a)
+{
+ if (a > 0)
+ g (a, 3);
+ else
+ g (a, 5);
+
+ send_addr (&a);
+}
+int main ()
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f (7);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "replacing param a with const 7" 1 "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-8.c
new file mode 100644
index 000000000..edea7f900
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-8.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+/* { dg-add-options bind_pic_locally } */
+
+#include <stdio.h>
+static int g (int b, int c)
+{
+ printf ("%d %d\n", b, c);
+}
+static int f (int a)
+{
+ /* Second parameter of g gets different values. */
+ if (a > 0)
+ g (a, 3);
+ else
+ g (a, 5);
+}
+int main ()
+{
+ f (7);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c
new file mode 100644
index 000000000..a56e71a4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-options "-O -fipa-pta -fdump-ipa-pta-details" } */
+
+static int __attribute__((noinline))
+foo (int *p, int *q)
+{
+ *p = 2;
+ *q = 1;
+ return *p;
+}
+
+static int __attribute__((noinline))
+bar (int *p, int *q)
+{
+ *p = -2;
+ *q = -1;
+ return *p;
+}
+
+static int __attribute__((noinline,noclone))
+foobar (int foo_p)
+{
+ int a;
+ int (*fn)(int *, int *);
+ if (foo_p)
+ fn = foo;
+ else
+ fn = bar;
+ return (*fn)(&a, &a);
+}
+
+extern void abort (void);
+
+int main()
+{
+ if (foobar (1) != 1)
+ abort ();
+
+ return 0;
+}
+
+/* IPA PTA needs to handle indirect calls properly. Verify that
+ both bar and foo get a (and only a) in their arguments points-to sets. */
+
+/* { dg-final { scan-ipa-dump "fn_1 = { bar foo }" "pta" } } */
+/* { dg-final { scan-ipa-dump "bar.arg0 = { a }" "pta" } } */
+/* { dg-final { scan-ipa-dump "bar.arg1 = { a }" "pta" } } */
+/* { dg-final { scan-ipa-dump "foo.arg0 = { a }" "pta" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = { a }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c
new file mode 100644
index 000000000..81a3c53bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details" } */
+
+#include <stdarg.h>
+
+static void __attribute__((noinline,noclone))
+foo (int i, ...)
+{
+ va_list ap;
+ int *p;
+ va_start (ap, i);
+ p = va_arg (ap, int *);
+ *p = 1;
+ va_end (ap);
+}
+extern void abort (void);
+int main()
+{
+ int i = 0;
+ foo (0, &i);
+ if (i != 1)
+ abort ();
+ return 0;
+}
+
+/* Verify we properly handle variadic arguments and do not let escape
+ stuff through it. */
+
+/* { dg-final { scan-ipa-dump "ESCAPED = { (ESCAPED )?(NONLOCAL )?}" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
new file mode 100644
index 000000000..dadb16676
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
@@ -0,0 +1,36 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details" } */
+
+static int i;
+/* i should not escape here, p should point to i only. */
+/* { dg-final { scan-ipa-dump "p = { i }" "pta" } } */
+static int *p = &i;
+
+int j;
+/* q should point to j only. */
+/* { dg-final { scan-ipa-dump "q = { j }" "pta" } } */
+static int *q = &j;
+
+static int k;
+/* k should escape here, r should point to NONLOCAL, ESCAPED, k. */
+int *r = &k;
+/* { dg-final { scan-ipa-dump "r = { ESCAPED NONLOCAL k }" "pta" } } */
+
+int l;
+/* s should point to NONLOCAL, ESCAPED, l. */
+int *s = &l;
+/* { dg-final { scan-ipa-dump "s = { ESCAPED NONLOCAL l }" "pta" } } */
+
+/* Make p and q referenced so they do not get optimized out. */
+int foo() { return &p < &q; }
+
+int main()
+{
+ return 0;
+}
+
+/* It isn't clear if the escape if l is strictly necessary, if it were
+ we should have i, r and s in ESCAPED as well. */
+
+/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL l k }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-12.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-12.c
new file mode 100644
index 000000000..1c773eed0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-12.c
@@ -0,0 +1,34 @@
+static int i, j;
+
+static void __attribute__((noinline,noclone))
+foo (void) { i = 1; }
+
+static void __attribute__((noinline,noclone))
+bar (void) { j = 1; }
+
+typedef void (*fn_t)(void);
+void escapeme (fn_t);
+fn_t getme (void);
+
+extern void link_error (void);
+
+int main()
+{
+ fn_t fn;
+ escapeme (foo);
+ fn = getme();
+
+ i = 0;
+ fn();
+ if (i != 1)
+ return 100;
+ j = 0;
+ fn();
+ if (j != 0)
+ link_error ();
+ bar();
+ if (j != 1)
+ return 200;
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
new file mode 100644
index 000000000..1e04bfc21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
@@ -0,0 +1,62 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details -fdump-tree-fre" } */
+
+static int x, y;
+
+static __attribute__((noinline,noclone)) void
+local (int *p)
+{
+ *p = 1;
+}
+
+static __attribute__((noinline,noclone)) void
+local_address_taken (int *p)
+{
+ *p = 1;
+}
+
+void *anyfn_global;
+
+/* Even though not referenced in this TU we should have added constraints
+ for the initializer. */
+/* { dg-final { scan-ipa-dump "ex = &local_address_taken" "pta" } } */
+void (*ex)(int *) = local_address_taken;
+
+extern void link_error (void);
+
+int main()
+{
+ void (*anyfn)(int *) = (void (*)(int *))(__SIZE_TYPE__)anyfn_global;
+ /* The following should cause local_address_taken to get &x
+ as argument, but not local. We shouldn't get &x added to
+ arbitrary special sub-vars of local_address_taken though,
+ a missed optimization currently.
+ As local_address_taken escapes the translation unit its
+ argument points-to set needs to include ESCAPED and NONLOCAL.
+ We shouldn't get the functions sub-vars in the ESCAPED solution
+ though, another missed-optimization. This also causes the functions
+ uses to be messed up even further. */
+ /* ??? As we don't expand the ESCAPED solution we either get x printed here
+ or not based on the phase of the moon. */
+ /* { dg-final { scan-ipa-dump "local_address_taken.arg0 = { ESCAPED NONLOCAL y x }" "pta" { xfail *-*-* } } } */
+ /* { dg-final { scan-ipa-dump "local_address_taken.clobber = { ESCAPED NONLOCAL y x }" "pta" { xfail *-*-* } } } */
+ /* { dg-final { scan-ipa-dump "local_address_taken.use = { }" "pta" { xfail *-*-* } } } */
+ /* ??? But make sure x really escaped. */
+ /* { dg-final { scan-ipa-dump "ESCAPED = {\[^\n\}\]* x \[^\n\}\]*}" "pta" } } */
+ (*anyfn) (&x);
+ x = 0;
+ local (&y);
+ /* Thus we should be able to disambiguate x against the call to local
+ and CSE the stored value. */
+ if (x != 0)
+ link_error ();
+ x = 1;
+ local_address_taken (&y);
+ /* As we are computing flow- and context-insensitive we may not
+ CSE the load of x here. */
+ /* { dg-final { scan-tree-dump " = x;" "fre" } } */
+ return x;
+}
+
+/* { dg-final { cleanup-ipa-dump "pta" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
new file mode 100644
index 000000000..074f44a6d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fno-tree-sra -fdump-ipa-pta-details" } */
+
+struct X {
+ int i;
+ void *p;
+};
+
+static void * __attribute__((noinline,noclone))
+foo(struct X *q, void *p)
+{
+ struct X b;
+ b.p = p;
+ *q = b;
+ return q->p;
+}
+extern void abort (void);
+int main()
+{
+ struct X a, c;
+ void *p;
+ a.p = (void *)&c;
+ p = foo(&a, &a);
+ /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* c\[^ \]* }" "pta" { xfail *-*-* } } } */
+ /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" } } */
+ ((struct X *)p)->p = (void *)0;
+ if (a.p != (void *)0)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-15.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-15.c
new file mode 100644
index 000000000..77701ebd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-15.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta" } */
+
+struct Foo {
+ int *p;
+ int *q;
+};
+
+void __attribute__((noinline))
+bar (int **x)
+{
+ struct Foo *f = (struct Foo *)(x - 1);
+ *(f->p) = 0;
+}
+
+int foo(void)
+{
+ struct Foo f;
+ int i = 1, j = 2;
+ f.p = &i;
+ f.q = &j;
+ bar(&f.q);
+ return i;
+}
+
+extern void abort (void);
+int main()
+{
+ if (foo () != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c
new file mode 100644
index 000000000..ef4182632
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-sra -fipa-pta -fdump-ipa-pta" } */
+
+struct X
+{
+ long l1;
+ struct Y
+ {
+ long l2;
+ int *p;
+ } y;
+};
+int i;
+static int __attribute__((noinline))
+foo (struct X *x)
+{
+ struct Y y = x->y;
+ *y.p = 0;
+ i = 1;
+ return *y.p;
+}
+extern void abort (void);
+int main()
+{
+ struct X x;
+ x.y.p = &i;
+ if (foo(&x) != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "y.\[0-9\]*\\\+\[0-9\]* = { i }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c
new file mode 100644
index 000000000..a6c7e4b47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fipa-pta -fdump-ipa-pta-details" } */
+
+int (*fn)(int *);
+
+static int __attribute__((noinline,noclone))
+foo (int *p)
+{
+ return *p;
+}
+
+extern void bar (void);
+
+int main()
+{
+ fn = foo;
+ bar ();
+ return 0;
+}
+
+/* Make sure that when a local function escapes its argument points-to sets
+ are properly adjusted. */
+
+/* { dg-final { scan-ipa-dump "foo.arg0 = { ESCAPED NONLOCAL }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c
new file mode 100644
index 000000000..e73db1c95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details -fdump-tree-fre-details" } */
+
+static int __attribute__((noinline,noclone))
+foo (int *p, int *q)
+{
+ *p = 1;
+ *q = 0;
+ return *p;
+}
+
+extern void abort (void);
+
+int main()
+{
+ int a, b;
+ if (foo (&a, &b) != 1)
+ abort ();
+ return 0;
+}
+
+/* Verify we can disambiguate *p and *q in foo. */
+
+/* { dg-final { scan-ipa-dump "foo.arg0 = &a" "pta" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = &b" "pta" } } */
+/* { dg-final { scan-tree-dump "Replaced \\\*p_1\\\(D\\\) with 1" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c
new file mode 100644
index 000000000..d2b901cf9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details -fdump-tree-fre-details" } */
+
+int a, b;
+
+static int __attribute__((noinline,noclone))
+foo (int *p, int *q)
+{
+ int res;
+ *p = 1;
+ *q = 0;
+ res = *p;
+ a = 1;
+ b = 1;
+ return res;
+}
+
+extern void abort (void);
+
+int main()
+{
+ if (foo (&a, &b) != 1)
+ abort ();
+ return 0;
+}
+
+/* Verify we can disambiguate *p and *q in foo. */
+
+/* { dg-final { scan-ipa-dump "foo.arg0 = &a" "pta" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = &b" "pta" } } */
+/* { dg-final { scan-tree-dump "Replaced \\\*p_1\\\(D\\\) with 1" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c
new file mode 100644
index 000000000..3359c534a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details" } */
+
+int **x;
+
+static int __attribute__((noinline,noclone))
+foo (int **q)
+{
+ int a = 1;
+ **q = 0;
+ *x = &a;
+ return **q;
+}
+
+extern void abort (void);
+int main()
+{
+ int b;
+ int *p = &b;
+ x = &p;
+ if (foo (&p) != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c
new file mode 100644
index 000000000..aaa6090dd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-O -fipa-pta -fdump-ipa-pta-details" } */
+
+static void __attribute__((noinline,noclone))
+foo (int *p)
+{
+ *p = 1;
+}
+
+extern void abort (void);
+
+int main()
+{
+ int i = 0;
+ foo (&i);
+ if (i != 1)
+ abort ();
+ return 0;
+}
+
+/* Verify we correctly compute the units ESCAPED set as empty but
+ still properly account for the store via *p in foo. */
+
+/* { dg-final { scan-ipa-dump "ESCAPED = { }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-7.c
new file mode 100644
index 000000000..3cdfd63fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-7.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-early-inlining -fipa-pta" } */
+
+static void __attribute__((noinline,noclone))
+clobber_me (int *p, int how)
+{
+ *p = how;
+}
+
+/* When foo is inlined into main we have to make sure to adjust
+ main()s IPA CLOBBERED set according to the decl remappings
+ inlining does. */
+
+static int
+foo (void)
+{
+ int a = 0;
+ clobber_me (&a, 1);
+ return a;
+}
+
+extern void abort (void);
+
+int main()
+{
+ if (foo () != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-8.c
new file mode 100644
index 000000000..5bedc9d8a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-8.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-early-inlining -fipa-pta" } */
+
+static int *__attribute__((noinline,noclone))
+pass_me (int *p)
+{
+ return p;
+}
+
+/* When foo is inlined into main we have to make sure to adjust
+ main()s IPA CLOBBERED set according to the decl remappings
+ inlining does. */
+
+static int
+foo (void)
+{
+ int a = 0;
+ int *p = pass_me (&a);
+ *p = 1;
+ return a;
+}
+
+extern void abort (void);
+
+int main()
+{
+ if (foo () != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-9.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-9.c
new file mode 100644
index 000000000..1a98da397
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-9.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta" } */
+
+static void __attribute__((noinline,noclone))
+foo (int *p, int *q)
+{
+ __builtin_memcpy (p, q, sizeof (int));
+}
+extern void abort (void);
+int main()
+{
+ int i = 0, j = 1;
+ foo (&i, &j);
+ if (i != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
new file mode 100644
index 000000000..2c05347c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+extern int printf (const char *, ...);
+extern void abort (void);
+
+static int
+__attribute__((noinline))
+ox (struct bovid cow)
+{
+ if (cow.green != 6)
+ abort ();
+
+ printf ("green: %f\nblue: %p\nblue again: %p\n", cow.green,
+ cow.blue, cow.blue);
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct bovid cow;
+
+ cow.red = 7.4;
+ cow.green = 6;
+ cow.blue = &cow;
+
+ ox (cow);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "About to replace expr" 2 "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
new file mode 100644
index 000000000..c6b4d63aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+/* { dg-require-effective-target non_strict_align } */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+static int
+__attribute__((noinline))
+ox (struct bovid *cow)
+{
+ cow->red = cow->red + cow->green + cow->green;
+ return 0;
+}
+
+int something;
+
+static int
+__attribute__((noinline))
+ox_improved (struct bovid *calf)
+{
+ if (something > 0)
+ calf->red = calf->red + calf->green;
+ else
+ calf->red = calf->green + 87;
+ something = 77;
+ return 0;
+}
+
+
+int main (int argc, char *argv[])
+{
+ struct bovid cow;
+
+ cow.red = 7.4;
+ cow.green = 6;
+ cow.blue = &cow;
+
+ ox (&cow);
+
+ ox_improved (&cow);
+ 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" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
new file mode 100644
index 000000000..ac078c22d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+extern void foo (float, void *, void *, long);
+
+static int
+__attribute__((noinline))
+ox (struct bovid cow, int z, struct bovid calf, long l)
+{
+ foo (cow.red, cow.blue, cow.blue, l);
+ return 0;
+}
+
+void caller (void)
+{
+ struct bovid cow, calf;
+
+ cow.red = 7.4;
+ cow.green = 6;
+ cow.blue = &cow;
+
+ calf.red = 8.4;
+ calf.green = 5;
+ calf.blue = &cow;
+
+ ox (cow,4,calf,2);
+ 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 { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
new file mode 100644
index 000000000..f07706b92
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+
+static int
+__attribute__((noinline))
+ox (int *i)
+{
+ return *i+4**i;
+}
+
+int *holder;
+
+static int
+__attribute__((noinline))
+ox_ctrl_1 (int *j)
+{
+ holder = j;
+ return *j+4 * *j+1;
+}
+
+static void
+__attribute__((noinline))
+ox_ctrl_2 (int *k)
+{
+ *k = 8;
+}
+
+static int zzz[10];
+
+static int
+__attribute__((noinline))
+ox_improved (int recurse, int *l)
+{
+ int r = 0;
+
+ r = *l;
+
+ if (recurse)
+ {
+ if (recurse > 2)
+ l = &zzz[3];
+ else
+ l = zzz;
+
+ ox_improved (0, l);
+ }
+
+ return r;
+}
+
+void caller (void)
+{
+ int a = 1;
+ int b = 10;
+ int c;
+
+ ox (&a);
+ ox_ctrl_1 (&a);
+ ox_ctrl_2 (&a);
+ *holder = ox_improved (1, &b);
+ 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 { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
new file mode 100644
index 000000000..2fe4ee741
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */
+
+static int *
+__attribute__((noinline,used))
+ ox (int *i, int *j)
+{
+ return i;
+}
+
+int a;
+
+int *caller (void)
+{
+ int b = 10;
+
+ return ox (&a, &b);
+}
+/* { dg-final { scan-tree-dump-times "base: j, remove_param" 0 "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c
new file mode 100644
index 000000000..487e72ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-slim" } */
+/* { dg-require-effective-target non_strict_align } */
+
+struct bovid
+{
+ float a;
+ int b;
+ struct bovid *next;
+};
+
+static int
+__attribute__((noinline))
+foo (struct bovid *cow, int i)
+{
+ i++;
+ if (cow->next)
+ foo (cow->next, i);
+ return i;
+}
+
+int main (int argc, char *argv[])
+{
+ struct bovid cow;
+
+ cow.a = 7.4;
+ cow.b = 6;
+ cow.next = (struct bovid *) 0;
+
+ return foo (&cow, 0);
+}
+
+/* { dg-final { scan-tree-dump-times "foo " 1 "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa.exp b/gcc/testsuite/gcc.dg/ipa/ipa.exp
new file mode 100644
index 000000000..1bbfee7cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 1997, 2004, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/ipa/ipacost-1.c b/gcc/testsuite/gcc.dg/ipa/ipacost-1.c
new file mode 100644
index 000000000..d91546899
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipacost-1.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fipa-cp -fdump-ipa-cp -fno-early-inlining -fdump-tree-optimized" } */
+
+int array[100];
+
+int t(int);
+
+static int
+i_can_be_propagated_fully (int *a)
+{
+ int i;
+ for (i=0;i<50;i++)
+ {
+ t(a[i]);
+ t(a[i+1]);
+ t(a[i+2]);
+ t(a[i+3]);
+ }
+}
+static int
+i_can_be_propagated_fully2 (int *a)
+{
+ i_can_be_propagated_fully (a);
+ i_can_be_propagated_fully (a);
+ i_can_be_propagated_fully (a);
+}
+static int
+i_can_not_be_propagated_fully (int *a)
+{
+ int i;
+ for (i=0;i<50;i++)
+ {
+ t(a[i]);
+ t(a[i+1]);
+ t(a[i+2]);
+ t(a[i+3]);
+ }
+}
+int
+i_can_not_be_propagated_fully2 (int *a)
+{
+ i_can_not_be_propagated_fully (a);
+ i_can_not_be_propagated_fully (a);
+ i_can_not_be_propagated_fully (a);
+}
+main()
+{
+ i_can_be_propagated_fully2 (array);
+ i_can_be_propagated_fully2 (array);
+ i_can_not_be_propagated_fully2 (array);
+ i_can_not_be_propagated_fully2 (array);
+}
+
+/* { dg-final { scan-ipa-dump-times "versioned function i_can_be_propagated_fully2" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "versioned function i_can_be_propagated_fully " 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-not "versioned function i_can_not_be_propagated_fully2" "cp" } } */
+/* { dg-final { scan-ipa-dump-not "versioned function i_can_not_be_propagated_fully " "cp" } } */
+/* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully2 " "optimized" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipacost-2.c b/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
new file mode 100644
index 000000000..6ebd6d374
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining -fdump-tree-optimized" } */
+/* { dg-add-options bind_pic_locally } */
+
+int array[100];
+
+int t(int);
+
+static int
+i_can_be_propagated_fully (int *a)
+{
+ int i;
+ for (i=0;i<50;i++)
+ {
+ t(a[i]);
+ t(a[i+1]);
+ t(a[i+2]);
+ t(a[i+3]);
+ }
+}
+static int
+i_can_be_propagated_fully2 (int *a)
+{
+ i_can_be_propagated_fully (a);
+ i_can_be_propagated_fully (a);
+ i_can_be_propagated_fully (a);
+}
+static int
+i_can_not_be_propagated_fully (int *a)
+{
+ int i;
+ for (i=0;i<50;i++)
+ {
+ t(a[i]);
+ t(a[i+1]);
+ t(a[i+2]);
+ t(a[i+3]);
+ }
+}
+int
+i_can_not_be_propagated_fully2 (int *a)
+{
+ i_can_not_be_propagated_fully (a);
+ i_can_not_be_propagated_fully (a);
+ i_can_not_be_propagated_fully (a);
+}
+main()
+{
+ int i;
+ i_can_be_propagated_fully2 (array);
+ i_can_be_propagated_fully2 (array);
+
+ for (i = 0; i < 100; i++)
+ i_can_not_be_propagated_fully2 (array);
+ i_can_not_be_propagated_fully2 (array);
+}
+
+/* { dg-final { scan-ipa-dump-times "versioned function i_can_be_propagated_fully2" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "versioned function i_can_be_propagated_fully " 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "versioned function i_can_not_be_propagated_fully2" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "versioned function i_can_not_be_propagated_fully " 1 "cp" } } */
+/* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully \\(" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully2 \\(" "optimized" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-ii-1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-ii-1.c
new file mode 100644
index 000000000..9caa54beb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-ii-1.c
@@ -0,0 +1,34 @@
+/* Verify that simple indirect calls are inlined even without early
+ inlining.. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining" } */
+
+extern void non_existent(int);
+extern void non_existent(int);
+
+static void hooray ()
+{
+ non_existent (1);
+}
+
+static void __attribute__ ((noinline)) hiphip (void (*f)())
+{
+ f ();
+}
+
+int __attribute__ ((noinline,noclone)) get_input(void)
+{
+ return 1;
+}
+
+int main (int argc, int *argv[])
+{
+ int i;
+
+ for (i = 0; i < get_input (); i++)
+ hiphip (hooray);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in hiphip.constprop" "inline" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/noclone-1.c b/gcc/testsuite/gcc.dg/ipa/noclone-1.c
new file mode 100644
index 000000000..118df3a00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/noclone-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
+
+int global_1, global_2;
+
+__attribute__((__noclone__)) int g (int b, int c)
+ {
+ global_1 = b;
+ global_2 = c;
+}
+
+__attribute__((__noclone__)) int f (int a)
+{
+ /* Second parameter of g gets different values. */
+ if (a > 0)
+ g (a, 3);
+ else
+ g (a, 5);
+}
+
+int main ()
+{
+ f (7);
+ return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump-times "versioned function" 0 "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr42706.c b/gcc/testsuite/gcc.dg/ipa/pr42706.c
new file mode 100644
index 000000000..9c5f43af3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr42706.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-early-inlining -fipa-sra" } */
+
+struct S
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+extern int gi;
+static int foo ();
+
+int
+bar (void)
+{
+ foo ();
+ return 0;
+}
+
+static int
+foo (struct S s)
+{
+ gi = s.green;
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/ipa/pr45644.c b/gcc/testsuite/gcc.dg/ipa/pr45644.c
new file mode 100644
index 000000000..3f61b8b41
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr45644.c
@@ -0,0 +1,35 @@
+/* Verify that we do not IPA-SRA bitfields. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+struct S
+{
+ int j : 8;
+ int i : 24;
+ int l;
+};
+
+static int __attribute__((noinline)) foo (struct S *s)
+{
+ int z = s->i;
+ if (z != 777)
+ abort ();
+ return 0;
+}
+
+int __attribute__((noinline)) bar (struct S *s)
+{
+ return foo (s);
+}
+
+int main (int argc, char *argv[])
+{
+ struct S s;
+ s.j = 5;
+ s.i = 777;
+ s.l = -1;
+
+ return bar (&s);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr48195.c b/gcc/testsuite/gcc.dg/ipa/pr48195.c
new file mode 100644
index 000000000..2e38452d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr48195.c
@@ -0,0 +1,25 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -flto --param partial-inlining-entry-probability=101" } */
+/* { dg-require-effective-target lto } */
+
+extern void abort(void);
+
+int i;
+
+void __attribute__ ((constructor))
+c2 ()
+{
+ if (i)
+ abort ();
+}
+
+void __attribute__ ((destructor))
+d1 ()
+{
+ if (i)
+ abort ();
+}
+
+void main ()
+{
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c
new file mode 100644
index 000000000..51837ea9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c
@@ -0,0 +1,80 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining" } */
+void abort (void);
+int error_code;
+static int val;
+__attribute__ ((noinline, noclone))
+static int
+i_am_pure1 (int a)
+{
+ if (a > 50)
+ abort ();
+ return a;
+}
+
+__attribute__ ((noinline, noclone))
+static int
+i_am_const2 (int a)
+{
+ return a+val;
+}
+
+__attribute__ ((noinline, noclone))
+int
+call_me(int a)
+{
+ return a;
+}
+
+inline int
+call_callback(int (*fn)(int), int a)
+{
+ return fn(a);
+}
+
+__attribute__ ((noinline, noclone))
+i_am_const3(int a)
+{
+ return call_callback (call_me, a);
+}
+
+__attribute__ ((noinline))
+explode_badly()
+{
+ error_code = 0xbad;
+ abort ();
+}
+
+__attribute__ ((noinline, noclone))
+i_am_pure4(int a)
+{
+ if (a > 50)
+ explode_badly ();
+ return a;
+}
+
+test()
+{
+ int s;
+ s = i_am_pure1(5);
+ s += i_am_pure1(5);
+ s += i_am_const2(5);
+ s += i_am_const2(5);
+ s += i_am_const3(5);
+ s += i_am_const3(5);
+ s += i_am_pure4(5);
+ s += i_am_pure4(5);
+ return s;
+}
+/* { dg-final { scan-tree-dump-times "i_am_pure1 .5" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "i_am_const2 .5" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "i_am_const3 .5" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "i_am_pure4 .5" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump "found to be looping pure: i_am_pure1" "local-pure-const1"} } */
+/* { dg-final { scan-tree-dump "found to be looping pure: i_am_pure4" "local-pure-const1"} } */
+/* { dg-final { scan-ipa-dump "found to be const: i_am_const2" "pure-const"} } */
+/* { dg-final { scan-ipa-dump "found to be const: i_am_const3" "pure-const"} } */
+/* { dg-final { cleanup-tree-dump "local-pure-const1" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-final { cleanup-ipa-dump "pure-const" } } */
+
diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-2.c b/gcc/testsuite/gcc.dg/ipa/pure-const-2.c
new file mode 100644
index 000000000..2dcca18c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pure-const-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-tree-optimized" } */
+static __attribute__ ((noinline, noclone))
+int i_am_pure(char *c, int n)
+{
+ char *d=__builtin_alloca (n);
+ int i;
+ int sum;
+ for (i=0;i<n;i++)
+ d[i] = c[i];
+ for (i=0;i<n;i++)
+ d[i] *= c[n-i];
+ for (i=0;i<n;i++)
+ sum+=d[i];
+ if (sum)
+ __builtin_unreachable ();
+ return sum;
+}
+char array[11];
+int
+main(void)
+{
+ i_am_pure (array,5);
+ i_am_pure (array,11);
+ return 0;
+}
+/* { dg-final { scan-tree-dump "found to be pure: i_am_pure" "local-pure-const1"} } */
+/* { dg-final { scan-tree-dump-not "i_am_pure" "optimized"} } */
+/* { dg-final { cleanup-tree-dump "local-pure-const1" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */