]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Check BIGGEST_ALIGNMENT when forcing a local copy
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 31 Mar 2026 15:59:50 +0000 (08:59 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 1 Apr 2026 10:58:42 +0000 (03:58 -0700)
BIGGEST_ALIGNMENT is the biggest alignment that any data type can require
on the target machine.  It is not the biggest alignment that is supported,
just the biggest alignment that, when violated, may cause a fault.

MAX_SUPPORTED_STACK_ALIGNMENT is the maximum stack alignment guaranteed by
the backend.  If SUPPORTS_STACK_ALIGNMENT is false, it is defined as
PREFERRED_STACK_BOUNDARY.

Adjust alignment check forcing a local copy if the argument on stack is
not aligned to its type and the current alignment is less than the
minimum of BIGGEST_ALIGNMENT and MAX_SUPPORTED_STACK_ALIGNMENT.

gcc/

PR middle-end/124697
* function.cc (assign_parm_adjust_stack_rtl): Force a local copy
if the current alignment is less than the minimum of
BIGGEST_ALIGNMENT and MAX_SUPPORTED_STACK_ALIGNMENT.

gcc/testsuite/

PR middle-end/124697
* gcc.target/i386/pr120839-1b.c: Adjusted.
* gcc.target/i386/pr124697-1a.c: New test.
* gcc.target/i386/pr124697-1b.c: Likewise.
* gcc.target/i386/pr124697-2a.c: Likewise.
* gcc.target/i386/pr124697-2b.c: Likewise.
* gcc.target/i386/pr124697-3a.c: Likewise.
* gcc.target/i386/pr124697-3b.c: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
gcc/function.cc
gcc/testsuite/gcc.target/i386/pr120839-1b.c
gcc/testsuite/gcc.target/i386/pr124697-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr124697-1b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr124697-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr124697-2b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr124697-3a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr124697-3b.c [new file with mode: 0644]

index 46c0d8b54c2f27490f9e7486f8d7d703ab333b3c..109821c16fc96e4cd77d0721babca21dcdf82419 100644 (file)
@@ -2840,7 +2840,8 @@ assign_parm_adjust_stack_rtl (tree parm, struct assign_parm_data_one *data)
                                                 MEM_ALIGN (stack_parm))))
          || (data->nominal_type
              && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm)
-             && (MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY
+             && ((MEM_ALIGN (stack_parm)
+                  < MIN (BIGGEST_ALIGNMENT, MAX_SUPPORTED_STACK_ALIGNMENT))
                  /* If its address is taken, make a local copy whose
                     maximum alignment is MAX_SUPPORTED_STACK_ALIGNMENT.
                   */
index d9dafc19afb7370bd551d3c65d2824f4da38dfaa..cd7701f1d89576e3f103d5fbd2391c3cb58b76c5 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -mavx2" } */
-/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-32,\[\\t \]*%\[re\]?sp" { xfail ia32 } } } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-32,\[\\t \]*%\[re\]?sp" } } */
 
 #include "pr120839-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr124697-1a.c b/gcc/testsuite/gcc.target/i386/pr124697-1a.c
