diff options
| author | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-12-01 17:39:44 +0000 |
|---|---|---|
| committer | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-12-01 17:39:44 +0000 |
| commit | c77fa5484e7c9746a0992b3db5a69a2fed5ef8d2 (patch) | |
| tree | 53d7b9d714ee4065887856ae83a6c37f3a1a9412 | |
| parent | edbb328f08335dc95672cc24f135acd556c195cd (diff) | |
| download | ppe42-gcc-c77fa5484e7c9746a0992b3db5a69a2fed5ef8d2.tar.gz ppe42-gcc-c77fa5484e7c9746a0992b3db5a69a2fed5ef8d2.zip | |
2009-12-01 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/42237
* tree-sra.c (sra_ipa_modify_assign): Split gimple_reg_type assignments
in between references into two.
* testsuite/gcc.c-torture/compile/pr42237.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154874 138bc75d-0d04-0410-961f-82ee72b054a4
| -rw-r--r-- | gcc/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr42237.c | 32 | ||||
| -rw-r--r-- | gcc/tree-sra.c | 18 |
4 files changed, 57 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 939b7bce54c..3b15962e71f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-12-01 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/42237 + * tree-sra.c (sra_ipa_modify_assign): Split gimple_reg_type assignments + in between references into two. + 2009-12-01 Richard Guenther <rguenther@suse.de> * tree-inline.c (copy_tree_body_r): Do not set TREE_BLOCK diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bfc58ea6b3a..c691529d995 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-12-01 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/42237 + * gcc.c-torture/compile/pr42237.c: New test. + 2009-12-01 Paolo Carlini <paolo.carlini@oracle.com> PR c++/42057 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr42237.c b/gcc/testsuite/gcc.c-torture/compile/pr42237.c new file mode 100644 index 00000000000..58db8660ca3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr42237.c @@ -0,0 +1,32 @@ +struct A +{ + int p; +}; + +struct B +{ + struct A n; + struct A m; + int x; + int y; + int z; +}; + +extern int g1, g2; + +static void __attribute__((noinline)) foo (struct B *b) +{ + int t; + + t = b->n.p; + g1 = t; + b->n.p = t+1; + g2 = b->m.p; + + b->m = b->n; +} + +void bar (struct B *b) +{ + foo (b); +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 2c75838835a..a6a1a90d757 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3707,12 +3707,22 @@ sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data) any |= sra_ipa_modify_expr (lhs_p, gsi, true, data); if (any) { + tree new_rhs = NULL_TREE; + if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p))) + new_rhs = fold_build1_loc (gimple_location (stmt), VIEW_CONVERT_EXPR, + TREE_TYPE (*lhs_p), *rhs_p); + else if (REFERENCE_CLASS_P (*rhs_p) + && is_gimple_reg_type (TREE_TYPE (*lhs_p)) + && !is_gimple_reg (*lhs_p)) + /* This can happen when an assignment in between two single field + structures is turned into an assignment in between two pointers to + scalars (PR 42237). */ + new_rhs = *rhs_p; + + if (new_rhs) { - location_t loc = gimple_location (stmt); - tree vce = fold_build1_loc (loc, VIEW_CONVERT_EXPR, - TREE_TYPE (*lhs_p), *rhs_p); - tree tmp = force_gimple_operand_gsi (gsi, vce, true, NULL_TREE, + tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE, true, GSI_SAME_STMT); gimple_assign_set_rhs_from_tree (gsi, tmp); |

