diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e827b573e3..3418ae77222 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-07-24 Richard Sandiford + + PR middle-end/61268 + * function.c (assign_parm_setup_reg): Prevent invalid sharing of + DECL_INCOMING_RTL and entry_parm. + (get_arg_pointer_save_area): Likewise arg_pointer_save_area. + * calls.c (load_register_parameters): Likewise argument values. + (emit_library_call_value_1, store_one_arg): Likewise argument + save areas. + * config/i386/i386.c (assign_386_stack_local): Likewise the local + stack slot. + * explow.c (validize_mem): Modify the argument in-place. + 2014-07-24 Jiong Wang * config/aarch64/aarch64.c (aarch64_popwb_single_reg): New function. diff --git a/gcc/calls.c b/gcc/calls.c index 78fe7d8525b..e8456528a59 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1937,7 +1937,7 @@ load_register_parameters (struct arg_data *args, int num_actuals, else if (partial == 0 || args[i].pass_on_stack) { - rtx mem = validize_mem (args[i].value); + rtx mem = validize_mem (copy_rtx (args[i].value)); /* Check for overlap with already clobbered argument area, providing that this has non-zero size. */ @@ -4014,7 +4014,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, argvec[argnum].locate.size.constant ); - emit_block_move (validize_mem (argvec[argnum].save_area), + emit_block_move (validize_mem + (copy_rtx (argvec[argnum].save_area)), stack_area, GEN_INT (argvec[argnum].locate.size.constant), BLOCK_OP_CALL_PARM); @@ -4289,7 +4290,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, if (save_mode == BLKmode) emit_block_move (stack_area, - validize_mem (argvec[count].save_area), + validize_mem + (copy_rtx (argvec[count].save_area)), GEN_INT (argvec[count].locate.size.constant), BLOCK_OP_CALL_PARM); else @@ -4433,7 +4435,8 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, arg->save_area = assign_temp (TREE_TYPE (arg->tree_value), 1, 1); preserve_temp_slots (arg->save_area); - emit_block_move (validize_mem (arg->save_area), stack_area, + emit_block_move (validize_mem (copy_rtx (arg->save_area)), + stack_area, GEN_INT (arg->locate.size.constant), BLOCK_OP_CALL_PARM); } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index bc0c42ef3b3..9de2035336c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25061,7 +25061,7 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n) s->next = ix86_stack_locals; ix86_stack_locals = s; - return validize_mem (s->rtl); + return validize_mem (copy_rtx (s->rtl)); } static void diff --git a/gcc/explow.c b/gcc/explow.c index e39db0507db..92c4e574dcb 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -518,8 +518,9 @@ memory_address_addr_space (enum machine_mode mode, rtx x, addr_space_t as) return x; } -/* Convert a mem ref into one with a valid memory address. - Pass through anything else unchanged. */ +/* If REF is a MEM with an invalid address, change it into a valid address. + Pass through anything else unchanged. REF must be an unshared rtx and + the function may modify it in-place. */ rtx validize_mem (rtx ref) @@ -531,8 +532,7 @@ validize_mem (rtx ref) MEM_ADDR_SPACE (ref))) return ref; - /* Don't alter REF itself, since that is probably a stack slot. */ - return replace_equiv_address (ref, XEXP (ref, 0)); + return replace_equiv_address (ref, XEXP (ref, 0), true); } /* If X is a memory reference to a member of an object block, try rewriting diff --git a/gcc/function.c b/gcc/function.c index 922ef3d7b2f..84d6a107c70 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2662,13 +2662,14 @@ assign_parm_adjust_entry_rtl (struct assign_parm_data_one *data) /* Handle calls that pass values in multiple non-contiguous locations. The Irix 6 ABI has examples of this. */ if (GET_CODE (entry_parm) == PARALLEL) - emit_group_store (validize_mem (stack_parm), entry_parm, + emit_group_store (validize_mem (copy_rtx (stack_parm)), entry_parm, data->passed_type, int_size_in_bytes (data->passed_type)); else { gcc_assert (data->partial % UNITS_PER_WORD == 0); - move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm), + move_block_from_reg (REGNO (entry_parm), + validize_mem (copy_rtx (stack_parm)), data->partial / UNITS_PER_WORD); } @@ -2837,7 +2838,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all, else gcc_assert (!size || !(PARM_BOUNDARY % BITS_PER_WORD)); - mem = validize_mem (stack_parm); + mem = validize_mem (copy_rtx (stack_parm)); /* Handle values in multiple non-contiguous locations. */ if (GET_CODE (entry_parm) == PARALLEL) @@ -2972,7 +2973,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, assign_parm_find_data_types and expand_expr_real_1. */ equiv_stack_parm = data->stack_parm; - validated_mem = validize_mem (data->entry_parm); + validated_mem = validize_mem (copy_rtx (data->entry_parm)); need_conversion = (data->nominal_mode != data->passed_mode || promoted_nominal_mode != data->promoted_mode); @@ -3228,7 +3229,7 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm, /* Conversion is required. */ rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm)); - emit_move_insn (tempreg, validize_mem (data->entry_parm)); + emit_move_insn (tempreg, validize_mem (copy_rtx (data->entry_parm))); push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn); to_conversion = true; @@ -3265,8 +3266,8 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm, set_mem_attributes (data->stack_parm, parm, 1); } - dest = validize_mem (data->stack_parm); - src = validize_mem (data->entry_parm); + dest = validize_mem (copy_rtx (data->stack_parm)); + src = validize_mem (copy_rtx (data->entry_parm)); if (MEM_P (src)) { @@ -5261,7 +5262,7 @@ get_arg_pointer_save_area (void) generated stack slot may not be a valid memory address, so we have to check it and fix it if necessary. */ start_sequence (); - emit_move_insn (validize_mem (ret), + emit_move_insn (validize_mem (copy_rtx (ret)), crtl->args.internal_arg_pointer); seq = get_insns (); end_sequence ();