From 8085c586613ba2905acd555b0b4bd6bf265f1f43 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 14 Feb 2012 15:33:56 +0000 Subject: [PATCH] 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 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 --- gcc/ChangeLog | 7 +++++ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.dg/torture/pr52244.c | 36 ++++++++++++++++++++++++++ gcc/tree-sra.c | 14 ++++++++-- 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr52244.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eca470c3cc8..407a61fdd6c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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. + 2012-02-14 Walter Lee * config.gcc: Handle tilegx and tilepro. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05a6af0e1bc..963e1bfd320 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-02-14 Richard Guenther + + PR tree-optimization/52244 + PR tree-optimization/51528 + * gcc.dg/torture/pr52244.c: New testcase. + 2012-02-14 Walter Lee * 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 00000000000..2a29e3cf420 --- /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 e2091e5fda4..1439c43c889 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 -- 2.30.2