diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2016-10-28 14:18:50 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2016-10-28 14:18:50 +0000 |
commit | f663d9ad6eaa6ff32676981461e865f96cb7c151 (patch) | |
tree | c6b6f30f38de29c8fcc46fc859446438b55c447f /gcc/testsuite | |
parent | 1f5700e95225d0a95cae2f96c17699c4d133f5e0 (diff) | |
download | gcc-f663d9ad6eaa6ff32676981461e865f96cb7c151.zip gcc-f663d9ad6eaa6ff32676981461e865f96cb7c151.tar.gz gcc-f663d9ad6eaa6ff32676981461e865f96cb7c151.tar.bz2 |
GIMPLE store merging pass
2016-10-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR middle-end/22141
* Makefile.in (OBJS): Add gimple-ssa-store-merging.o.
* common.opt (fstore-merging): New Optimization option.
* opts.c (default_options_table): Add entry for
OPT_ftree_store_merging.
* fold-const.h (can_native_encode_type_p): Declare prototype.
* fold-const.c (can_native_encode_type_p): Define.
* params.def (PARAM_STORE_MERGING_ALLOW_UNALIGNED): Define.
(PARAM_MAX_STORES_TO_MERGE): Likewise.
* timevar.def (TV_GIMPLE_STORE_MERGING): New timevar.
* passes.def: Insert pass_tree_store_merging.
* tree-pass.h (make_pass_store_merging): Declare extern
prototype.
* gimple-ssa-store-merging.c: New file.
* doc/invoke.texi (Optimization Options): Document
-fstore-merging.
(--param documentation): Document store-merging-allow-unaligned
and max-stores-to-merge.
2016-10-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Jakub Jelinek <jakub@redhat.com>
Andrew Pinski <pinskia@gmail.com>
PR middle-end/22141
PR rtl-optimization/23684
* gcc.c-torture/execute/pr22141-1.c: New test.
* gcc.c-torture/execute/pr22141-2.c: Likewise.
* gcc.target/aarch64/ldp_stp_1.c: Adjust for -fstore-merging.
* gcc.target/aarch64/ldp_stp_4.c: Likewise.
* gcc.dg/store_merging_1.c: New test.
* gcc.dg/store_merging_2.c: Likewise.
* gcc.dg/store_merging_3.c: Likewise.
* gcc.dg/store_merging_4.c: Likewise.
* gcc.dg/store_merging_5.c: Likewise.
* gcc.dg/store_merging_6.c: Likewise.
* gcc.dg/store_merging_7.c: Likewise.
* gcc.target/i386/pr22141.c: Likewise.
* gcc.target/i386/pr34012.c: Add -fno-store-merging to dg-options.
* g++.dg/init/new17.C: Likewise.
Co-Authored-By: Andrew Pinski <pinskia@gmail.com>
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r241649
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/new17.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr22141-1.c | 122 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr22141-2.c | 122 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_1.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_2.c | 80 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_3.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_4.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_5.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_6.c | 53 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/store_merging_7.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/ldp_stp_1.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/ldp_stp_4.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr22141.c | 126 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr34012.c | 2 |
15 files changed, 711 insertions, 32 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b4d7ec0..3a4041d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,24 @@ +2016-10-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + Jakub Jelinek <jakub@redhat.com> + Andrew Pinski <pinskia@gmail.com> + + PR middle-end/22141 + PR rtl-optimization/23684 + * gcc.c-torture/execute/pr22141-1.c: New test. + * gcc.c-torture/execute/pr22141-2.c: Likewise. + * gcc.target/aarch64/ldp_stp_1.c: Adjust for -fstore-merging. + * gcc.target/aarch64/ldp_stp_4.c: Likewise. + * gcc.dg/store_merging_1.c: New test. + * gcc.dg/store_merging_2.c: Likewise. + * gcc.dg/store_merging_3.c: Likewise. + * gcc.dg/store_merging_4.c: Likewise. + * gcc.dg/store_merging_5.c: Likewise. + * gcc.dg/store_merging_6.c: Likewise. + * gcc.dg/store_merging_7.c: Likewise. + * gcc.target/i386/pr22141.c: Likewise. + * gcc.target/i386/pr34012.c: Add -fno-store-merging to dg-options. + * g++.dg/init/new17.C: Likewise. + 2016-10-26 Will Schmidt <will_schmidt@vnet.ibm.com> PR middle-end/72747 diff --git a/gcc/testsuite/g++.dg/init/new17.C b/gcc/testsuite/g++.dg/init/new17.C index a7b1659..f6a3231 100644 --- a/gcc/testsuite/g++.dg/init/new17.C +++ b/gcc/testsuite/g++.dg/init/new17.C @@ -1,5 +1,5 @@ // { dg-do compile } -// { dg-options "-O2 -fstrict-aliasing -fdump-tree-optimized" } +// { dg-options "-O2 -fstrict-aliasing -fno-store-merging -fdump-tree-optimized" } // Test that placement new does not introduce an unnecessary memory // barrier. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22141-1.c b/gcc/testsuite/gcc.c-torture/execute/pr22141-1.c new file mode 100644 index 0000000..7c888b4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr22141-1.c @@ -0,0 +1,122 @@ +/* PR middle-end/22141 */ + +extern void abort (void); + +struct S +{ + struct T + { + char a; + char b; + char c; + char d; + } t; +} u; + +struct U +{ + struct S s[4]; +}; + +void __attribute__((noinline)) +c1 (struct T *p) +{ + if (p->a != 1 || p->b != 2 || p->c != 3 || p->d != 4) + abort (); + __builtin_memset (p, 0xaa, sizeof (*p)); +} + +void __attribute__((noinline)) +c2 (struct S *p) +{ + c1 (&p->t); +} + +void __attribute__((noinline)) +c3 (struct U *p) +{ + c2 (&p->s[2]); +} + +void __attribute__((noinline)) +f1 (void) +{ + u = (struct S) { { 1, 2, 3, 4 } }; +} + +void __attribute__((noinline)) +f2 (void) +{ + u.t.a = 1; + u.t.b = 2; + u.t.c = 3; + u.t.d = 4; +} + +void __attribute__((noinline)) +f3 (void) +{ + u.t.d = 4; + u.t.b = 2; + u.t.a = 1; + u.t.c = 3; +} + +void __attribute__((noinline)) +f4 (void) +{ + struct S v; + v.t.a = 1; + v.t.b = 2; + v.t.c = 3; + v.t.d = 4; + c2 (&v); +} + +void __attribute__((noinline)) +f5 (struct S *p) +{ + p->t.a = 1; + p->t.c = 3; + p->t.d = 4; + p->t.b = 2; +} + +void __attribute__((noinline)) +f6 (void) +{ + struct U v; + v.s[2].t.a = 1; + v.s[2].t.b = 2; + v.s[2].t.c = 3; + v.s[2].t.d = 4; + c3 (&v); +} + +void __attribute__((noinline)) +f7 (struct U *p) +{ + p->s[2].t.a = 1; + p->s[2].t.c = 3; + p->s[2].t.d = 4; + p->s[2].t.b = 2; +} + +int +main (void) +{ + struct U w; + f1 (); + c2 (&u); + f2 (); + c1 (&u.t); + f3 (); + c2 (&u); + f4 (); + f5 (&u); + c2 (&u); + f6 (); + f7 (&w); + c3 (&w); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22141-2.c b/gcc/testsuite/gcc.c-torture/execute/pr22141-2.c new file mode 100644 index 0000000..cb9cc79 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr22141-2.c @@ -0,0 +1,122 @@ +/* PR middle-end/22141 */ + +extern void abort (void); + +struct S +{ + struct T + { + char a; + char b; + char c; + char d; + } t; +} u __attribute__((aligned)); + +struct U +{ + struct S s[4]; +}; + +void __attribute__((noinline)) +c1 (struct T *p) +{ + if (p->a != 1 || p->b != 2 || p->c != 3 || p->d != 4) + abort (); + __builtin_memset (p, 0xaa, sizeof (*p)); +} + +void __attribute__((noinline)) +c2 (struct S *p) +{ + c1 (&p->t); +} + +void __attribute__((noinline)) +c3 (struct U *p) +{ + c2 (&p->s[2]); +} + +void __attribute__((noinline)) +f1 (void) +{ + u = (struct S) { { 1, 2, 3, 4 } }; +} + +void __attribute__((noinline)) +f2 (void) +{ + u.t.a = 1; + u.t.b = 2; + u.t.c = 3; + u.t.d = 4; +} + +void __attribute__((noinline)) +f3 (void) +{ + u.t.d = 4; + u.t.b = 2; + u.t.a = 1; + u.t.c = 3; +} + +void __attribute__((noinline)) +f4 (void) +{ + struct S v __attribute__((aligned)); + v.t.a = 1; + v.t.b = 2; + v.t.c = 3; + v.t.d = 4; + c2 (&v); +} + +void __attribute__((noinline)) +f5 (struct S *p) +{ + p->t.a = 1; + p->t.c = 3; + p->t.d = 4; + p->t.b = 2; +} + +void __attribute__((noinline)) +f6 (void) +{ + struct U v __attribute__((aligned)); + v.s[2].t.a = 1; + v.s[2].t.b = 2; + v.s[2].t.c = 3; + v.s[2].t.d = 4; + c3 (&v); +} + +void __attribute__((noinline)) +f7 (struct U *p) +{ + p->s[2].t.a = 1; + p->s[2].t.c = 3; + p->s[2].t.d = 4; + p->s[2].t.b = 2; +} + +int +main (void) +{ + struct U w __attribute__((aligned)); + f1 (); + c2 (&u); + f2 (); + c1 (&u.t); + f3 (); + c2 (&u); + f4 (); + f5 (&u); + c2 (&u); + f6 (); + f7 (&w); + c3 (&w); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/store_merging_1.c b/gcc/testsuite/gcc.dg/store_merging_1.c new file mode 100644 index 0000000..35f4d82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_1.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +struct bar { + int a; + char b; + char c; + char d; + char e; + char f; + char g; +}; + +void +foo1 (struct bar *p) +{ + p->b = 0; + p->a = 0; + p->c = 0; + p->d = 0; + p->e = 0; +} + +void +foo2 (struct bar *p) +{ + p->b = 0; + p->a = 0; + p->c = 1; + p->d = 0; + p->e = 0; +} + +/* { dg-final { scan-tree-dump-times "Merging successful" 2 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.dg/store_merging_2.c b/gcc/testsuite/gcc.dg/store_merging_2.c new file mode 100644 index 0000000..8e2acf3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_2.c @@ -0,0 +1,80 @@ +/* { dg-do run } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +struct bar +{ + int a; + unsigned char b; + unsigned char c; + short d; + unsigned char e; + unsigned char f; + unsigned char g; +}; + +__attribute__ ((noinline)) void +foozero (struct bar *p) +{ + p->b = 0; + p->a = 0; + p->c = 0; + p->d = 0; + p->e = 0; + p->f = 0; + p->g = 0; +} + +__attribute__ ((noinline)) void +foo1 (struct bar *p) +{ + p->b = 1; + p->a = 2; + p->c = 3; + p->d = 4; + p->e = 5; + p->f = 0; + p->g = 0xff; +} + +__attribute__ ((noinline)) void +foo2 (struct bar *p, struct bar *p2) +{ + p->b = 0xff; + p2->b = 0xa; + p->a = 0xfffff; + p2->c = 0xc; + p->c = 0xff; + p2->d = 0xbf; + p->d = 0xfff; +} + +int +main (void) +{ + struct bar b1, b2; + foozero (&b1); + foozero (&b2); + + foo1 (&b1); + if (b1.b != 1 || b1.a != 2 || b1.c != 3 || b1.d != 4 || b1.e != 5 + || b1.f != 0 || b1.g != 0xff) + __builtin_abort (); + + foozero (&b1); + /* Make sure writes to aliasing struct pointers preserve the + correct order. */ + foo2 (&b1, &b1); + if (b1.b != 0xa || b1.a != 0xfffff || b1.c != 0xff || b1.d != 0xfff) + __builtin_abort (); + + foozero (&b1); + foo2 (&b1, &b2); + if (b1.a != 0xfffff || b1.b != 0xff || b1.c != 0xff || b1.d != 0xfff + || b2.b != 0xa || b2.c != 0xc || b2.d != 0xbf) + __builtin_abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "Merging successful" 2 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.dg/store_merging_3.c b/gcc/testsuite/gcc.dg/store_merging_3.c new file mode 100644 index 0000000..caf356d --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_3.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging-details" } */ + +/* Make sure stores to volatile addresses don't get combined with + other accesses. */ + +struct bar +{ + int a; + char b; + char c; + volatile short d; + char e; + char f; + char g; +}; + +void +foozero (struct bar *p) +{ + p->b = 0xa; + p->a = 0xb; + p->c = 0xc; + p->d = 0; + p->e = 0xd; + p->f = 0xe; + p->g = 0xf; +} + +/* { dg-final { scan-tree-dump "Volatile access terminates all chains" "store-merging" } } */ +/* { dg-final { scan-tree-dump-times "=\{v\} 0;" 1 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.dg/store_merging_4.c b/gcc/testsuite/gcc.dg/store_merging_4.c new file mode 100644 index 0000000..a3d6769 --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +/* Check that we can merge interleaving stores that are guaranteed + to be non-aliasing. */ + +struct bar +{ + int a; + char b; + char c; + short d; + char e; + char f; + char g; +}; + +void +foozero (struct bar *restrict p, struct bar *restrict p2) +{ + p->b = 0xff; + p2->b = 0xa; + p->a = 0xfffff; + p2->a = 0xab; + p2->c = 0xc; + p->c = 0xff; + p2->d = 0xbf; + p->d = 0xfff; +} + +/* { dg-final { scan-tree-dump-times "Merging successful" 2 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.dg/store_merging_5.c b/gcc/testsuite/gcc.dg/store_merging_5.c new file mode 100644 index 0000000..4ffe512 --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_5.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +/* Make sure that non-aliasing non-constant interspersed stores do not + stop chains. */ + +struct bar { + int a; + char b; + char c; + char d; + char e; + char g; +}; + +void +foo1 (struct bar *p, char tmp) +{ + p->a = 0; + p->b = 0; + p->g = tmp; + p->c = 0; + p->d = 0; + p->e = 0; +} + + +/* { dg-final { scan-tree-dump-times "Merging successful" 1 "store-merging" } } */ +/* { dg-final { scan-tree-dump-times "MEM\\\[.*\\\]" 1 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.dg/store_merging_6.c b/gcc/testsuite/gcc.dg/store_merging_6.c new file mode 100644 index 0000000..42b5c4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_6.c @@ -0,0 +1,53 @@ +/* { dg-do run } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +/* Check that we can widen accesses to bitfields. */ + +struct bar { + int a : 3; + unsigned char b : 4; + unsigned char c : 1; + char d; + char e; + char f; + char g; +}; + +__attribute__ ((noinline)) void +foozero (struct bar *p) +{ + p->b = 0; + p->a = 0; + p->c = 0; + p->d = 0; + p->e = 0; + p->f = 0; + p->g = 0; +} + +__attribute__ ((noinline)) void +foo1 (struct bar *p) +{ + p->b = 3; + p->a = 2; + p->c = 1; + p->d = 4; + p->e = 5; +} + +int +main (void) +{ + struct bar p; + foozero (&p); + foo1 (&p); + if (p.a != 2 || p.b != 3 || p.c != 1 || p.d != 4 || p.e != 5 + || p.f != 0 || p.g != 0) + __builtin_abort (); + + return 0; +} + + +/* { dg-final { scan-tree-dump-times "Merging successful" 2 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.dg/store_merging_7.c b/gcc/testsuite/gcc.dg/store_merging_7.c new file mode 100644 index 0000000..4be352f --- /dev/null +++ b/gcc/testsuite/gcc.dg/store_merging_7.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target non_strict_align } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +/* Check that we can merge consecutive array members through the pointer. + PR rtl-optimization/23684. */ + +void +foo (char *input) +{ + input = __builtin_assume_aligned (input, 8); + input[0] = 'H'; + input[1] = 'e'; + input[2] = 'l'; + input[3] = 'l'; + input[4] = 'o'; + input[5] = ' '; + input[6] = 'w'; + input[7] = 'o'; + input[8] = 'r'; + input[9] = 'l'; + input[10] = 'd'; + input[11] = '\0'; +} + +/* { dg-final { scan-tree-dump-times "Merging successful" 1 "store-merging" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_1.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_1.c index f02e55f..9de4e77 100644 --- a/gcc/testsuite/gcc.target/aarch64/ldp_stp_1.c +++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_1.c @@ -3,22 +3,22 @@ int arr[4][4]; void -foo () +foo (int x, int y) { - arr[0][1] = 1; - arr[1][0] = -1; - arr[2][0] = 1; - arr[1][1] = -1; - arr[0][2] = 1; - arr[0][3] = -1; - arr[1][2] = 1; - arr[2][1] = -1; - arr[3][0] = 1; - arr[3][1] = -1; - arr[2][2] = 1; - arr[1][3] = -1; - arr[2][3] = 1; - arr[3][2] = -1; + arr[0][1] = x; + arr[1][0] = y; + arr[2][0] = x; + arr[1][1] = y; + arr[0][2] = x; + arr[0][3] = y; + arr[1][2] = x; + arr[2][1] = y; + arr[3][0] = x; + arr[3][1] = y; + arr[2][2] = x; + arr[1][3] = y; + arr[2][3] = x; + arr[3][2] = y; } /* { dg-final { scan-assembler-times "stp\tw\[0-9\]+, w\[0-9\]" 7 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_4.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_4.c index 40056b1..824f0d2 100644 --- a/gcc/testsuite/gcc.target/aarch64/ldp_stp_4.c +++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_4.c @@ -3,22 +3,22 @@ float arr[4][4]; void -foo () +foo (float x, float y) { - arr[0][1] = 1; - arr[1][0] = -1; - arr[2][0] = 1; - arr[1][1] = -1; - arr[0][2] = 1; - arr[0][3] = -1; - arr[1][2] = 1; - arr[2][1] = -1; - arr[3][0] = 1; - arr[3][1] = -1; - arr[2][2] = 1; - arr[1][3] = -1; - arr[2][3] = 1; - arr[3][2] = -1; + arr[0][1] = x; + arr[1][0] = y; + arr[2][0] = x; + arr[1][1] = y; + arr[0][2] = x; + arr[0][3] = y; + arr[1][2] = x; + arr[2][1] = y; + arr[3][0] = x; + arr[3][1] = y; + arr[2][2] = x; + arr[1][3] = y; + arr[2][3] = x; + arr[3][2] = y; } /* { dg-final { scan-assembler-times "stp\ts\[0-9\]+, s\[0-9\]" 7 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr22141.c b/gcc/testsuite/gcc.target/i386/pr22141.c new file mode 100644 index 0000000..036422e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr22141.c @@ -0,0 +1,126 @@ +/* PR middle-end/22141 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +extern void abort (void); + +struct S +{ + struct T + { + char a; + char b; + char c; + char d; + } t; +} u; + +struct U +{ + struct S s[4]; +}; + +void __attribute__((noinline)) +c1 (struct T *p) +{ + if (p->a != 1 || p->b != 2 || p->c != 3 || p->d != 4) + abort (); + __builtin_memset (p, 0xaa, sizeof (*p)); +} + +void __attribute__((noinline)) +c2 (struct S *p) +{ + c1 (&p->t); +} + +void __attribute__((noinline)) +c3 (struct U *p) +{ + c2 (&p->s[2]); +} + +void __attribute__((noinline)) +f1 (void) +{ + u = (struct S) { { 1, 2, 3, 4 } }; +} + +void __attribute__((noinline)) +f2 (void) +{ + u.t.a = 1; + u.t.b = 2; + u.t.c = 3; + u.t.d = 4; +} + +void __attribute__((noinline)) +f3 (void) +{ + u.t.d = 4; + u.t.b = 2; + u.t.a = 1; + u.t.c = 3; +} + +void __attribute__((noinline)) +f4 (void) +{ + struct S v; + v.t.a = 1; + v.t.b = 2; + v.t.c = 3; + v.t.d = 4; + c2 (&v); +} + +void __attribute__((noinline)) +f5 (struct S *p) +{ + p->t.a = 1; + p->t.c = 3; + p->t.d = 4; + p->t.b = 2; +} + +void __attribute__((noinline)) +f6 (void) +{ + struct U v; + v.s[2].t.a = 1; + v.s[2].t.b = 2; + v.s[2].t.c = 3; + v.s[2].t.d = 4; + c3 (&v); +} + +void __attribute__((noinline)) +f7 (struct U *p) +{ + p->s[2].t.a = 1; + p->s[2].t.c = 3; + p->s[2].t.d = 4; + p->s[2].t.b = 2; +} + +int +main (void) +{ + struct U w; + f1 (); + c2 (&u); + f2 (); + c1 (&u.t); + f3 (); + c2 (&u); + f4 (); + f5 (&u); + c2 (&u); + f6 (); + f7 (&w); + c3 (&w); + return 0; +} + +/* { dg-final { scan-assembler-times "67305985\|4030201" 7 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr34012.c b/gcc/testsuite/gcc.target/i386/pr34012.c index 00b1240..d0cffa05 100644 --- a/gcc/testsuite/gcc.target/i386/pr34012.c +++ b/gcc/testsuite/gcc.target/i386/pr34012.c @@ -1,7 +1,7 @@ /* PR rtl-optimization/34012 */ /* { dg-do compile } */ /* { dg-require-effective-target lp64 } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -fno-store-merging" } */ void bar (long int *); void |