new file mode 100644 (file)
index 0000000..63d5cc7
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run  { target avx2_runtime } }  */
+/* { dg-options "-O2 -mavx2" } */
+
+typedef double v4df __attribute__((vector_size(32)));
+typedef double v2df __attribute__((vector_size(16)));
+typedef struct {
+  v2df a[2];
+} c __attribute__((aligned(32)));
+v4df d;
+c v;
+
+__attribute__ ((noipa))
+void
+foo (float a1, float a2, float a3, float a4, float a5, float a6, c f)
+{
+  d = *(v4df *) &f;
+}
+
+__attribute__ ((noipa))
+void
+bar (void)
+{
+  foo (0, 0, 0, 0, 0, 0, v);
+}
+
+int
+main ()
+{
+  bar ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr124697-1b.c b/gcc/testsuite/gcc.target/i386/pr124697-1b.c
new file mode 100644 (file)
index 0000000..3b74f62
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile }  */
+/* { dg-options "-O2 -mno-avx512f -mavx2" } */
+/* { dg-final { scan-assembler-times "vmovupd.*, %ymm0" 1 } } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-32,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler-not "vmovapd.*, %ymm0" } } */
+
+typedef double v4df __attribute__((vector_size(32)));
+typedef double v2df __attribute__((vector_size(16)));
+typedef struct {
+  v2df a[2];
+} c __attribute__((aligned(32)));
+v4df d;
+c v;
+
+void
+foo (float a1, float a2, float a3, float a4, float a5, float a6, c f)
+{
+  d = *(v4df *) &f;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr124697-2a.c b/gcc/testsuite/gcc.target/i386/pr124697-2a.c
new file mode 100644 (file)
index 0000000..46a1f95
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run  { target avx2_runtime } }  */
+/* { dg-options "-O2 -mavx2" } */
+
+typedef double v4df __attribute__((vector_size(32)));
+typedef struct {
+  v4df a[2];
+} c __attribute__((aligned(64)));
+v4df d;
+c v;
+
+__attribute__ ((noipa))
+void
+foo (float a1, float a2, float a3, float a4, float a5, float a6, c f)
+{
+  d = *(v4df *) &f;
+}
+
+__attribute__ ((noipa))
+void
+bar (void)
+{
+  foo (0, 0, 0, 0, 0, 0, v);
+}
+
+int
+main ()
+{
+  bar ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr124697-2b.c b/gcc/testsuite/gcc.target/i386/pr124697-2b.c
new file mode 100644 (file)
index 0000000..1c2256d
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile }  */
+/* { dg-options "-O2 -mno-avx512f -mavx2" } */
+/* { dg-final { scan-assembler-times "vmovapd.*, %ymm0" 1 } } */
+/* { dg-final { scan-assembler-not "vmovupd.*, %ymm0" } } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
+
+typedef double v4df __attribute__((vector_size(32)));
+typedef struct {
+  v4df a[2];
+} c __attribute__((aligned(64)));
+v4df d;
+c v;
+
+void
+foo (float a1, float a2, float a3, float a4, float a5, float a6, c f)
+{
+  d = *(v4df *) &f;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr124697-3a.c b/gcc/testsuite/gcc.target/i386/pr124697-3a.c
new file mode 100644 (file)
index 0000000..87e6f6f
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run  { target avx512f_runtime } }  */
+/* { dg-options "-O2 -mavx512f" } */
+
+typedef double v4df __attribute__((vector_size(32)));
+typedef double v8df __attribute__((vector_size(64)));
+typedef struct {
+  v4df a[2];
+} c __attribute__((aligned(64)));
+v8df d;
+c v;
+
+__attribute__ ((noipa))
+void
+foo (float a1, float a2, float a3, float a4, float a5, float a6, c f)
+{
+  d = *(v8df *) &f;
+}
+
+__attribute__ ((noipa))
+void
+bar (void)
+{
+  foo (0, 0, 0, 0, 0, 0, v);
+}
+
+int
+main ()
+{
+  bar ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr124697-3b.c b/gcc/testsuite/gcc.target/i386/pr124697-3b.c
new file mode 100644 (file)
index 0000000..31d52f8
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile }  */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-final { scan-assembler-times "vmovupd.*, %zmm0" 1 } } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]*\\$-64,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler-not "vmovapd.*, %zmm0" } } */
+
+typedef double v4df __attribute__((vector_size(32)));
+typedef double v8df __attribute__((vector_size(64)));
+typedef struct {
+  v4df a[2];
+} c __attribute__((aligned(64)));
+v8df d;
+c v;
+
+void
+foo (float a1, float a2, float a3, float a4, float a5, float a6, c f)
+{
+  d = *(v8df *) &f;
+}