diff mbox

Fix PR middle-end/54617

Message ID 6278136.nyUT2xYhuG@polaris
State New
Headers show

Commit Message

Eric Botcazou Sept. 18, 2012, 10:38 p.m. UTC
In the recent patch for PR rtl-opt/44194 I left a case potentially ICEing 
because I managed to have it covered neither on x86-64 nor on SPARC 64-bit.
This PR brings the missing coverage and it's from the gcc.c-torture/compile 
testsuite on PowerPC/Darwin 64-bit.

Bootstrapped/regtested on x86-64/Linux, generated code manually inspected on 
PowerPC/Darwin 64-bit, applied on the mainline.


2012-09-18  Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/54617
	* expr.c (store_field): Handle a PARALLEL in more cases.
diff mbox

Patch

Index: expr.c
===================================================================
--- expr.c	(revision 191365)
+++ expr.c	(working copy)
@@ -6452,16 +6452,33 @@  store_field (rtx target, HOST_WIDE_INT b
 
       /* Handle calls that return values in multiple non-contiguous locations.
 	 The Irix 6 ABI has examples of this.  */
-      if (bitpos == 0
-	  && bitsize == GET_MODE_BITSIZE (mode)
-	  && GET_CODE (temp) == PARALLEL)
-	emit_group_store (target, temp, TREE_TYPE (exp),
-			  int_size_in_bytes (TREE_TYPE (exp)));
-      else
-	/* Store the value in the bitfield.  */
-	store_bit_field (target, bitsize, bitpos,
-		         bitregion_start, bitregion_end,
-		         mode, temp);
+      if (GET_CODE (temp) == PARALLEL)
+	{
+	  rtx temp_target;
+
+	  /* We are not supposed to have a true bitfield in this case.  */
+	  gcc_assert (bitsize == GET_MODE_BITSIZE (mode));
+
+	  /* If we don't store at bit 0, we need an intermediate pseudo
+	     since emit_group_store only stores at bit 0.  */
+	  if (bitpos != 0)
+	    temp_target = gen_reg_rtx (mode);
+	  else
+	    temp_target = target;
+
+	  emit_group_store (temp_target, temp, TREE_TYPE (exp),
+			    int_size_in_bytes (TREE_TYPE (exp)));
+
+	  if (temp_target == target)
+	    return const0_rtx;
+
+	  temp = temp_target;
+	}
+
+      /* Store the value in the bitfield.  */
+      store_bit_field (target, bitsize, bitpos,
+		       bitregion_start, bitregion_end,
+		       mode, temp);
 
       return const0_rtx;
     }