"H.J. Lu" <hjl.to...@gmail.com> writes: > On Thu, Jul 3, 2025 at 11:02 PM Richard Sandiford > <richard.sandif...@arm.com> wrote: >> >> "H.J. Lu" <hjl.to...@gmail.com> writes: >> > Since a backend may ignore user type alignment for arguments passed on >> > stack, update alignment for arguments passed on stack when copying MEM's >> > memory attributes. >> > >> > gcc/ >> > >> > PR target/120839 >> > * emit-rtl.cc (set_mem_attrs): Update alignment for argument on >> > stack. >> > >> > gcc/testsuite/ >> > >> > PR target/120839 >> > * gcc.target/i386/pr120839-1.c: New test. >> > * gcc.target/i386/pr120839-2.c: Likewise. >> > >> > >> > -- >> > H.J. >> > >> > From 3f8a9bfb4beae47bfc0da20b517a5b3b06a1cbcc Mon Sep 17 00:00:00 2001 >> > From: "H.J. Lu" <hjl.to...@gmail.com> >> > Date: Sat, 28 Jun 2025 06:27:25 +0800 >> > Subject: [PATCH] Update alignment for argument on stack >> > >> > Since a backend may ignore user type alignment for arguments passed on >> > stack, update alignment for arguments passed on stack when copying MEM's >> > memory attributes. >> > >> > gcc/ >> > >> > PR target/120839 >> > * emit-rtl.cc (set_mem_attrs): Update alignment for argument on >> > stack. >> > >> > gcc/testsuite/ >> > >> > PR target/120839 >> > * gcc.target/i386/pr120839-1.c: New test. >> > * gcc.target/i386/pr120839-2.c: Likewise. >> > >> > Signed-off-by: H.J. Lu <hjl.to...@gmail.com> >> > --- >> > gcc/emit-rtl.cc | 14 ++++++++++++++ >> > gcc/testsuite/gcc.target/i386/pr120839-1.c | 14 ++++++++++++++ >> > gcc/testsuite/gcc.target/i386/pr120839-2.c | 19 +++++++++++++++++++ >> > 3 files changed, 47 insertions(+) >> > create mode 100644 gcc/testsuite/gcc.target/i386/pr120839-1.c >> > create mode 100644 gcc/testsuite/gcc.target/i386/pr120839-2.c >> > >> > diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc >> > index f4fc92bb37a..0d1616361ca 100644 >> > --- a/gcc/emit-rtl.cc >> > +++ b/gcc/emit-rtl.cc >> > @@ -389,6 +389,20 @@ set_mem_attrs (rtx mem, mem_attrs *attrs) >> > { >> > MEM_ATTRS (mem) = ggc_alloc<mem_attrs> (); >> > memcpy (MEM_ATTRS (mem), attrs, sizeof (mem_attrs)); >> > + if (MEM_EXPR (mem)) >> > + { >> > + tree base_address = get_base_address (MEM_EXPR (mem)); >> > + if (base_address && TREE_CODE (base_address) == PARM_DECL) >> > + { >> > + /* User alignment on type may be ignored for parameter >> > + passed on stack. */ >> > + tree type = TREE_TYPE (base_address); >> > + unsigned int alignment >> > + = targetm.calls.function_arg_boundary (TYPE_MODE (type), >> > + type); >> > + set_mem_align (mem, alignment); >> > + } >> > + } >> > } >> > } >> >> This doesn't feel like the right place to address this. set_mem_attrs >> is just supposed to install the attributes that it has been given, >> without second-guessing the contents. >> >> Where does the incorrect alignment ultimately come from? (As in, >> which piece of code creates the MEM and fails to give it the correct >> alignment?) > > x86 has > > static unsigned int > ix86_function_arg_boundary (machine_mode mode, const_tree type) > { > unsigned int align; > if (type) > { > /* Since the main variant type is used for call, we convert it to > the main variant type. */ > type = TYPE_MAIN_VARIANT (type); > align = TYPE_ALIGN (type); > if (TYPE_EMPTY_P (type)) > return PARM_BOUNDARY; > } > > Because of > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120900 > > for C, > > typedef struct { > long double a, b > } c __attribute__((aligned(32))); > > when such a variable is passed on stack, its alignment > on stack is 16, not 32. However, when set_mem_attrs ^^^^^^^^^^^^^^^^^^ > is called to set MEM_ALIGN for such a variable on stack, ^^^^^^^^^^^^^^^^^^^^^^^^^^ > it sets MEM_ALIGN to 32, instead of 16.
But what I meant was: which piece of code calls set_mem_attrs to set MEM_ALIGN in this case? The bug seems further up the call stack to me. Richard > But 16 is the > actual alignment on stack. This means that the incorrect > alignment is set exactly where my patch tries to change. > >> Richard >> >> > >> > diff --git a/gcc/testsuite/gcc.target/i386/pr120839-1.c >> > b/gcc/testsuite/gcc.target/i386/pr120839-1.c >> > new file mode 100644 >> > index 00000000000..74fbf876330 >> > --- /dev/null >> > +++ b/gcc/testsuite/gcc.target/i386/pr120839-1.c >> > @@ -0,0 +1,14 @@ >> > +/* { dg-do compile } */ >> > +/* { dg-options "-O2" } */ >> > + >> > +typedef struct >> > +{ >> > + long double a; >> > + long double b; >> > +} c __attribute__((aligned(32))); >> > +extern double d; >> > +void >> > +bar (c f) >> > +{ >> > + d = f.a; >> > +} >> > diff --git a/gcc/testsuite/gcc.target/i386/pr120839-2.c >> > b/gcc/testsuite/gcc.target/i386/pr120839-2.c >> > new file mode 100644 >> > index 00000000000..e5b711c966f >> > --- /dev/null >> > +++ b/gcc/testsuite/gcc.target/i386/pr120839-2.c >> > @@ -0,0 +1,19 @@ >> > +/* { dg-do compile } */ >> > +/* { dg-options "-O2" } */ >> > +/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-32,\[\\t >> > \]*%\[re\]?sp" } } */ >> > + >> > +typedef struct >> > +{ >> > + long double a; >> > + long double b; >> > +} c __attribute__((aligned(32))); >> > +extern c x; >> > +extern double d; >> > +extern void bar (c); >> > +void >> > +foo (void) >> > +{ >> > + x.a = d; >> > + x.b = d; >> > + bar (x); >> > +}