commit b4c215b36d63e1c264d8c1bd5d34f9aef1bb8463
Author: H.J. Lu <[email protected]>
Date: Sat Jun 28 06:27:25 2025 +0800
Adjust check for addressable misaligned stack argument
ignores arguments passed on stack since caller is responsible to align
the outgoing stack for arguments passed on stack. However, callee may
spill a register argument:
(set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
(const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
(reg:V2DI 20 xmm0 [ a1 ]))
Update ix86_argument_passed_on_stack_p to check spill of register argument
by callee.
gcc/
PR target/126320
* config/i386/i386.cc (ix86_spill_register_argument_p): New
function.
(ix86_argument_passed_on_stack_p): Add a pattern argument. Call
ix86_spill_register_argument_p to check spill of register argument
by callee.
(ix86_update_stack_alignment): Pass pat to
ix86_argument_passed_on_stack_p.
gcc/testsuite/
PR target/126320
* gcc.target/i386/pr126320.c: New test.
--
H.J.
From 80db542e70379b7a0417f7669907525fa5879a98 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Mon, 20 Jul 2026 07:57:31 +0800
Subject: [PATCH] x86: Check register argument spill by callee
commit b4c215b36d63e1c264d8c1bd5d34f9aef1bb8463
Author: H.J. Lu <[email protected]>
Date: Sat Jun 28 06:27:25 2025 +0800
Adjust check for addressable misaligned stack argument
ignores arguments passed on stack since caller is responsible to align
the outgoing stack for arguments passed on stack. However, callee may
spill a register argument:
(set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
(const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
(reg:V2DI 20 xmm0 [ a1 ]))
Update ix86_argument_passed_on_stack_p to check spill of register argument
by callee.
gcc/
PR target/126320
* config/i386/i386.cc (ix86_spill_register_argument_p): New
function.
(ix86_argument_passed_on_stack_p): Add a pattern argument. Call
ix86_spill_register_argument_p to check spill of register argument
by callee.
(ix86_update_stack_alignment): Pass pat to
ix86_argument_passed_on_stack_p.
gcc/testsuite/
PR target/126320
* gcc.target/i386/pr126320.c: New test.
Signed-off-by: H.J. Lu <[email protected]>
---
gcc/config/i386/i386.cc | 63 +++++++++++++++++++++---
gcc/testsuite/gcc.target/i386/pr126320.c | 45 +++++++++++++++++
2 files changed, 101 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr126320.c
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index fd16dd441c1..094f224a20c 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -8609,18 +8609,67 @@ struct stack_access_data
unsigned int *stack_alignment;
};
-/* Return true if OP references an argument passed on stack. */
+/* Return true if SET is a register argument spill to the stack operand
+ OP with base address BASE. */
static bool
-ix86_argument_passed_on_stack_p (const_rtx op)
+ix86_spill_register_argument_p (const_rtx set, const_rtx op, tree base)
+{
+ rtx src = SET_SRC (set);
+
+ /* Return true if source isn't a hard register. Callee can read from
+ or write to argument passed on stack by caller. */
+ if (!REG_P (src) || !HARD_REGISTER_P (src))
+ return false;
+
+ rtx dest = SET_DEST (set);
+ tree reg_expr = REG_EXPR (src);
+
+ /* If both the stack operand, which also is the destination of PAT,
+ and the register source of PAT point to the same argument, PAT
+ spills the register argument:
+
+ (set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
+ (const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
+ (reg:V2DI 20 xmm0 [ a1 ]))
+ */
+ return dest == op && reg_expr == base;
+}
+
+/* Return true if OP, found in instruction PAT, references an argument
+ passed on stack by the caller. */
+
+static bool
+ix86_argument_passed_on_stack_p (const_rtx op, const_rtx pat)
{
tree mem_expr = MEM_EXPR (op);
- if (mem_expr)
+ if (!mem_expr)
+ return false;
+
+ tree var = get_base_address (mem_expr);
+ if (TREE_CODE (var) != PARM_DECL)
+ return false;
+
+ /* The stack operand for register argument spill isn't the argument
+ passed on stack from caller. */
+ switch (GET_CODE (pat))
{
- tree var = get_base_address (mem_expr);
- return TREE_CODE (var) == PARM_DECL;
+ case SET:
+ return !ix86_spill_register_argument_p (pat, op, var);
+ case PARALLEL:
+ for (int i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx exp = XVECEXP (pat, 0, i);
+ if (GET_CODE (exp) == SET
+ && ix86_spill_register_argument_p (exp, op, var))
+ return false;
+ }
+ /* Fall through. */
+ default:
+ break;
}
- return false;
+
+ return true;
}
/* Update the maximum stack slot alignment from memory alignment in PAT. */
@@ -8642,7 +8691,7 @@ ix86_update_stack_alignment (rtx, const_rtx pat, void *data)
responsible to align the outgoing stack for arguments
passed on stack. */
if (reg_mentioned_p (p->reg, XEXP (op, 0))
- && !ix86_argument_passed_on_stack_p (op))
+ && !ix86_argument_passed_on_stack_p (op, pat))
{
unsigned int alignment = MEM_ALIGN (op);
diff --git a/gcc/testsuite/gcc.target/i386/pr126320.c b/gcc/testsuite/gcc.target/i386/pr126320.c
new file mode 100644
index 00000000000..fd567a5c816
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126320.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -march=x86-64 -mavx2" } */
+
+#include <stdint.h>
+
+typedef int64_t v2i64 __attribute__ ((vector_size (16)));
+void *g4, *f3_p2;
+int8_t g15, g23;
+v2i64 g21;
+_Bool g22, f3_c4;
+__attribute__ ((__vector_size__ (16 * sizeof (int)))) int g26;
+int16_t g29;
+
+__attribute__((noipa, noinline))
+void
+do_test (v2i64 a1)
+{
+ int16_t v3;
+lbl_entry:
+ f3_p2 = &a1;
+ v3 = g29;
+ if (g22)
+ goto lbl_bf4;
+ f3_c4 = v3 - 709;
+ if (f3_c4)
+ return;
+lbl_bf4:
+ g21 = a1;
+ uint8_t __ov_tmp_g15;
+ g15 = __ov_tmp_g15;
+ a1[0] = 0;
+ g26 = g26 == ~g26;
+ g4 = f3_p2;
+ g23 = 0;
+ goto lbl_entry;
+}
+
+int
+main (void)
+{
+ if (__builtin_cpu_supports ("avx2"))
+ do_test (g21);
+
+ return 0;
+}
--
2.55.0