From: H.J. Lu Date: Tue, 28 Jul 2026 22:23:57 +0000 (+0800) Subject: x86: Check argument-linked memory used for local variable X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ea27cb48a346633d6bfabcde75f88affb9463e40;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 33e5e063b99..e83402f2c42 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -8618,7 +8618,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; +}