]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/54617 (ICE on gcc.c-torture/compile/pr42025-2.c with -m64 and -O1)
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 18 Sep 2012 22:42:18 +0000 (22:42 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 18 Sep 2012 22:42:18 +0000 (22:42 +0000)
PR middle-end/54617
* expr.c (store_field): Handle a PARALLEL in more cases.

From-SVN: r191451

gcc/ChangeLog
gcc/expr.c

index d8c0e23c013d64b0dea7b0e6363f8e0d40975f25..ed8d8b1575b8f1a0d2d45e0b64119d586f607e84 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-18  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR middle-end/54617
+       * expr.c (store_field): Handle a PARALLEL in more cases.
+
 2012-09-18  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/rs6000.md (sminsi3, smaxsi3, uminsi3, umaxsi3):
index c53f1a8dc9b7d0dba5ddb88e3c923acaaf430933..36f4dd7d53ec1626e4d795e502a78c100e62bb85 100644 (file)
@@ -6452,16 +6452,33 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
 
       /* 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;
     }