diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-09 14:35:51 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-09 14:35:51 +0000 |
commit | 3d8f99df8d63f366e1488547202bc0ad76bb18d3 (patch) | |
tree | 71d463d74a0a58f296740318049e7e99e52d9d90 /gcc | |
parent | ca1de3a62d14399000f480cd55dec6c1d79c463f (diff) | |
download | gcc-3d8f99df8d63f366e1488547202bc0ad76bb18d3.tar.gz |
2009-09-09 Richard Guenther <rguenther@suse.de>
PR middle-end/41317
* tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Remove
code dealing with plain pointer bases.
(maybe_fold_offset_to_reference): Likewise.
(maybe_fold_stmt_addition): Adjust.
* gcc.c-torture/execute/pr41317.c: New testcase.
* gcc.dg/tree-ssa/forwprop-11.c: XFAIL.
* gcc.dg/tree-ssa/forwprop-12.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151559 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr41317.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 104 |
6 files changed, 82 insertions, 69 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e6f096a01b3..f423067fbfa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2009-09-09 Richard Guenther <rguenther@suse.de> + PR middle-end/41317 + * tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Remove + code dealing with plain pointer bases. + (maybe_fold_offset_to_reference): Likewise. + (maybe_fold_stmt_addition): Adjust. + +2009-09-09 Richard Guenther <rguenther@suse.de> + * tree.c (free_lang_data_in_type): Do not free the type variant chains. (free_lang_data): Merge char_type_node with its properly signed diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 229c800ea74..7b1704321f1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-09-09 Richard Guenther <rguenther@suse.de> + + PR middle-end/41317 + * gcc.c-torture/execute/pr41317.c: New testcase. + * gcc.dg/tree-ssa/forwprop-11.c: XFAIL. + * gcc.dg/tree-ssa/forwprop-12.c: Likewise. + 2009-09-08 Dodji Seketeli <dodji@redhat.com> Fix some test breakages on Darwin diff --git a/gcc/testsuite/gcc.c-torture/execute/pr41317.c b/gcc/testsuite/gcc.c-torture/execute/pr41317.c new file mode 100644 index 00000000000..742068b9ad4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr41317.c @@ -0,0 +1,28 @@ +extern void abort (void); + +struct A +{ + int i; +}; +struct B +{ + struct A a; + int j; +}; + +static void +foo (struct B *p) +{ + ((struct A *)p)->i = 1; +} + +int main() +{ + struct A a; + a.i = 0; + foo ((struct B *)&a); + if (a.i != 1) + abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c index eaaa6dd4e24..73051ae9645 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c @@ -15,5 +15,5 @@ int g(int *p, int n) return q[-1]; } -/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c index a74809b609e..1c5ea02ba78 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c @@ -18,5 +18,5 @@ int bar(struct X *p, int i) /* We should have propagated the base array address through the address arithmetic into the memory access as an array access. */ -/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 14ffdfeb62b..61827a74ab4 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1818,8 +1818,7 @@ maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset, static tree maybe_fold_offset_to_component_ref (location_t loc, tree record_type, - tree base, tree offset, - tree orig_type, bool base_is_ptr) + tree base, tree offset, tree orig_type) { tree f, t, field_type, tail_array_field, field_offset; tree ret; @@ -1871,8 +1870,6 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type, if (cmp == 0 && useless_type_conversion_p (orig_type, field_type)) { - if (base_is_ptr) - base = build1 (INDIRECT_REF, record_type, base); t = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE); return t; } @@ -1897,13 +1894,8 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type, /* If we matched, then set offset to the displacement into this field. */ - if (base_is_ptr) - new_base = build1 (INDIRECT_REF, record_type, base); - else - new_base = base; - protected_set_expr_location (new_base, loc); - new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE); - protected_set_expr_location (new_base, loc); + new_base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE); + SET_EXPR_LOCATION (new_base, loc); /* Recurse to possibly find the match. */ ret = maybe_fold_offset_to_array_ref (loc, new_base, t, orig_type, @@ -1911,7 +1903,7 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type, if (ret) return ret; ret = maybe_fold_offset_to_component_ref (loc, field_type, new_base, t, - orig_type, false); + orig_type); if (ret) return ret; } @@ -1925,11 +1917,6 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type, /* 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) - { - base = build1 (INDIRECT_REF, record_type, base); - SET_EXPR_LOCATION (base, loc); - } base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE); SET_EXPR_LOCATION (base, loc); @@ -1938,7 +1925,7 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type, if (t) return t; return maybe_fold_offset_to_component_ref (loc, field_type, base, offset, - orig_type, false); + orig_type); } /* Attempt to express (ORIG_TYPE)BASE+OFFSET as BASE->field_of_orig_type @@ -1955,61 +1942,44 @@ maybe_fold_offset_to_reference (location_t loc, tree base, tree offset, { tree ret; tree type; - bool base_is_ptr = true; STRIP_NOPS (base); - if (TREE_CODE (base) == ADDR_EXPR) - { - base_is_ptr = false; - - base = TREE_OPERAND (base, 0); + if (TREE_CODE (base) != ADDR_EXPR) + return NULL_TREE; - /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union, - so it needs to be removed and new COMPONENT_REF constructed. - The wrong COMPONENT_REF are often constructed by folding the - (type *)&object within the expression (type *)&object+offset */ - if (handled_component_p (base)) + base = TREE_OPERAND (base, 0); + + /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union, + so it needs to be removed and new COMPONENT_REF constructed. + The wrong COMPONENT_REF are often constructed by folding the + (type *)&object within the expression (type *)&object+offset */ + if (handled_component_p (base)) + { + HOST_WIDE_INT sub_offset, size, maxsize; + tree newbase; + newbase = get_ref_base_and_extent (base, &sub_offset, + &size, &maxsize); + gcc_assert (newbase); + if (size == maxsize + && size != -1 + && !(sub_offset & (BITS_PER_UNIT - 1))) { - HOST_WIDE_INT sub_offset, size, maxsize; - tree newbase; - newbase = get_ref_base_and_extent (base, &sub_offset, - &size, &maxsize); - gcc_assert (newbase); - if (size == maxsize - && size != -1 - && !(sub_offset & (BITS_PER_UNIT - 1))) - { - base = newbase; - if (sub_offset) - offset = int_const_binop (PLUS_EXPR, offset, - build_int_cst (TREE_TYPE (offset), - sub_offset / BITS_PER_UNIT), 1); - } + base = newbase; + if (sub_offset) + offset = int_const_binop (PLUS_EXPR, offset, + build_int_cst (TREE_TYPE (offset), + sub_offset / BITS_PER_UNIT), 1); } - if (useless_type_conversion_p (orig_type, TREE_TYPE (base)) - && integer_zerop (offset)) - return base; - type = TREE_TYPE (base); } - else - { - base_is_ptr = true; - if (!POINTER_TYPE_P (TREE_TYPE (base))) - return NULL_TREE; - type = TREE_TYPE (TREE_TYPE (base)); - } - ret = maybe_fold_offset_to_component_ref (loc, type, base, offset, - orig_type, base_is_ptr); + if (useless_type_conversion_p (orig_type, TREE_TYPE (base)) + && integer_zerop (offset)) + return base; + type = TREE_TYPE (base); + + ret = maybe_fold_offset_to_component_ref (loc, type, base, offset, orig_type); if (!ret) - { - if (base_is_ptr) - { - base = build1 (INDIRECT_REF, type, base); - SET_EXPR_LOCATION (base, loc); - } - ret = maybe_fold_offset_to_array_ref (loc, - base, offset, orig_type, true); - } + ret = maybe_fold_offset_to_array_ref (loc, base, offset, orig_type, true); + return ret; } @@ -2286,7 +2256,7 @@ maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1) t = maybe_fold_offset_to_array_ref (loc, op0, op1, ptd_type, true); if (!t) t = maybe_fold_offset_to_component_ref (loc, TREE_TYPE (op0), op0, op1, - ptd_type, false); + ptd_type); if (t) { t = build1 (ADDR_EXPR, res_type, t); |