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);
+	    }
+	}
     }
 }
 
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);
+}
-- 
2.50.0

Reply via email to