summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-11-25 14:20:43 +0100
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-11-25 14:26:11 +0100
commitcf54c81ecd07c5ad0cdd81e6b2473faff2141b2e (patch)
treee5533471bb27e7182f836fa0df5a5c67a9ff111f
parentcacc6dfafad4d5ec8e440be9440abe19f2da5c10 (diff)
Add tests
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/ipa-type-escape-analysis.c11
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c40
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c37
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c42
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c37
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c42
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c44
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c38
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c27
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-14-volatile-0.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-15-union-0.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c32
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-03-new-type-0.c21
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-heterogeneous-struct-0.c21
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c21
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-nested-struct-0.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-pointer-struct-0.c31
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-1-prints-structs-0.c19
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-11-rewrites-minus-expr-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-12-delete-last-field-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-13-modify-size-four-0.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-14-rewrite-plus-expr-0.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-15-rewrite-mult-expr-0.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-16-rewrite-field-reads-ptr-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-17-rewrite-field-write-ptr-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-18-field-writes-deref-0.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-19-middle-pointer-equal-0.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-2-modifies-0.c19
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-20-array-offset-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-22-rewrites-addr-expr-read-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-23-array-cast-0.c31
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-25-array-cast-0.c31
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-26-array-cast-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-27-array-cast-0.c21
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-29-heterogeneous-struct.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-30-heterogenous-struct-0.c27
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-31-heterogenous-struct-0.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-nested-struct-0.c39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-pointer-indirection-level-0.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-34-array-cast-0.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-36-arguments-0.c42
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-37-arguments-0.c43
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-38-return-values-0.c39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-39-typedef-0.c21
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-40-typedef-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-41-deref-0.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-42-mem-ref-0.c32
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-43-args-0.c39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-44-cond-0.c16
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-45-phis-0.c16
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-46-static-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-47-constructor-0.c27
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-48-function-ptr-0.c44
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-50-field-write-delete-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-51-creduce-0.c6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-52-creduce-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-53-csmith-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-54-csmith-3.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-55-csmith-4.c9
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-56-csmith-5.c25
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-57-csmith-6.c8
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-58-csmith-7.c15
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-59-csmith-8.c14
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-60-csmith-9.c26
82 files changed, 2063 insertions, 0 deletions
diff --git a/gcc/common.opt b/gcc/common.opt
index 7885d0f5c0c..68315db9a01 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -3472,4 +3472,8 @@ fipa-field-reorder
Common Report Var(flag_ipa_field_reorder) Optimization
Reorder fields.
+fipa-dlo-tests
+Common Report Var(flag_ipa_dlo_tests)
+A flag to make it easier to test
+
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c
index 48d8dc2bcd8..8ccb2991090 100644
--- a/gcc/ipa-type-escape-analysis.c
+++ b/gcc/ipa-type-escape-analysis.c
@@ -2025,6 +2025,7 @@ void
gimple_type_collector::print_collected ()
{
tpartitions_t sets = get_record_reaching_trees ();
+ // TODO: I think previously we were printing info here for tests
}
/* Walk over LHS and RHS of conditions. */
@@ -2833,6 +2834,11 @@ expr_accessor::_walk_ADDR_EXPR_pre (__attribute__ ((unused)) tree e)
field_access_map_t field_map;
field_map = record_already_in_map ? record_field_map[addr_expr_t] : field_map;
+ // UNSAFE! But it is necesseary for testing...
+ // Unless there is someone who is smarter that finds another way to test this.
+ if (flag_ipa_dlo_tests)
+ return;
+
tree field = NULL;
for (field = TYPE_FIELDS (addr_expr_t); field; field = DECL_CHAIN (field))
{
@@ -2921,6 +2927,11 @@ expr_accessor::_walk_COMPONENT_REF_pre (tree e)
* TODO: Maybe add a flag to enable and disable this for debugging and
* testing.
*/
+ // UNSAFE! But it is necesseary for testing...
+ // Unless there is someone who is smarter that finds another way to test this.
+ if (flag_ipa_dlo_tests)
+ return;
+
for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
{
log ("ever inside?\n");
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c
new file mode 100644
index 00000000000..2cab46e6bd3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c
@@ -0,0 +1,22 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct;
+
+int
+main ()
+{
+ printf ("%d\n", astruct.a);
+ printf ("%d\n", astruct.a);
+}
+
+// This means a read.
+/// { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0001" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c
new file mode 100644
index 00000000000..02e9f53c74f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c
@@ -0,0 +1,22 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct;
+
+int
+main ()
+{
+ astruct.a++;
+ astruct.a = 3;
+}
+
+// This means that this is only a write and not a read.
+/// { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0003" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c
new file mode 100644
index 00000000000..dcc0f186951
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c
@@ -0,0 +1,22 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s *astruct = NULL;
+
+int
+main ()
+{
+ printf ("%d\n", astruct->a);
+ printf ("%d\n", astruct->a);
+}
+
+// So, even if we have a pointer COMPONENT_REF counter still works...
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0001" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c
new file mode 100644
index 00000000000..4d2973ce5b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c
@@ -0,0 +1,22 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s *astruct;
+
+int
+main ()
+{
+ astruct->a++;
+ astruct->a = 3;
+}
+
+// This says that only writes are happening even if astruct is a pointer
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0003" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c
new file mode 100644
index 00000000000..6faccf4dc08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c
@@ -0,0 +1,24 @@
+/* { dg-do link } */
+/* { dg-options "-flto -flto-partition=none -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct;
+
+int
+main ()
+{
+ if (astruct.a)
+ {
+ puts ("hello world");
+ }
+}
+
+// This says that astruct_s.a is read in a conditional
+//// { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0001" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c
new file mode 100644
index 00000000000..4c2bbf70bb8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c
@@ -0,0 +1,20 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct;
+
+int
+main ()
+{
+ astruct.a = 0;
+}
+
+// Please note that braces and semicollons are replaced with dots in order
+// to parse correctly
+///// { dg-final { scan-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c.." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c
new file mode 100644
index 00000000000..306edbd7546
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c
@@ -0,0 +1,23 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s *astruct;
+
+int
+main ()
+{
+ astruct = NULL;
+}
+
+// This is for the structure
+/* //// { dg-final { scan-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c.." "type-escape-analysis" } } */
+// This one has an extra dot to mark the * for the pointer
+/* /// { dg-final { scan-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c..." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c
new file mode 100644
index 00000000000..b4eb2c93cb1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c
@@ -0,0 +1,23 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct[2];
+
+int
+main ()
+{
+ struct astruct_s another = astruct[0];
+}
+
+// This one is for the structure
+/// { dg-final { scan-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c.." "type-escape-analysis" } } */
+// This one is for the array. That's why it has two dots at the end. They correspond to []
+/// { dg-final { scan-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c...." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c
new file mode 100644
index 00000000000..1ff8d4bd5ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c
@@ -0,0 +1,26 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct outer_struct
+{
+ _Bool d;
+ struct astruct_s a;
+};
+struct outer_struct bstruct;
+
+int
+main ()
+{
+ bstruct.d = 0;
+}
+
+// We only care about collecting the inner struct for this test
+/// { dg-final { scan-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c.." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c
new file mode 100644
index 00000000000..444eac30274
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c
@@ -0,0 +1,40 @@
+/* { dg-do link } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+
+void
+record_parameter (struct astruct_s a)
+{}
+void
+pointer_parameter (struct astruct_s *a)
+{}
+void
+array_parameter (struct astruct_s a[])
+{}
+
+int
+main ()
+{}
+
+// We have a complete type, probably from record_parameter
+/// { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c.." "type-escape-analysis" } } */
+// Now we have an incomplete struct
+/// { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .." "type-escape-analysis" } } */
+// This is the pointer...
+/// { dg-final { scan-wpa-ipa-dump "collected: record astruct_s ..." "type-escape-analysis" } } */
+// We are missing the array parameter
+// But it seems that the array parameter is passed as a pointer, which makes
+// sense... array_parameter (struct astruct_s * a)
+// {
+// <bb 2> :
+// return;
+//
+// }
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c
new file mode 100644
index 00000000000..e1777c087ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c
@@ -0,0 +1,37 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+/* { dg-require-effective-target lto } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+__attribute__ ((
+ externally_visible)) struct astruct_s astruct; // This should escape
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s bstruct; // This should not escape
+
+int
+main ()
+{
+ astruct.a = 0;
+ bstruct.b = 0;
+}
+
+/// { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump "collected: record bstruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */
+// Do we find the externally visible struct?
+// This says that record astruct_s is escaping because the reason g (global is
+// visible) is set to true...
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: e=1 g=1 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
+// This says that record bstruct_s is not escaping
+/// { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: e=0 g=0 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c
new file mode 100644
index 00000000000..e20e6de0dba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c
@@ -0,0 +1,42 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+__attribute__ ((
+ externally_visible)) struct astruct_s astruct; // This should escape
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s bstruct; // This should not escape
+
+int
+main ()
+{
+ astruct.a = 0;
+ bstruct.b = 0;
+}
+
+// This test is pretty much the same as the previous one.
+// The reason for this is because initially the previous
+// test tested the escaping of variables and this one of
+// types. Since, we are now not checking variables escaping
+// these two tests have merged.
+
+/// { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump "collected: record bstruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */
+// Do we find the externally visible struct?
+// This says that record astruct_s is escaping because the reason g (global is
+// visible) is set to true...
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: e=1 g=1 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
+// This says that record bstruct_s is not escaping
+/// { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: e=0 g=0 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c
new file mode 100644
index 00000000000..106ec9ceed8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c
@@ -0,0 +1,37 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+/* { dg-require-effective-target lto } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct; // This should not escape
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s bstruct; // This should not escape
+
+__attribute__ ((externally_visible)) void
+escaping (struct astruct_s cstruct)
+{}
+void
+non_escaping (struct bstruct_s dstruct)
+{}
+
+int
+main ()
+{
+ escaping (astruct);
+ non_escaping (bstruct);
+}
+
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=1 g=0 p=1 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=0 g=0 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c
new file mode 100644
index 00000000000..31bff4abc1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c
@@ -0,0 +1,42 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct; // This should not escape
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s bstruct; // This should not escape
+
+// This will make astruct_s escape
+struct astruct_s __attribute__ ((externally_visible)) escaping ()
+{
+ struct astruct_s a;
+ return a;
+}
+struct bstruct_s
+non_escaping ()
+{}
+
+int
+main ()
+{
+ astruct = escaping ();
+ bstruct = non_escaping ();
+}
+
+// This says that astruct_s escapes because it is returning from an externally
+// visible function
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=1 g=0 p=0 r=1 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
+// This says that bstruct_s does not escape
+/// { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=0 g=0 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c
new file mode 100644
index 00000000000..8cd60279d7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c
@@ -0,0 +1,44 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+};
+
+struct bstruct_s *
+casting_to_void (struct astruct_s *s)
+{
+ return (struct bstruct_s *) (s);
+}
+
+int
+main ()
+{
+ struct astruct_s astruct;
+ struct bstruct_s bstruct;
+ casting_to_void (&astruct);
+}
+
+// The type
+/// { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;boolean_type d;. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
+// The pointer
+/// { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;boolean_type d;.. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s {boolean_type a;boolean_type b;boolean_type c;}* reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
+
+// But there are incomplete types... should does be marked as escaping as well
+// here? No, because at the moment, how we compute it is with the fixed point
+// and at that moment, we get rid of reasons. So, at the moment, it is
+// sufficient to say that only a fraction of equivalent types escape.
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c
new file mode 100644
index 00000000000..2b8c279e0ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c
@@ -0,0 +1,38 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct; // This should not escape
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s bstruct; // This should not escape
+
+void
+casting_to_void (struct astruct_s *s)
+{
+ void *nullify_non_escape = s;
+}
+
+int
+main ()
+{
+ astruct.a = 0;
+ bstruct.b = 0;
+}
+
+/// { dg-final { scan-wpa-ipa-dump "void_type. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
+// base type
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */
+// pointer
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;.. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c
new file mode 100644
index 00000000000..23805359fd7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c
@@ -0,0 +1,27 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ char *filename = "helloworld.txt";
+ FILE *f = fopen (filename, "r");
+ fclose (f);
+}
+
+// This is the incomplete type p=0 because it is memoized and it is an
+// optimization. However, I will also match a 1
+/// { dg-final { scan-wpa-ipa-dump " record _IO_FILE .. reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_FILE ... reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_wide_data .. reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_wide_data ... reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_codecvt .. reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_codecvt ... reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump "void_type. reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_marker .. reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record _IO_marker ... reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
+// This is the complete type... but I have condensed it to match .*
+/// { dg-final { scan-wpa-ipa-dump " record FILE .* reason: e=1 g=0 p=. r=1 c=0 v=0 u=0 i=." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-14-volatile-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-14-volatile-0.c
new file mode 100644
index 00000000000..223cb9e5458
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-14-volatile-0.c
@@ -0,0 +1,20 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ volatile struct astruct_s astruct;
+}
+
+// This says that astruct_s has a volatile
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: e=1 g=0 p=0 r=0 c=0 v=1 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-15-union-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-15-union-0.c
new file mode 100644
index 00000000000..460da72aaca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-15-union-0.c
@@ -0,0 +1,25 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <stddef.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ union outer
+ {
+ struct astruct_s a;
+ double b;
+ };
+ union outer an_outer;
+}
+
+// This says that astruct_s is inside a union
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s {boolean_type a;boolean_type b;boolean_type c;} reason: e=1 g=0 p=0 r=0 c=0 v=0 u=1 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c
new file mode 100644
index 00000000000..149d1fa1dba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c
@@ -0,0 +1,32 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-incompatible-pointer-types -Wno-dfa" } */
+
+#include <stddef.h>
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct bstruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+void
+foo (struct bstruct_s *s){};
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s astruct;
+ foo (&astruct);
+}
+
+// This says that astruct_s is casted
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
+// This says that the pointer is casted
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;.. reason: e=1 g=0 p=0 r=0 c=1 v=0 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c
new file mode 100644
index 00000000000..875f5021653
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c
@@ -0,0 +1,23 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s *a = malloc (sizeof (struct astruct_s));
+}
+
+// This says that astruct_s is not casted
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: e=0 g=0 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
+/// { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;.. reason: e=0 g=0 p=0 r=0 c=0 v=0 u=0 i=0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-03-new-type-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-03-new-type-0.c
new file mode 100644
index 00000000000..2e97584269c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-03-new-type-0.c
@@ -0,0 +1,21 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct astruct_s astruct;
+
+int
+main ()
+{
+ printf ("%d\n", astruct.a);
+ printf ("%d\n", astruct.c);
+}
+
+/// { dg-final { scan-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. .. record astruct_s .boolean_type a;boolean_type c;." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-heterogeneous-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-heterogeneous-struct-0.c
new file mode 100644
index 00000000000..3a59518061c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-heterogeneous-struct-0.c
@@ -0,0 +1,21 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ float a;
+ _Bool b;
+ int c;
+};
+struct astruct_s astruct;
+
+int
+main ()
+{
+ printf ("%d\n", astruct.a);
+ printf ("%d\n", astruct.c);
+}
+
+/// { dg-final { scan-ipa-dump " record astruct_s .real_type a.boolean_type b.integer_type c.. .. record astruct_s .real_type a.integer_type c.." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c
new file mode 100644
index 00000000000..a530a5c944d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <stddef.h>
+#include <assert.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ int a;
+ int b;
+ int c;
+ };
+ struct astruct_s astruct;
+ int *c = &astruct.c;
+ int *a = &astruct.a;
+ ptrdiff_t d = c - a;
+ assert (d == 1);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c
new file mode 100644
index 00000000000..232c1a683e7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ _Bool a = astruct.a;
+ _Bool c = astruct.c;
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with a 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-nested-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-nested-struct-0.c
new file mode 100644
index 00000000000..9c42296709c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-nested-struct-0.c
@@ -0,0 +1,30 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ float a;
+ _Bool b;
+ int c;
+};
+struct ostruct_s
+{
+ struct astruct_s a;
+ float b;
+ float c;
+};
+struct ostruct_s ostruct;
+
+int
+main ()
+{
+ printf ("%d\n", ostruct.b);
+ printf ("%d\n", ostruct.c);
+ printf ("%f\n", ostruct.a.a);
+ printf ("%d\n", ostruct.a.c);
+}
+
+/// { dg-final { scan-ipa-dump " record astruct_s .real_type a;boolean_type b;integer_type c;. -> record astruct_s .real_type a;integer_type c;." "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump " record ostruct_s . record astruct_s .real_type a;boolean_type b;integer_type c;. a;real_type b;real_type c;. -> record ostruct_s . record astruct_s .real_type a;integer_type c;. a;real_type b;real_type c;." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c
new file mode 100644
index 00000000000..4ca8bf9f654
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ printf ("%d %d\n", astruct.a, astruct.c);
+ return 0;
+}
+
+// This is different from previous because here we are replacing a local
+// declaration
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c
new file mode 100644
index 00000000000..a9e54368ec9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ astruct.c = 0;
+ printf ("%d %d\n", astruct.a, astruct.c);
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+// There's two... mmm.. not sure how to convey this here to the test?
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-pointer-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-pointer-struct-0.c
new file mode 100644
index 00000000000..26a595e9c3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-pointer-struct-0.c
@@ -0,0 +1,31 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+struct astruct_s
+{
+ float a;
+ _Bool b;
+ int c;
+};
+struct ostruct_s
+{
+ struct astruct_s *a;
+ float b;
+ float c;
+};
+struct ostruct_s ostruct;
+
+int
+main ()
+{
+ printf ("%d\n", ostruct.b);
+ printf ("%d\n", ostruct.c);
+ printf ("%f\n", ostruct.a->a);
+ printf ("%d\n", ostruct.a->c);
+}
+
+/// { dg-final { scan-ipa-dump " record astruct_s ... -> record astruct_s ..." "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump " record ostruct_s . record astruct_s ... a;real_type b;real_type c;. -> record ostruct_s . record astruct_s ... a;real_type b;real_type c;." "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump " record astruct_s .real_type a;boolean_type b;integer_type c.. -> record astruct_s .real_type a;integer_type c.." "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c
new file mode 100644
index 00000000000..5f7c061f68d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool b;
+ _Bool a;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s astruct;
+
+ printf ("%d %d %d\n", astruct.a, astruct.c, astruct.d);
+ _Bool *a_ptr = &astruct.a;
+ struct astruct_s *s_ptr = &astruct;
+ assert (a_ptr == s_ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c
new file mode 100644
index 00000000000..17217924eba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stdio.h>
+int
+main ()
+{
+ struct inner_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s
+ {
+ struct inner_s a;
+ struct inner_s b;
+ struct inner_s c;
+ struct inner_s d;
+ };
+ struct astruct_s astruct;
+ // printf("%d %d %d\n", &astruct.a, &astruct.c, &astruct.d);
+ struct inner_s *a_ptr = &(astruct.a);
+ struct inner_s *c_ptr = &(astruct.c);
+ struct inner_s *d_ptr = &(astruct.d);
+ printf ("%d %d %d %d\n", a_ptr->a, a_ptr->b, a_ptr->c, a_ptr->d);
+ struct inner_s *c_ptr_2 = a_ptr + 1;
+ struct inner_s *a_ptr_2 = d_ptr - 2;
+ assert (c_ptr_2 == c_ptr);
+ assert (a_ptr == a_ptr_2);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c
new file mode 100644
index 00000000000..a073fa0bdab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ int a;
+ int b;
+ int c;
+ int d;
+ };
+ struct astruct_s astruct;
+ int *a = &(astruct.a);
+ int *c = &(astruct.c);
+ int *d = &(astruct.d);
+ assert (c - 1 == a);
+ assert (a + 2 == d);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-1-prints-structs-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-1-prints-structs-0.c
new file mode 100644
index 00000000000..7b5061ccafc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-1-prints-structs-0.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "astruct_s.a may be deleted" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "astruct_s.b may be deleted" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "astruct_s.c may be deleted" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c
new file mode 100644
index 00000000000..4839cb24eb6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options " -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s a;
+ printf ("%d %d\n", a.a, a.c);
+ struct astruct_s b[2];
+ a = b[0];
+ _Bool *a_ptr = &a.a;
+ _Bool *c_ptr = &a.c;
+ assert (a_ptr + 1 == c_ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-11-rewrites-minus-expr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-11-rewrites-minus-expr-0.c
new file mode 100644
index 00000000000..5590d8d9006
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-11-rewrites-minus-expr-0.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ _Bool *c_ptr = &(astruct.c);
+ _Bool *a_ptr = &(astruct.a);
+ ptrdiff_t diff = c_ptr - a_ptr;
+ assert (diff == 1);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-12-delete-last-field-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-12-delete-last-field-0.c
new file mode 100644
index 00000000000..6dc5d847122
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-12-delete-last-field-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool c;
+ _Bool b;
+ };
+ struct astruct_s b[2];
+ _Bool *first_of_second = &(b[1].a);
+ _Bool *c_0 = &(b[0].c);
+ _Bool *a_1 = &(b[1].a);
+ _Bool *a_1_from_c_0 = c_0 + 1;
+ _Bool test = a_1_from_c_0 == a_1;
+ char compile_test[test ? 1 : -1];
+ assert (test);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-13-modify-size-four-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-13-modify-size-four-0.c
new file mode 100644
index 00000000000..70d0ca74f75
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-13-modify-size-four-0.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s astruct;
+ _Bool *a = &(astruct.a);
+ _Bool *c = &(astruct.c);
+ _Bool *d = &(astruct.d);
+ ptrdiff_t diff_1 = c - a;
+ ptrdiff_t diff_2 = d - a;
+ assert (diff_1 == 1);
+ assert (diff_2 == 2);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-14-rewrite-plus-expr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-14-rewrite-plus-expr-0.c
new file mode 100644
index 00000000000..571ebe28851
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-14-rewrite-plus-expr-0.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ astruct.a = 1;
+ astruct.c = 1;
+ int d = astruct.a + astruct.c;
+ assert (d == 2);
+ _Bool *a = &(astruct.a);
+ _Bool *c = &(astruct.c);
+ assert (a + 1 == c);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-15-rewrite-mult-expr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-15-rewrite-mult-expr-0.c
new file mode 100644
index 00000000000..c845c472ea7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-15-rewrite-mult-expr-0.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <stddef.h>
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ astruct.a = 1;
+ astruct.c = 1;
+ int d = astruct.a * astruct.c;
+ assert (d == 1);
+ _Bool *a = &(astruct.a);
+ _Bool *c = &(astruct.c);
+ assert (a + 1 == c);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-16-rewrite-field-reads-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-16-rewrite-field-reads-ptr-0.c
new file mode 100644
index 00000000000..3c657ace805
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-16-rewrite-field-reads-ptr-0.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ struct astruct_s *astruct_p = &astruct;
+ printf ("%d %d\n", astruct_p->a, astruct_p->c);
+ _Bool *a = &(astruct.a);
+ _Bool *c = &(astruct.c);
+ assert (a + 1 == c);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-17-rewrite-field-write-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-17-rewrite-field-write-ptr-0.c
new file mode 100644
index 00000000000..587a94acc5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-17-rewrite-field-write-ptr-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ struct astruct_s *astruct_p = &astruct;
+ astruct_p->c = 1;
+ _Bool *a = &(astruct.a);
+ _Bool *c_ptr = &(astruct.c);
+ _Bool *c = a + 1;
+ assert (*c == *c_ptr);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-18-field-writes-deref-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-18-field-writes-deref-0.c
new file mode 100644
index 00000000000..d58955521c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-18-field-writes-deref-0.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s astruct;
+ _Bool *c_ptr = &astruct.c;
+ *c_ptr = 1;
+ _Bool *a_ptr = &astruct.a;
+ _Bool *d_ptr = &astruct.d;
+ a_ptr++;
+ d_ptr--;
+ assert (*a_ptr == 1);
+ assert (*d_ptr == 1);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-19-middle-pointer-equal-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-19-middle-pointer-equal-0.c
new file mode 100644
index 00000000000..c1e22c99bbe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-19-middle-pointer-equal-0.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s astruct;
+ _Bool *a = &astruct.a;
+ _Bool *d = &astruct.d;
+ _Bool *c = &astruct.c;
+ _Bool *c_from_a = a + 1;
+ _Bool *c_from_d = d - 1;
+ assert (c == c_from_a);
+ assert (c == c_from_d);
+ assert (c_from_a == c_from_d);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-2-modifies-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-2-modifies-0.c
new file mode 100644
index 00000000000..c320deb5343
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-2-modifies-0.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ astruct.a = astruct.c;
+ astruct.c = astruct.a;
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "astruct_s.b may be deleted" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-20-array-offset-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-20-array-offset-0.c
new file mode 100644
index 00000000000..581cdba8840
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-20-array-offset-0.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s b[2];
+ _Bool *a_0_ptr = &(b[0].a);
+ _Bool *c_0_ptr = &(b[0].c);
+ _Bool *a_1_ptr = &(b[1].a);
+
+ _Bool *c_0_ptr_from_a_0_ptr = a_0_ptr + 1;
+ _Bool *c_0_ptr_from_a_1_ptr = a_1_ptr - 1;
+ assert (c_0_ptr_from_a_0_ptr == c_0_ptr);
+ assert (c_0_ptr_from_a_1_ptr == c_0_ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-22-rewrites-addr-expr-read-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-22-rewrites-addr-expr-read-0.c
new file mode 100644
index 00000000000..120c3da0d27
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-22-rewrites-addr-expr-read-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ _Bool *a = &astruct.a;
+ _Bool *c = &astruct.c;
+ _Bool *c_1 = a + 1;
+ _Bool *a_1 = c - 1;
+ assert (c_1 == c);
+ assert (a_1 == a);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-23-array-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-23-array-cast-0.c
new file mode 100644
index 00000000000..01f270161fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-23-array-cast-0.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s a[2];
+ struct astruct_s *a_0 = &(a[0]);
+ struct astruct_s *a_1 = &(a[1]);
+ struct astruct_s *a_1_from_a_0 = a_0 + 1;
+ printf ("%d %d\n", a_0->a, a_0->c);
+ // old new
+ // 0 a a
+ // 1 b c
+ // 2 c a
+ // 3 a c
+ // 4 b a
+ // 5 c c
+ assert (a_1 == a_1_from_a_0);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-25-array-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-25-array-cast-0.c
new file mode 100644
index 00000000000..bf867b6cd43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-25-array-cast-0.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s a[2];
+ struct bstruct_s
+ {
+ _Bool a;
+ _Bool c;
+ _Bool d;
+ };
+
+ struct astruct_s *a_1 = &(a[1]);
+ struct astruct_s *a_0 = a_1 - 1;
+ struct bstruct_s *b_1 = (struct bstruct_s *) a_1;
+ struct bstruct_s *b_0 = b_1 - 1;
+ assert ((struct bstruct_s *) a_0 != b_0);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-26-array-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-26-array-cast-0.c
new file mode 100644
index 00000000000..32d0ba9171c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-26-array-cast-0.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s a[2];
+ struct astruct_s *a_0 = &(a[0]);
+ struct astruct_s *a_1 = a_0 + argc;
+ ptrdiff_t d = a_1 - a_0;
+ printf ("%d %d %d\n", a_0->a, a_0->c, a_0->d);
+ printf ("%d\n", d);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-27-array-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-27-array-cast-0.c
new file mode 100644
index 00000000000..352965c4e4f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-27-array-cast-0.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s a[2][2];
+ struct astruct_s b = a[argc][argc];
+ printf ("%d %d %d\n", b.a, b.c, b.d);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-29-heterogeneous-struct.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-29-heterogeneous-struct.c
new file mode 100644
index 00000000000..e3fdf6ef7ea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-29-heterogeneous-struct.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ int a;
+ _Bool b;
+ int c;
+ };
+ struct astruct_s astruct;
+ int *a = &(astruct.a);
+ int *c = &(astruct.c);
+ ptrdiff_t d = c - a;
+ assert (d == 1);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-30-heterogenous-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-30-heterogenous-struct-0.c
new file mode 100644
index 00000000000..30015c743b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-30-heterogenous-struct-0.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ // unmodified { a = 1, b = 4; c = 5; d = 8; e = 12
+ // modified { a = 1, c = 2; d = 4, e = 8
+ struct astruct_s
+ {
+ _Bool a;
+ int b;
+ _Bool c;
+ int d;
+ _Bool e;
+ };
+ struct astruct_s astruct;
+ _Bool *a = &(astruct.a);
+ printf ("%d %d\n", astruct.c, astruct.d);
+ _Bool *e = &(astruct.e);
+ ptrdiff_t diff = e - a;
+ assert (diff == 8);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-31-heterogenous-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-31-heterogenous-struct-0.c
new file mode 100644
index 00000000000..b1f6e9a5166
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-31-heterogenous-struct-0.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main ()
+{
+ // unmodified a = 0, d = 5; e = 6; f = 7; b = 8; c = 9
+ // modified a = 0, d = 1, e = 2, f = 3, c = 4;
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool d;
+ _Bool e;
+ _Bool f;
+ _Bool b;
+ int c;
+ };
+ struct astruct_s astruct;
+ struct astruct_s *p = &astruct;
+ printf ("%d %d %d %d %d\n", p->a, p->d, p->e, p->f, p->c);
+ _Bool *a = &(p->a);
+ int *c = &(p->c);
+ ptrdiff_t d = (_Bool *) c - a;
+ printf ("%d\n", d);
+ assert (d == 4);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-nested-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-nested-struct-0.c
new file mode 100644
index 00000000000..4f5906c1af7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-nested-struct-0.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool _a;
+ _Bool _b;
+ _Bool _c;
+ _Bool _d;
+ };
+ struct outerstruct_s
+ {
+ struct astruct_s a;
+ struct astruct_s b;
+ struct astruct_s c;
+ struct astruct_s d;
+ };
+ struct outerstruct_s outerstruct;
+ struct astruct_s a = outerstruct.a;
+ struct astruct_s b = outerstruct.b;
+ struct astruct_s c = outerstruct.c;
+ struct astruct_s d = outerstruct.d;
+ _Bool _a = a._a;
+ _Bool _c = a._c;
+ _Bool _d = a._d;
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field b 32 with b 32" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 64 with c 64" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field d 96 with d 96" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field _a 0 with _a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field _c 16 with _c 8" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field _d 24 with _d 16" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-pointer-indirection-level-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-pointer-indirection-level-0.c
new file mode 100644
index 00000000000..e91f8b7b5ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-33-pointer-indirection-level-0.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s astruct;
+ struct astruct_s *p0 = &astruct;
+ struct astruct_s **p1 = &p0;
+ _Bool *a_ptr = &(astruct.a);
+ _Bool *c_ptr = &(astruct.c);
+ _Bool *c_ptr_from_1 = a_ptr + 1;
+ _Bool *a_ptr_2 = &((*p1)->a);
+ _Bool *c_ptr_from_2 = a_ptr_2 + 1;
+ assert (c_ptr == c_ptr_from_1);
+ assert (c_ptr == c_ptr_from_2);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-34-array-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-34-array-cast-0.c
new file mode 100644
index 00000000000..8b30d96acbb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-34-array-cast-0.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+ };
+ struct astruct_s a[2][2];
+
+ struct astruct_s b = a[argc][argc];
+ printf ("%d %d %d\n", b.a, b.c, b.d);
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field d 24 with d 16" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-36-arguments-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-36-arguments-0.c
new file mode 100644
index 00000000000..1453b63dda0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-36-arguments-0.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+};
+
+// PASS BY VALUE
+_Bool
+foo (struct astruct_s astruct)
+{
+ _Bool *a = &astruct.a;
+ assert (!*a);
+ _Bool *c = a + 1;
+ assert (*c);
+ _Bool *d = a + 2;
+ assert (*d);
+ return *c;
+}
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s astruct;
+ astruct.a = 0;
+ astruct.c = argc;
+ astruct.d = 1;
+ printf ("%d %d %d\n", astruct.a, astruct.c, astruct.d);
+ foo (astruct);
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field d 24 with d 16" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-37-arguments-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-37-arguments-0.c
new file mode 100644
index 00000000000..829e2aab335
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-37-arguments-0.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests" } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+};
+
+// PASS BY REFERENCE
+_Bool
+foo (struct astruct_s *astruct)
+{
+ assert (astruct);
+ _Bool *a = &(astruct->a);
+ assert (!*a);
+ _Bool *c = a + 1;
+ assert (*c);
+ _Bool *d = a + 2;
+ assert (*d);
+ return *c;
+}
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s astruct;
+ astruct.a = 0;
+ astruct.c = argc;
+ astruct.d = 1;
+ printf ("%d %d %d\n", astruct.a, astruct.c, astruct.d);
+ foo (&astruct);
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field d 24 with d 16" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-38-return-values-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-38-return-values-0.c
new file mode 100644
index 00000000000..b6d372b4766
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-38-return-values-0.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ _Bool d;
+};
+
+// RETURN BY VALUE
+struct astruct_s
+foo (_Bool c)
+{
+ struct astruct_s astruct;
+ astruct.a = 0;
+ astruct.c = c;
+ astruct.d = 1;
+ return astruct;
+}
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s astruct;
+ astruct = foo (argc);
+ printf ("%d %d %d\n", astruct.a, astruct.c, astruct.d);
+ _Bool *a = &(astruct.a);
+ assert (!*a);
+ _Bool *c = a + 1;
+ assert (*c == argc);
+ _Bool *d = a + 2;
+ assert (*d);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-39-typedef-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-39-typedef-0.c
new file mode 100644
index 00000000000..08b1120d7de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-39-typedef-0.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ typedef struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ } astruct_s;
+ astruct_s astruct;
+ printf ("%d %d", astruct.a, astruct.c);
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-40-typedef-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-40-typedef-0.c
new file mode 100644
index 00000000000..c8f8f2586d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-40-typedef-0.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ typedef struct astruct_s astruct_s;
+ astruct_s astruct;
+ printf ("%d %d", astruct.a, astruct.c);
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-41-deref-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-41-deref-0.c
new file mode 100644
index 00000000000..5af63d482a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-41-deref-0.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdbool.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ struct astruct_s *t, copy;
+ t = &astruct;
+ t->a = true;
+ t->c = true;
+ copy = *t;
+ printf ("%d %d", copy.a, copy.c);
+ assert (astruct.a == true);
+ assert (astruct.c == true);
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-42-mem-ref-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-42-mem-ref-0.c
new file mode 100644
index 00000000000..30b61398515
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-42-mem-ref-0.c
@@ -0,0 +1,32 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct astruct astruct_t;
+typedef struct astruct *astruct_p;
+
+struct astruct
+{
+ int a;
+ int b;
+ astruct_p one;
+ astruct_p two;
+ int c;
+ int d;
+};
+
+int
+main ()
+{
+ int n = 10;
+ astruct_p *astructs;
+ register astruct_t *astructnew
+ = (astruct_t *) malloc (n * sizeof (astruct_p));
+ astructs = (astruct_p *) malloc (n * n * sizeof (astruct_p));
+ astructs[n - 1][n - 1] = astructnew[0];
+ printf ("%d %d %d %d\n", astructnew->a, astructnew->b, astructnew->c,
+ astructnew->d);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-43-args-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-43-args-0.c
new file mode 100644
index 00000000000..dae73e80a82
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-43-args-0.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+struct wrapper_s
+{
+ struct astruct_s *a;
+};
+
+void
+foo (struct wrapper_s *wrapper){};
+
+void
+bar (struct wrapper_s *wrapper)
+{
+ foo (wrapper);
+};
+
+int
+main ()
+{
+ struct wrapper_s a_wrapper;
+ _Bool is_non_null = a_wrapper.a != NULL;
+ printf ("%d %d %d", &a_wrapper.a, is_non_null ? a_wrapper.a->a : 0,
+ is_non_null ? a_wrapper.a->c : 0);
+ bar (&a_wrapper);
+}
+
+/// { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */
+/// { dg-final { scan-ipa-dump "replacing field c 16 with a 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-44-cond-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-44-cond-0.c
new file mode 100644
index 00000000000..99498058671
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-44-cond-0.c
@@ -0,0 +1,16 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+struct a
+{
+ struct b *b;
+} c (struct a *d)
+{
+ while (d)
+ ;
+}
+void
+main ()
+{}
+
+/// { dg-final { scan-ipa-dump "deleting all fields for struct a" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-45-phis-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-45-phis-0.c
new file mode 100644
index 00000000000..f8acd5011cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-45-phis-0.c
@@ -0,0 +1,16 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa" } */
+
+struct a
+{
+ struct a_inner *b;
+} c (struct a *d, struct a *e)
+{
+ while (e)
+ d = d;
+}
+int
+main ()
+{}
+
+/// { dg-final { scan-ipa-dump "deleting all fields for struct a" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-46-static-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-46-static-0.c
new file mode 100644
index 00000000000..86c428e291c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-46-static-0.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa -fipa-dlo-tests " } */
+
+#include <assert.h>
+#include <stddef.h>
+
+struct a_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+
+struct a_s a_t;
+
+int
+main ()
+{
+ _Bool *a = &(a_t.a);
+ _Bool *c = &(a_t.c);
+ ptrdiff_t diff = c - a;
+ assert (diff == 1);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-47-constructor-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-47-constructor-0.c
new file mode 100644
index 00000000000..52dc67589cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-47-constructor-0.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool b;
+ _Bool c;
+ };
+ struct astruct_s an_arc;
+ struct another
+ {
+ _Bool a;
+ struct astruct_s d;
+ _Bool c;
+ };
+ struct another an_another = {0, {0, 1}, 1};
+ struct astruct_s a = an_another.d;
+ printf ("%d %d %d %d %d", an_another.a, &a, a.a, a.c, an_another.c);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-48-function-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-48-function-ptr-0.c
new file mode 100644
index 00000000000..405ccab3c34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-48-function-ptr-0.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+
+struct astruct_s
+{
+ _Bool a;
+ _Bool b;
+ _Bool c;
+};
+
+_Bool
+returnLast (struct astruct_s astruct)
+{
+ return astruct.c;
+}
+
+_Bool
+returnLast2 (struct astruct_s astruct)
+{
+ _Bool *ptr = &(astruct.a);
+ ptr = ptr + 1;
+ return *ptr;
+}
+
+int
+main (int argc, char **argv)
+{
+ _Bool (*func1) (struct astruct_s);
+ func1 = &returnLast;
+ _Bool (*func2) (struct astruct_s);
+ func2 = &returnLast2;
+ struct astruct_s astruct;
+ astruct.c = argc;
+ printf ("%d %d", astruct.a, astruct.c);
+ // These test means that things remain equal
+ // A.k.a without an optimization.
+ // Why? Because a function pointer can be a
+ // pointer to anything
+ assert (func1 (astruct) != func2 (astruct));
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-50-field-write-delete-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-50-field-write-delete-0.c
new file mode 100644
index 00000000000..591ade318ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-50-field-write-delete-0.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -Wno-dfa " } */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ struct astruct_s
+ {
+ _Bool a;
+ _Bool delete_me;
+ _Bool c;
+ };
+ struct astruct_s astruct;
+ printf ("%d %d", astruct.a, astruct.c);
+ astruct.delete_me = false;
+ return 0;
+}
+
+/// { dg-final { scan-ipa-dump "deleting field delete_me 8" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-51-creduce-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-51-creduce-0.c
new file mode 100644
index 00000000000..1d86ad808be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-51-creduce-0.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-flto -flto-partition=none -fipa-type-escape-analysis" } */
+
+struct
+{
+} main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-52-creduce-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-52-creduce-1.c
new file mode 100644
index 00000000000..0eeda3f82b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-52-creduce-1.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdint.h>
+union a
+{
+ int16_t b
+} c ()
+{
+ union a d;
+ -d.b;
+}
+main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-53-csmith-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-53-csmith-2.c
new file mode 100644
index 00000000000..87268497d39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-53-csmith-2.c
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+struct
+{
+} a;
+main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-54-csmith-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-54-csmith-3.c
new file mode 100644
index 00000000000..0b4e981deb4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-54-csmith-3.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdint.h>
+// TODO: So, our analysis says that we are deleting a field "a".
+// And that the field "a" is contained in struct "b".
+// However, we are doing is_interesting_struct("c") == yes
+// is_interesting_field("a") == yes
+// and so we delete field a from struct c.
+struct
+{
+ uint64_t a
+} b[];
+struct
+{
+ unsigned : 5;
+ unsigned a
+} c;
+d ()
+{
+ uint16_t e = b;
+ int8_t f = c.a;
+}
+main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-55-csmith-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-55-csmith-4.c
new file mode 100644
index 00000000000..d4f1d684614
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-55-csmith-4.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdint.h>
+union a
+{
+ int8_t b
+} c () { union a d = {4073709551608}; }
+main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-56-csmith-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-56-csmith-5.c
new file mode 100644
index 00000000000..b016a3b8ea1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-56-csmith-5.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdint.h>
+struct a
+{
+ int8_t b
+};
+struct c
+{
+ struct a d
+} e[];
+
+/* Analysis failed because e[2].d was considered not read
+ * we were only looking at e[2].d.b which is considered read.
+ * So we need to recurse
+ */
+f () { g (e[2].d.b, 0); }
+
+void
+g (int8_t a, int8_t b)
+{
+ a + b;
+}
+main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-57-csmith-6.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-57-csmith-6.c
new file mode 100644
index 00000000000..985975e01d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-57-csmith-6.c
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+struct a
+{
+};
+b (struct a c) {}
+main () {}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-58-csmith-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-58-csmith-7.c
new file mode 100644
index 00000000000..055ab515767
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-58-csmith-7.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdint.h>
+struct a
+{
+ int32_t b
+} c;
+d ()
+{
+ for (;; c.b = 0)
+ ;
+}
+main () {}
+/// { dg-final { scan-ipa-dump "deleting field b 0" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-59-csmith-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-59-csmith-8.c
new file mode 100644
index 00000000000..d8c546e4d32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-59-csmith-8.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+struct a
+{
+ signed b
+};
+struct
+{
+ struct a b
+} volatile c;
+main () { c.b.b; }
+
+// we will do nothing because volatile
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-60-csmith-9.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-60-csmith-9.c
new file mode 100644
index 00000000000..0a99e271628
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-60-csmith-9.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */
+
+#include <stdint.h>
+
+void
+foo (uint64_t a, uint64_t b)
+{
+ a + b;
+}
+
+struct a
+{
+ uint64_t b;
+ uint8_t c
+} d ()
+{
+ // I think the problem here is with the const attribute...
+ const struct a e;
+ foo (0, e.b);
+ return e;
+}
+
+main () {}
+
+/// { dg-final { scan-ipa-dump "a.c may be deleted" "type-escape-analysis" } } */