diff options
author | Richard Guenther <rguenther@suse.de> | 2012-02-14 15:33:56 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-02-14 15:33:56 +0000 |
commit | 8085c586613ba2905acd555b0b4bd6bf265f1f43 (patch) | |
tree | c501248fa589afafc35f7a550a5f38592d411785 /gcc | |
parent | 31772c9507ed3c9f69565efa9dd80dcd8c72b0ba (diff) | |
download | gcc-8085c586613ba2905acd555b0b4bd6bf265f1f43.zip gcc-8085c586613ba2905acd555b0b4bd6bf265f1f43.tar.gz gcc-8085c586613ba2905acd555b0b4bd6bf265f1f43.tar.bz2 |
re PR middle-end/52244 (wrong code for function returning union between int and _Bool at O > 2, with no-early-inlining)
2012-02-14 Richard Guenther <rguenther@suse.de>
PR tree-optimization/52244
PR tree-optimization/51528
* tree-sra.c (analyze_access_subtree): Only create INTEGER_TYPE
replacements for integral types.
* gcc.dg/torture/pr52244.c: New testcase.
From-SVN: r184214
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr52244.c | 36 | ||||
-rw-r--r-- | gcc/tree-sra.c | 14 |
4 files changed, 61 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eca470c..407a61f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-02-14 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/52244 + PR tree-optimization/51528 + * tree-sra.c (analyze_access_subtree): Only create INTEGER_TYPE + replacements for integral types. + 2012-02-14 Walter Lee <walt@tilera.com> * config.gcc: Handle tilegx and tilepro. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05a6af0..963e1bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-02-14 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/52244 + PR tree-optimization/51528 + * gcc.dg/torture/pr52244.c: New testcase. + 2012-02-14 Walter Lee <walt@tilera.com> * g++.dg/other/PR23205.C: Disable test on tile. diff --git a/gcc/testsuite/gcc.dg/torture/pr52244.c b/gcc/testsuite/gcc.dg/torture/pr52244.c new file mode 100644 index 0000000..2a29e3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr52244.c @@ -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; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index e2091e5..1439c43 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2172,11 +2172,21 @@ analyze_access_subtree (struct access *root, struct access *parent, && (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 |