------- Comment #2 from jakub at gcc dot gnu dot org 2007-11-07 21:01 -------
This stems from the inliner, which changes:
result_end_9 = &<retval>.elems[0] + D.2223_8;
into:
result_end_6 = &this_2(D)->n_cells.elems[0] + D.2233_5;
While the former is valid GIMPLE, as &<retval> is TREE_INVARIANT, this is not
marked so.
copy_bb has:
805 /* With return slot optimization we can end up with
806 non-gimple (foo *)&this->m, fix that here. */
807 if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
808 && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR
809 && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND
(stmt, 1), 0)))
810 gimplify_stmt (&stmt);
to handle some of the cases of this and copy_phis_for_bb chunk I've recently
added too:
1196 /* With return slot optimization we can end up with
1197 non-gimple (foo *)&this->m, fix that here. */
1198 if (TREE_CODE (new_arg) != SSA_NAME
1199 && TREE_CODE (new_arg) != FUNCTION_DECL
1200 && !is_gimple_val (new_arg))
1201 {
1202 tree stmts = NULL_TREE;
1203 new_arg = force_gimple_operand (new_arg, &stmts,
1204 true, NULL);
1205 bsi_insert_on_edge_immediate (new_edge, stmts);
(gdb)
1206 }
But the copy_bb hunk only handles some cases, particularly where the &<result>
-> this replacement was done on the right side of GIMPLE_MODIFY_STMT. But as
can be seen on this testcase, it can happen in many other places.
Blindly doing a gimplify_stmt is dangerous though, because VLA types could be
involved somewhere and gimplifying them again perhaps could introduce trouble.
SO I guess we just need to note the replacement of TREE_INVARIANT with
non-invariant and gimplify just it into a new temporary.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34018