------- 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