[backport from gcc-4.7/trunk r184214 ] gcc/ 2012-02-14 Richard Guenther PR tree-optimization/52244 PR tree-optimization/51528 * tree-sra.c (analyze_access_subtree): Only create INTEGER_TYPE replacements for integral types. gcc/testsuite/ 2012-02-14 Richard Guenther PR tree-optimization/52244 PR tree-optimization/51528 * gcc.dg/torture/pr52244.c: New testcase. --- gcc-4.6.2/gcc/testsuite/gcc.dg/torture/pr52244.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.2/gcc/testsuite/gcc.dg/torture/pr52244.c 2012-02-18 20:06:34.000000000 +0100 @@ -0,0 +1,36 @@ +/* { dg-do run } */ + +extern void abort (void); + +typedef union u_r +{ + _Bool b; + unsigned char c; +} u_t; + +u_t +bar (void) +{ + u_t u; + u.c = 0x12; + return u; +} + +u_t __attribute__ ((noinline)) +foo (void) +{ + u_t u; + + u.b = 1; + u = bar (); + + return u; +} + +int main (int argc, char **argv) +{ + u_t u = foo (); + if (u.c != 0x12) + abort (); + return 0; +} --- gcc-4.6.2/gcc/tree-sra.c.~1~ 2012-02-18 20:01:47.000000000 +0100 +++ gcc-4.6.2/gcc/tree-sra.c 2012-02-18 20:06:34.000000000 +0100 @@ -1993,11 +1993,21 @@ analyze_access_subtree (struct access *r && (root->grp_scalar_write || root->grp_assignment_write)))) { bool new_integer_type; - if (TREE_CODE (root->type) == ENUMERAL_TYPE) + /* Always create access replacements that cover the whole access. + For integral types this means the precision has to match. + Avoid assumptions based on the integral type kind, too. */ + if (INTEGRAL_TYPE_P (root->type) + && (TREE_CODE (root->type) != INTEGER_TYPE + || TYPE_PRECISION (root->type) != root->size) + /* But leave bitfield accesses alone. */ + && (root->offset % BITS_PER_UNIT) == 0) { tree rt = root->type; - root->type = build_nonstandard_integer_type (TYPE_PRECISION (rt), + root->type = build_nonstandard_integer_type (root->size, TYPE_UNSIGNED (rt)); + root->expr = build_ref_for_offset (UNKNOWN_LOCATION, + root->base, root->offset, + root->type, NULL, false); new_integer_type = true; } else