expr.c (expand_assignment): Force an address offset computation into a register befor...
authorNick Clifton <nickc@redhat.com>
Tue, 14 Apr 2015 16:12:34 +0000 (16:12 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Tue, 14 Apr 2015 16:12:34 +0000 (16:12 +0000)
* expr.c (expand_assignment): Force an address offset computation
into a register before changing its mode.
(expand_expr_real_1): Likewise.

From-SVN: r222098

gcc/ChangeLog
gcc/expr.c

index e3ed96781059484539398d913faa730b928dac71..cf7f686de7f9ace0d16d2385df2cd81ae1510f62 100644 (file)
@@ -1,3 +1,9 @@
+2015-04-14  Nick Clifton  <nickc@redhat.com>
+
+       * expr.c (expand_assignment): Force an address offset computation
+       into a register before changing its mode.
+       (expand_expr_real_1): Likewise.
+
 2015-04-14  Alan Lawrence  <alan.lawrence@arm.com>
 
        * config/aarch64/arm_neon.h (vst1_lane_f32, vst1_lane_f64,
index 5c095507f4a303b1c4ab3519d165735be5a37d07..530a944da46152d07da226389ff78086937efcfa 100644 (file)
@@ -4879,7 +4879,13 @@ expand_assignment (tree to, tree from, bool nontemporal)
          offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
          address_mode = get_address_mode (to_rtx);
          if (GET_MODE (offset_rtx) != address_mode)
-           offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
+           {
+               /* We cannot be sure that the RTL in offset_rtx is valid outside
+                  of a memory address context, so force it into a register
+                  before attempting to convert it to the desired mode.  */
+             offset_rtx = force_operand (offset_rtx, NULL_RTX);
+             offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
+           }
 
          /* If we have an expression in OFFSET_RTX and a non-zero
             byte offset in BITPOS, adding the byte offset before the
@@ -10258,7 +10264,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 
            address_mode = get_address_mode (op0);
            if (GET_MODE (offset_rtx) != address_mode)
-             offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
+             {
+               /* We cannot be sure that the RTL in offset_rtx is valid outside
+                  of a memory address context, so force it into a register
+                  before attempting to convert it to the desired mode.  */
+               offset_rtx = force_operand (offset_rtx, NULL_RTX);
+               offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
+             }
 
            /* See the comment in expand_assignment for the rationale.  */
            if (mode1 != VOIDmode