From patchwork Sun Dec 16 09:56:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix PR rtl-optimization/55630 Date: Sat, 15 Dec 2012 23:56:56 -0000 From: Eric Botcazou X-Patchwork-Id: 206670 Message-Id: <5342027.huES4oqDll@polaris> To: gcc-patches@gcc.gnu.org This is an ICE for g++.dg/pr48660.C on HP-PA/Linux introduced by: http://gcc.gnu.org/ml/gcc-patches/2012-10/msg00745.html When I wrote it, I convinced myself that the HP-PA wasn't using the BLKmode registers path any more and wrapped everything in PARALLELs for return values, so it tested the change on MIPS instead. Now it turns out that, for sub-word structures, the HP-PA still uses BLKmode registers and the C++ testcase shows that the code doesn't correctly handle assignments from incoming return values to outgoing return values. Not clear why this didn't show up on MIPS... Tested on x86-64, HP-PA and MIPS/Linux, applied on the mainline. 2012-12-16 Eric Botcazou PR rtl-optimization/55630 * expr.c (expand_assignment): Do not call copy_blkmode_to_reg to move BLKmode return values to the return register. Index: expr.c =================================================================== --- expr.c (revision 194517) +++ expr.c (working copy) @@ -4920,7 +4920,12 @@ expand_assignment (tree to, tree from, b rtx temp; push_temp_slots (); - if (REG_P (to_rtx) && TYPE_MODE (TREE_TYPE (from)) == BLKmode) + + /* If the source is itself a return value, it still is in a pseudo at + this point so we can move it back to the return register directly. */ + if (REG_P (to_rtx) + && TYPE_MODE (TREE_TYPE (from)) == BLKmode + && TREE_CODE (from) != CALL_EXPR) temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from); else temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);