aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/foldaddr-3.c28
-rw-r--r--gcc/tree-ssa-ccp.c19
4 files changed, 53 insertions, 3 deletions
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 <jh@suse.cz>
+
+ * tree-ssa-ccp (maybe_fold_offset_to_component_ref): Recurse into
+ multiple fields of union.
+
2007-04-09 Zdenek Dvorak <dvorakz@suse.cz>
* 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 <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/foldaddr-3.c: New file.
+
2007-04-08 Jan Hubicka <jh@suse.cz>
* 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)