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

Reply via email to