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.

Reply via email to