diff options
Diffstat (limited to 'gcc/calls.cc')
| -rw-r--r-- | gcc/calls.cc | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/gcc/calls.cc b/gcc/calls.cc index bb8a6d0..85d6ea4 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -3579,7 +3579,8 @@ expand_call (tree exp, rtx target, int ignore) && check_sibcall_argument_overlap (before_arg, &args[i], true))) sibcall_failure = true; - } + gcc_checking_assert (!args[i].stack || argblock); + } if (args[i].stack) call_fusage @@ -3676,6 +3677,32 @@ expand_call (tree exp, rtx target, int ignore) && !must_preallocate && reg_parm_stack_space > 0) anti_adjust_stack (GEN_INT (reg_parm_stack_space)); + /* Cover pushed arguments with call usage, so that cselib knows to + invalidate the stores in them at the call insn. */ + if (pass == 1 && !argblock + && (maybe_ne (adjusted_args_size.constant, 0) + || adjusted_args_size.var)) + { + rtx addr = virtual_outgoing_args_rtx; + poly_int64 size = adjusted_args_size.constant; + if (!STACK_GROWS_DOWNWARD) + { + if (adjusted_args_size.var) + /* ??? We can't compute the exact base address. */ + addr = gen_rtx_PLUS (GET_MODE (addr), addr, + gen_rtx_SCRATCH (GET_MODE (addr))); + else + addr = plus_constant (GET_MODE (addr), addr, -size); + } + rtx fu = gen_rtx_MEM (BLKmode, addr); + if (adjusted_args_size.var == 0) + set_mem_size (fu, size); + call_fusage + = gen_rtx_EXPR_LIST (BLKmode, + gen_rtx_USE (VOIDmode, fu), + call_fusage); + } + /* Pass the function the address in which to return a structure value. */ if (pass != 0 && structure_value_addr && ! structure_value_addr_parm) |
