@@ -4777,6 +4777,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
tree offset;
int unsignedp;
int volatilep = 0;
+ rtx spilled_reg = NULL_RTX;
tree tem;
push_temp_slots ();
@@ -4828,11 +4829,23 @@ expand_assignment (tree to, tree from, bool nontemporal)
if (!MEM_P (to_rtx))
{
- /* We can get constant negative offsets into arrays with broken
- user code. Translate this to a trap instead of ICEing. */
- gcc_assert (TREE_CODE (offset) == INTEGER_CST);
- expand_builtin_trap ();
- to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
+ if (TREE_CODE (offset) == INTEGER_CST)
+ {
+ /* We have an invalid constant index into a register array.
+ Emit a trap and move on. */
+ expand_builtin_trap ();
+ to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
+ }
+ else
+ {
+ /* We have a non-constant index to a register array. Perform
+ the indexed store by spilling the register. */
+ spilled_reg = to_rtx;
+ to_rtx = assign_stack_temp
+ (GET_MODE (to_rtx),
+ GET_MODE_SIZE (GET_MODE (to_rtx)));
+ emit_move_insn (to_rtx, spilled_reg);
+ }
}
offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
@@ -4959,6 +4972,9 @@ expand_assignment (tree to, tree from, bool nontemporal)
get_alias_set (to), nontemporal);
}
+ if (spilled_reg)
+ emit_move_insn (spilled_reg, to_rtx);
+
if (result)
preserve_temp_slots (result);
pop_temp_slots ();