On Tue, Jul 8, 2025 at 5:02 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > On Mon, Jul 7, 2025 at 11:08 PM Jason Merrill <ja...@redhat.com> wrote: > > > > On 7/1/25 5:36 PM, H.J. Lu wrote: > > > On Tue, Jul 1, 2025 at 9:37 PM Jason Merrill <ja...@redhat.com> wrote: > > >> > > >> On 6/30/25 7:03 PM, H.J. Lu wrote: > > >>> On Mon, Jun 30, 2025 at 10:36 PM Jason Merrill <ja...@redhat.com> wrote: > > >>>> > > >>>> On 6/28/25 7:00 AM, H.J. Lu wrote: > > >>>>> Since a backend may ignore user type alignment for arguments passed on > > >>>>> stack, check backend for argument alignment on stack when evaluating > > >>>>> __alignof. > > >>>> > > >>>> I assume that's reflected in DECL_ALIGN, so could we just add > > >>>> PARM_DECL to > > >>> > > >>> No. targetm.calls.function_arg_boundary may have special handling for > > >>> it. > > >> > > >> Why wouldn't we adjust DECL_ALIGN of the PARM_DECL to reflect the actual > > >> alignment of the argument? Are you saying it could be different from > > >> one call to another? > > > > > > Function argument alignment is different from other places in memory if > > > the main variant type alignment is different: > > > > Yes, I understand that function parameter alignment can be different > > from other objects of that type. > > > > But since we have a PARM_DECL to represent that particular function > > parameter, it seems natural to represent that difference in the > > DECL_ALIGN of the PARM_DECL. If you don't, its DECL_ALIGN is wrong. > > > > __alignof returns TYPE_ALIGN, not DECL_ALIGN. For PARM_DECL, > TYPE_ALIGN may not be the same as DECL_ALIGN. >
How about this patch? Since a backend may ignore type alignment for arguments passed on stack, call targetm.calls.function_arg_boundary to set DECL_ALIGN for PARM_DECL and change __alignof to return DECL_ALIGN, instead of TYPE_ALIGN, for PARM_DECL. gcc/ PR target/120839 * stor-layout.cc (do_type_align): Call targetm.calls.function_arg_boundary to set DECL_ALIGN for PARM_DECL. gcc/c-family/ PR target/120839 * c-common.cc (c_alignof_expr): Return DECL_ALIGN for PARM_DECL. gcc/testsuite/ PR target/120839 * gcc.target/i386/pr120839-1.c: New test. * gcc.target/i386/pr120839-2.c: Likewise. -- H.J.
From ea4ef6816ade1b3daa99d5bacb57708f02d3c939 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] Check backend when setting DECL_ALIGN for PARM_DECL Since a backend may ignore type alignment for arguments passed on stack, call targetm.calls.function_arg_boundary to set DECL_ALIGN for PARM_DECL and change __alignof to return DECL_ALIGN, instead of TYPE_ALIGN, for PARM_DECL. gcc/ PR target/120839 * stor-layout.cc (do_type_align): Call targetm.calls.function_arg_boundary to set DECL_ALIGN for PARM_DECL. gcc/c-family/ PR target/120839 * c-common.cc (c_alignof_expr): Return DECL_ALIGN for PARM_DECL. 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/c-family/c-common.cc | 3 +++ gcc/stor-layout.cc | 9 ++++++++- gcc/testsuite/gcc.target/i386/pr120839-1.c | 16 ++++++++++++++++ gcc/testsuite/gcc.target/i386/pr120839-2.c | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) 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/c-family/c-common.cc b/gcc/c-family/c-common.cc index 362dc506f78..4be5a2e1500 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -4097,6 +4097,9 @@ c_alignof_expr (location_t loc, tree expr) } return c_alignof (loc, TREE_TYPE (TREE_TYPE (best))); } + /* For PARM_DECL, DECL_ALIGN may be different from TYPE_ALIGN. */ + else if (TREE_CODE (expr) == PARM_DECL) + return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT); else return c_alignof (loc, TREE_TYPE (expr)); diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc index 12071c96ca7..25cc900b920 100644 --- a/gcc/stor-layout.cc +++ b/gcc/stor-layout.cc @@ -636,7 +636,14 @@ do_type_align (tree type, tree decl) { if (TYPE_ALIGN (type) > DECL_ALIGN (decl)) { - SET_DECL_ALIGN (decl, TYPE_ALIGN (type)); + unsigned int align; + /* For PARM_DECL, DECL_ALIGN may be different from TYPE_ALIGN. */ + if (TREE_CODE (decl) == PARM_DECL) + align = targetm.calls.function_arg_boundary (TYPE_MODE (type), + type); + else + align = TYPE_ALIGN (type); + SET_DECL_ALIGN (decl, align); if (TREE_CODE (decl) == FIELD_DECL) DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type); } 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..25e232152ed --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120839-1.c @@ -0,0 +1,16 @@ +/* { 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) +{ + _Static_assert (__alignof (f) == __alignof (long double), + "__alignof (f) == __alignof (long double)"); + 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); +} -- 2.50.0