On Tue, Jul 21, 2026 at 9:49 AM H.J. Lu <[email protected]> wrote:
>
> On Tue, Jul 21, 2026 at 3:10 PM Sam James <[email protected]> wrote:
> >
> > "H.J. Lu" <[email protected]> writes:
> >
> > > commit b4c215b36d63e1c264d8c1bd5d34f9aef1bb8463
> > > Author: H.J. Lu <[email protected]>
> > > Date: Sat Jun 28 06:27:25 2025 +0800
> > >
> > > Adjust check for addressable misaligned stack argument
> > >
> > > ignores arguments passed on stack since caller is responsible to align
> > > the outgoing stack for arguments passed on stack. However, callee may
> > > spill a register argument:
> > >
> > > (set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
> > > (const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
> > > (reg:V2DI 20 xmm0 [ a1 ]))
> > >
> > > Update ix86_argument_passed_on_stack_p to check spill of register argument
> > > by callee.
> > >
> > > gcc/
> > >
> > > PR target/126320
> > > * config/i386/i386.cc (ix86_spill_register_argument_p): New
> > > function.
> > > (ix86_argument_passed_on_stack_p): Add a pattern argument. Call
> > > ix86_spill_register_argument_p to check spill of register argument
> > > by callee.
> > > (ix86_update_stack_alignment): Pass pat to
> > > ix86_argument_passed_on_stack_p.
> > >
> > > gcc/testsuite/
> > >
> > > PR target/126320
> > > * gcc.target/i386/pr126320.c: New test.
> >
> > IMO for tests of this shape where we do builtin_cpu_supports, we should
> > build the file without -march, but use the target attribute on the
> > called function. It is paranoid but it means we don't have a lot of pain
> > if (somehow) we use other instructions in main, and it sets a good
> > example for copying.
>
> Good point. Here is the v2 patch without -mavx2. -march=x86-64
> is needed to enable SSE register parameter passing.
I took the liberty and rewrite comments to be more comprehensible:
--cut here--
/* PAT is a SET whose destination is OP, a MEM tied to parameter BASE.
Return true if PAT stores BASE's own argument register into OP,
i.e. PAT is a callee-side spill of that register, not a caller-set-up
stack argument:
(set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
(const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
(reg:V2DI 20 xmm0 [ a1 ]))
*/
static bool
ix86_spill_register_argument_p (const_rtx set, const_rtx op, tree base)
{
rtx src = SET_SRC (set);
/* Not a hard-reg store, so not a spill. */
if (!REG_P (src) || !HARD_REGISTER_P (src))
return false;
rtx dest = SET_DEST (set);
tree reg_expr = REG_EXPR (src);
return dest == op && reg_expr == base;
}
--cut here--
The PARALLEL branch in the new ix86_argument_passed_on_stack_p looks
unreachable. This function is only called from
ix86_update_stack_alignment, which is a note_stores callback.
note_stores already unwraps PARALLEL patterns and invokes the callback
once per top-level SET/CLOBBER. So pat at this call site should never
itself be a PARALLEL; the loop over XVECEXP (pat, 0, i) can't fire.
--cut here--
/* Return true if OP, found in PAT, is a caller-supplied stack argument
(already aligned by the caller) rather than a register argument the
callee spilled to its own frame -- both share the same MEM_EXPR. */
static bool
ix86_argument_passed_on_stack_p (const_rtx op, const_rtx pat)
{
tree mem_expr = MEM_EXPR (op);
if (!mem_expr)
return false;
tree var = get_base_address (mem_expr);
if (TREE_CODE (var) != PARM_DECL)
return false;
/* PAT is always a single SET here (note_stores unwraps PARALLELs). */
if (GET_CODE (pat) == SET)
return !ix86_spill_register_argument_p (pat, op, var);
return true;
}
--cut here--
Please review the new comments.
Uros.