On Wed, Nov 20, 2024 at 9:55 PM Richard Sandiford <richard.sandif...@arm.com>
wrote:

> "H.J. Lu" <hjl.to...@gmail.com> writes:
> > On Wed, Nov 20, 2024 at 2:12 AM Richard Sandiford
> > <richard.sandif...@arm.com> wrote:
> >>
> >> "H.J. Lu" <hjl.to...@gmail.com> writes:
> >> > Adjust BLKmode argument size for parameter alignment for sibcall
> check.
> >> >
> >> > gcc/
> >> >
> >> > PR middle-end/117098
> >> > * calls.cc (store_one_arg): Adjust BLKmode argument size for
> >> > alignment padding for sibcall check.
> >> >
> >> > gcc/testsuite/
> >> >
> >> > PR middle-end/117098
> >> > * gcc.dg/sibcall-12.c: New test.
> >> >
> >> > OK for master?
> >> >
> >> >
> >> > H.J.
> >> > From 8b0518906cb23a9b5e77b04d6132c49047daebd2 Mon Sep 17 00:00:00 2001
> >> > From: "H.J. Lu" <hjl.to...@gmail.com>
> >> > Date: Sun, 13 Oct 2024 04:53:14 +0800
> >> > Subject: [PATCH] sibcall: Adjust BLKmode argument size for alignment
> padding
> >> >
> >> > Adjust BLKmode argument size for parameter alignment for sibcall
> check.
> >> >
> >> > gcc/
> >> >
> >> >       PR middle-end/117098
> >> >       * calls.cc (store_one_arg): Adjust BLKmode argument size for
> >> >       alignment padding for sibcall check.
> >> >
> >> > gcc/testsuite/
> >> >
> >> >       PR middle-end/117098
> >> >       * gcc.dg/sibcall-12.c: New test.
> >> >
> >> > Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
> >> > ---
> >> >  gcc/calls.cc                      |  4 +++-
> >> >  gcc/testsuite/gcc.dg/sibcall-12.c | 13 +++++++++++++
> >> >  2 files changed, 16 insertions(+), 1 deletion(-)
> >> >  create mode 100644 gcc/testsuite/gcc.dg/sibcall-12.c
> >> >
> >> > diff --git a/gcc/calls.cc b/gcc/calls.cc
> >> > index c5c26f65280..163c7e509d9 100644
> >> > --- a/gcc/calls.cc
> >> > +++ b/gcc/calls.cc
> >> > @@ -5236,7 +5236,9 @@ store_one_arg (struct arg_data *arg, rtx
> argblock, int flags,
> >> >             /* expand_call should ensure this.  */
> >> >             gcc_assert (!arg->locate.offset.var
> >> >                         && arg->locate.size.var == 0);
> >> > -           poly_int64 size_val = rtx_to_poly_int64 (size_rtx);
> >> > +           /* Adjust for argument alignment padding.  */
> >> > +           poly_int64 size_val = ROUND_UP (UINTVAL (size_rtx),
> >> > +                                           parm_align /
> BITS_PER_UNIT);
> >>
> >> This doesn't look right to me.  For one thing, going from
> >> rtx_to_poly_int64 to UINTVAL drops support for non-constant parameters.
> >> But even ignoring that, I think padding size_val (the size of arg->value
> >> IIUC) will pessimise the later:
> >>
> >>               else if (maybe_in_range_p (arg->locate.offset.constant,
> >>                                          i, size_val))
> >>                 sibcall_failure = true;
> >>
> >> and so cause sibcall failures elsewhere.  I'm also not sure this
> >> accurately reproduces the padding that is added by locate_and_pad_parm
> >> for all cases (arguments that grow up vs down, padding below vs above
> >> the argument).
> >>
> >> AIUI, the point of the:
> >>
> >>               if (known_eq (arg->locate.offset.constant, i))
> >>                 {
> >>                   /* Even though they appear to be at the same location,
> >>                      if part of the outgoing argument is in registers,
> >>                      they aren't really at the same location.  Check for
> >>                      this by making sure that the incoming size is the
> >>                      same as the outgoing size.  */
> >>                   if (maybe_ne (arg->locate.size.constant, size_val))
> >>                     sibcall_failure_1 = true;
> >>                 }
> >
> > Does this
> >
> > diff --git a/gcc/calls.cc b/gcc/calls.cc
> > index 246abe34243..98429cc757f 100644
> > --- a/gcc/calls.cc
> > +++ b/gcc/calls.cc
> > @@ -5327,7 +5327,13 @@ store_one_arg (struct arg_data *arg, rtx
> > argblock, int flags,
> >            they aren't really at the same location.  Check for
> >            this by making sure that the incoming size is the
> >            same as the outgoing size.  */
> > -       if (maybe_ne (arg->locate.size.constant, size_val))
> > +       poly_int64 aligned_size;
> > +       if (CONST_INT_P (size_rtx))
> > +         aligned_size = ROUND_UP (UINTVAL (size_rtx),
> > +                   parm_align / BITS_PER_UNIT);
> > +       else
> > +         aligned_size = size_val;
> > +       if (maybe_ne (arg->locate.size.constant, aligned_size))
> >           sibcall_failure = true;
> >       }
> >          else if (maybe_in_range_p (arg->locate.offset.constant,
> >
> > look correct?
>
> Heh.  Playing the reviewer here, I was kind-of hoping you'd explain
> why it was correct to me :)
>
> But conceptually, the call is copying from arg->value to arg->locate.
> And this code is trying to detect whether the copy is a nop, whether
> it overlaps, or whether the source and destination are distinct.
>
> It feels odd to grow the size of arg->value (the source of the copy),
> given that the extra bytes shouldn't be copied.
>
> Like I mentioned in the previous reply, it feels to me like testing
> partial != 0 would deal with the situation described in the comment,
> and the testcase in PR32602.  Personally I think we should try that first.
> Maybe it's wrong (quite probable), but if so, it'd be good to know and
>

Like this?

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 246abe34243..b85b22264de 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -5327,7 +5327,7 @@ store_one_arg (struct arg_data *arg, rtx argblock,
int flags,
           they aren't really at the same location.  Check for
           this by making sure that the incoming size is the
           same as the outgoing size.  */
-       if (maybe_ne (arg->locate.size.constant, size_val))
+       if (partial != 0)
          sibcall_failure = true;
      }
         else if (maybe_in_range_p (arg->locate.offset.constant,

Thanks.


> understand why.
>
> If that fails, perhaps a fallback would be to test:
>
>     maybe_lt (arg->locate.size.constant, size_val)
>
> instead.  I think the code is worried about the case where the stack
> slot is smaller than the number of bytes in the source value (because
> some of the source value is passed in registers instead).  But the fact
> that arg->locate.size includes padding seems to undermine the current
> test, which is why partial != 0 seems like it would be more direct
> and robust (if it works).
>
> Thanks,
> Richard
>


-- 
H.J.

Reply via email to