&& 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
&& !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)
--- /dev/null
+/* PR rtl-optimization/122947 based on PR 117239 */
+/* { dg-do run } */
+/* { dg-options "-fno-inline -O2" } */
+/* { dg-additional-options "-fschedule-insns -mno-accumulate-outgoing-args" { target x86 } } */
+
+int c = 1;
+
+struct A {
+ int e, f, g, h;
+ short i;
+ int j;
+};
+
+void
+bar (int x, struct A y)
+{
+ if (y.j == 1)
+ c = 0;
+}
+
+/* Simplest pure way to force baz's x.j back to memory.
+ So simple that IPA "inlines" it, so we disable IPA and mark as pure. */
+int __attribute__ ((noipa, pure))
+bad (struct A const *x)
+{
+ return x->j;
+}
+
+int
+baz (struct A x)
+{
+ x.j = 0;
+ return bad (&x);
+}
+
+int
+main ()
+{
+ struct A k = { 0, 0, 0, 0, 0, 1 };
+ int d = baz (k);
+ bar (0, k);
+ if (c + d != 0)
+ __builtin_abort ();
+ return 0;
+}