[backport gcc-4.8/trunk r194905, dropped mods to pr45144.c since that file is reverted from my 4.6 branch ] gcc/ 2013-01-04 Martin Jambor PR tree-optimization/55755 * tree-sra.c (sra_modify_assign): Do not check that an access has no children when trying to avoid producing a VIEW_CONVERT_EXPR. gcc/testsuite/ 2013-01-04 Martin Jambor PR tree-optimization/55755 * gcc.dg/torture/pr55755.c: New test. * gcc.dg/tree-ssa/sra-13.c: Likewise. --- gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr55755.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr55755.c 2013-01-05 13:30:28.000000000 +0100 @@ -0,0 +1,43 @@ +/* { dg-do run } */ +/* { dg-require-effective-target int32plus } */ + +struct S4 +{ + unsigned f0:24; +} __attribute__((__packed__)); + +struct S4 g_10 = { + 6210831 +}; + +struct S5 +{ + int i; + struct S4 l_8[2]; +} __attribute__((__packed__)); + +int a, b; + +struct S4 func_2 (int x) +{ + struct S5 l = { + 0, + {{0}, {0}} + }; + l.i = a; + g_10 = l.l_8[1]; + for (; x<2; x++) { + struct S4 tmp = { + 11936567 + }; + l.l_8[x] = tmp; + } + b = l.i; + return g_10; +} + +int main (void) +{ + func_2 (0); + return 0; +} --- gcc-4.6.3/gcc/testsuite/gcc.dg/tree-ssa/sra-13.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.3/gcc/testsuite/gcc.dg/tree-ssa/sra-13.c 2013-01-05 13:30:28.000000000 +0100 @@ -0,0 +1,114 @@ +/* Test that SRA replacement can deal with assignments that have + sub-replacements on one side and a single scalar replacement on another. */ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +struct A +{ + int i1, i2; +}; + +struct B +{ + long long int l; +}; + +union U +{ + struct A a; + struct B b; +}; + +int b, gi; +long gl; +union U gu1, gu2; + +int __attribute__ ((noinline, noclone)) +foo (void) +{ + union U x, y; + int r; + + y = gu1; + if (b) + y.b.l = gl; + + x = y; + + if (!b) + r = x.a.i1; + else + r = 0; + + gu2 = x; + return r; +} + +long long int __attribute__ ((noinline, noclone)) +bar (void) +{ + union U x, y; + int r; + + y = gu1; + if (b) + y.a.i1 = gi; + + x = y; + + if (!b) + r = x.b.l; + else + r = 0; + + gu2 = x; + return r; +} + + +int +main (void) +{ + int r; + long long int s; + + b = 0; + gu1.a.i1 = 123; + gu1.a.i2 = 234; + r = foo (); + if (r != 123) + __builtin_abort (); + if (gu2.a.i1 != 123) + __builtin_abort (); + if (gu2.a.i2 != 234) + __builtin_abort (); + + b = 1; + gl = 10000001; + gu1.b.l = 10000000; + r = foo (); + if (r != 0) + __builtin_abort (); + if (gu2.b.l != 10000001) + __builtin_abort (); + + b = 0; + gu1.b.l = 20000000; + s = bar (); + if (s != 20000000) + __builtin_abort (); + if (gu2.b.l != 20000000) + __builtin_abort (); + + b = 1; + gi = 456; + gu1.a.i1 = 123; + gu1.a.i2 = 234; + s = bar (); + if (s != 0) + __builtin_abort (); + if (gu2.a.i1 != 456) + __builtin_abort (); + + return 0; +} --- gcc-4.6.3/gcc/tree-sra.c.~1~ 2012-01-05 23:24:45.000000000 +0100 +++ gcc-4.6.3/gcc/tree-sra.c 2013-01-05 13:30:28.000000000 +0100 @@ -2867,15 +2867,13 @@ sra_modify_assign (gimple *stmt, gimple_ ??? This should move to fold_stmt which we simply should call after building a VIEW_CONVERT_EXPR here. */ if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) - && !contains_bitfld_comp_ref_p (lhs) - && !access_has_children_p (lacc)) + && !contains_bitfld_comp_ref_p (lhs)) { lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false); gimple_assign_set_lhs (*stmt, lhs); } else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs)) - && !contains_vce_or_bfcref_p (rhs) - && !access_has_children_p (racc)) + && !contains_vce_or_bfcref_p (rhs)) rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false); if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))