From d9745cea0edd0db7c11861860449a97e00dcb575 Mon Sep 17 00:00:00 2001 From: hubicka Date: Mon, 9 Apr 2007 17:00:10 +0000 Subject: [PATCH] * gcc.dg/tree-ssa/foldaddr-3.c: New file. * tree-ssa-ccp (maybe_fold_offset_to_component_ref): Recurse into multiple fields of union. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123674 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/tree-ssa/foldaddr-3.c | 28 ++++++++++++++++++++++++++++ gcc/tree-ssa-ccp.c | 19 ++++++++++++++++--- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/foldaddr-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0309e9f..5213472 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-04-09 Jan Hubicka + + * tree-ssa-ccp (maybe_fold_offset_to_component_ref): Recurse into + multiple fields of union. + 2007-04-09 Zdenek Dvorak * cfgloopmanip.c (create_preheader): Do not use loop_preheader_edge. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 64c6cf6..90550f2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-04-09 Jan Hubicka + + * gcc.dg/tree-ssa/foldaddr-3.c: New file. + 2007-04-08 Jan Hubicka * gcc.dg/tree-ssa/foldaddr-2.c: New file. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/foldaddr-3.c b/gcc/testsuite/gcc.dg/tree-ssa/foldaddr-3.c new file mode 100644 index 0000000..b764187 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/foldaddr-3.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ +union a +{ + struct s1 + { + long long a; + long long b; + } s1; + struct s2 + { + int c; + int d; + } s2; + struct s3 + { + unsigned long long e; + unsigned long long f; + } s3; +} a; +int * +t () +{ + return (int *) &a; +} + +/* { dg-final { scan-tree-dump "a.s2.c" "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index ebf2708..8e4d88c 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1648,6 +1648,8 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, tree orig_type, bool base_is_ptr) { tree f, t, field_type, tail_array_field, field_offset; + tree ret; + tree new_base; if (TREE_CODE (record_type) != RECORD_TYPE && TREE_CODE (record_type) != UNION_TYPE @@ -1719,8 +1721,20 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, /* If we matched, then set offset to the displacement into this field. */ - offset = t; - goto found; + if (base_is_ptr) + new_base = build1 (INDIRECT_REF, record_type, base); + else + new_base = base; + new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE); + + /* Recurse to possibly find the match. */ + ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type); + if (ret) + return ret; + ret = maybe_fold_offset_to_component_ref (field_type, new_base, t, + orig_type, false); + if (ret) + return ret; } if (!tail_array_field) @@ -1730,7 +1744,6 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, field_type = TREE_TYPE (f); offset = int_const_binop (MINUS_EXPR, offset, byte_position (f), 1); - found: /* If we get here, we've got an aggregate field, and a possibly nonzero offset into them. Recurse and hope for a valid match. */ if (base_is_ptr) -- 2.7.4