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? Thanks. > that you cite in the PR is to make sure that the nth byte of arg->value > corresponds to arg->locate.offset.constant + n. It's not clear to me > why the original fix for PR32602 didn't just check partial != 0. > Perhaps it was just for consistency with the neighbouring overlap check, > or maybe it was for some deeper reason. > > Thanks, > Richard > > > > > if (known_eq (arg->locate.offset.constant, i)) > > { > > diff --git a/gcc/testsuite/gcc.dg/sibcall-12.c > > b/gcc/testsuite/gcc.dg/sibcall-12.c > > new file mode 100644 > > index 00000000000..5773c9c1c4a > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/sibcall-12.c > > @@ -0,0 +1,13 @@ > > +// Test for sibcall optimization with struct aligned on stack. > > +// { dg-options "-O2" } > > +// { dg-final { scan-assembler "jmp" { target i?86-*-* x86_64-*-* } } } > > + > > +struct A { char a[17]; }; > > + > > +int baz (int a, int b, int c, void *p, struct A s, struct A); > > + > > +int > > +foo (int a, int b, int c, void *p, struct A s, struct A s2) > > +{ > > + return baz (a, b, c, p, s, s2); > > +} -- H.J.