Fix PR rtl-optimization/55630

Message ID 5342027.huES4oqDll@polaris
State New
Headers show

Commit Message

Eric Botcazou Dec. 16, 2012, 9:56 a.m.
This is an ICE for g++.dg/pr48660.C on HP-PA/Linux introduced by:

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);
 	temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);