Since in
typedef int V [[gnu::vector_size (16)]];
long long a, b, c, d, e;
short f;
[[gnu::vector_size (8 * sizeof (int))]] int g;
V h;
_Bool i;
void
foo (V x)
{
_Bool j = 0;
short l = 0;
l1:
b = l;
x = h;
...
}
the register argument, x, is used as local variable, also return true if
spilling an SSA_NAME into an argument-linked memory.
gcc/
PR target/126450
* config/i386/i386.cc (ix86_spill_register_argument_p): Check
the argument-linked memory used to store local variable.
gcc/testsuite/
PR target/126450
* gcc.target/i386/pr126450-1.c: New test.
* gcc.target/i386/pr126450-2.c: Likewise.
--
H.J.
From 1a6b15cc09445a28ce9be3be4ae41da6e595ae34 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Wed, 29 Jul 2026 06:23:57 +0800
Subject: [PATCH] x86: Check argument-linked memory used for local variable
Since in
typedef int V [[gnu::vector_size (16)]];
long long a, b, c, d, e;
short f;
[[gnu::vector_size (8 * sizeof (int))]] int g;
V h;
_Bool i;
void
foo (V x)
{
_Bool j = 0;
short l = 0;
l1:
b = l;
x = h;
...
}
the register argument, x, is used as local variable, also return true if
spilling an SSA_NAME into an argument-linked memory.
gcc/
PR target/126450
* config/i386/i386.cc (ix86_spill_register_argument_p): Check
the argument-linked memory used to store local variable.
gcc/testsuite/
PR target/126450
* gcc.target/i386/pr126450-1.c: New test.
* gcc.target/i386/pr126450-2.c: Likewise.
Signed-off-by: H.J. Lu <[email protected]>
---
gcc/config/i386/i386.cc | 6 ++-
gcc/testsuite/gcc.target/i386/pr126450-1.c | 43 ++++++++++++++++++++++
gcc/testsuite/gcc.target/i386/pr126450-2.c | 15 ++++++++
3 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr126450-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr126450-2.c
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index ae3a9ad595e..9f1d4b32ccc 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -8631,7 +8631,11 @@ ix86_spill_register_argument_p (const_rtx set, const_rtx op, tree base)
rtx dest = SET_DEST (set);
tree reg_expr = REG_EXPR (src);
- return dest == op && reg_expr == base;
+ /* If spilling an SSA_NAME into OP, the argument-linked memory is
+ also used to store a local variable. */
+ return dest == op && (reg_expr == base
+ || (reg_expr
+ && TREE_CODE (reg_expr) == SSA_NAME));
}
/* Return true if OP, found in PAT, is a stack argument set up by the
diff --git a/gcc/testsuite/gcc.target/i386/pr126450-1.c b/gcc/testsuite/gcc.target/i386/pr126450-1.c
new file mode 100644
index 00000000000..dd5b610ffe7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126450-1.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+typedef int V [[gnu::vector_size (16)]];
+long long a, b, c, d, e;
+short f;
+[[gnu::vector_size (8 * sizeof (int))]] int g;
+V h;
+_Bool i;
+
+__attribute__((noipa, noinline, target("avx2")))
+void
+foo (V x)
+{
+ _Bool j = 0;
+ short l = 0;
+l1:
+ b = l;
+ x = h;
+ l = c % 4;
+ i = f = e % 6;
+ e = x[j];
+ g = g > g;
+ if (d)
+ goto l2;
+l3:
+ j = l;
+ if (j)
+ goto l1;
+ a = l;
+l2:
+ if (e)
+ goto l3;
+}
+
+int
+main (void)
+{
+ if (__builtin_cpu_supports ("avx2"))
+ foo (h);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126450-2.c b/gcc/testsuite/gcc.target/i386/pr126450-2.c
new file mode 100644
index 00000000000..778f984d798
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126450-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int UDItype __attribute__ ((mode (DI)));
+typedef __attribute__ ((aligned)) struct
+{
+ UDItype w[2];
+} UINT128;
+
+UINT128
+__bid128_copySign (UINT128 x)
+{
+ x.w[1] = x.w[1] & 8000000000000000ULL;
+ return x;
+}
--
2.55.0