[v3,2/2] Correct x86: Call ix86_access_stack_p only for larger alignment
Commit Message
commit f511bf93f947199a9f9099fee87b7052e5515fb9
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sun Mar 29 14:30:28 2026 -0700
x86: Call ix86_access_stack_p only for larger alignment
has 2 issues:
1. It didn't exclude memory with SYMBOLIC_CONST when checking for stack
access.
2. It replaced:
HARD_REG_SET hard_stack_slot_access = stack_slot_access;
...
bool symbolic_const_load_p = false;
if (!TEST_HARD_REG_BIT (hard_stack_slot_access, regno))
...
symbolic_const_load_p = true;
...
if (!symbolic_const_load_p
|| ix86_access_stack_p...)
call ix86_update_stack_alignment.
with
if (ix86_need_alignment_p...
&& ix86_access_stack_p...)
call ix86_update_stack_alignment.
Since ix86_access_stack_p excludes registers on hard_stack_slot_access,
stack alignment isn't updated for registers on hard_stack_slot_access.
Instead, we should do
if (ix86_need_alignment_p...
&& (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
|| ix86_access_stack_p...))
call ix86_update_stack_alignment.
The compile times of PR target/124165 and PR target/124684 test are
unchanged.
if (ix86_need_alignment_p...
&& (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
|| ix86_access_stack_p...))
call ix86_update_stack_alignment.
gcc/
PR target/124759
PR target/124789
* config/i386/i386.cc (ix86_need_alignment_p_2): New function.
Exclude memory with SYMBOLIC_CONST.
(ix86_need_alignment_p_1): Call ix86_need_alignment_p_2.
(ix86_find_max_used_stack_alignment): Restore
hard_stack_slot_access handling.
gcc/testsuite/
PR target/124759
PR target/124789
* gcc.target/i386/pr124759.c: New test.
Comments
On Tue, 7 Apr 2026, H.J. Lu wrote:
> commit f511bf93f947199a9f9099fee87b7052e5515fb9
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date: Sun Mar 29 14:30:28 2026 -0700
>
> x86: Call ix86_access_stack_p only for larger alignment
This also LGTM.
Thanks,
Richard.
> has 2 issues:
>
> 1. It didn't exclude memory with SYMBOLIC_CONST when checking for stack
> access.
> 2. It replaced:
>
> HARD_REG_SET hard_stack_slot_access = stack_slot_access;
> ...
> bool symbolic_const_load_p = false;
>
> if (!TEST_HARD_REG_BIT (hard_stack_slot_access, regno))
> ...
> symbolic_const_load_p = true;
> ...
>
> if (!symbolic_const_load_p
> || ix86_access_stack_p...)
> call ix86_update_stack_alignment.
>
> with
>
> if (ix86_need_alignment_p...
> && ix86_access_stack_p...)
> call ix86_update_stack_alignment.
>
> Since ix86_access_stack_p excludes registers on hard_stack_slot_access,
> stack alignment isn't updated for registers on hard_stack_slot_access.
> Instead, we should do
>
> if (ix86_need_alignment_p...
> && (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
> || ix86_access_stack_p...))
> call ix86_update_stack_alignment.
>
> The compile times of PR target/124165 and PR target/124684 test are
> unchanged.
>
> if (ix86_need_alignment_p...
> && (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
> || ix86_access_stack_p...))
> call ix86_update_stack_alignment.
>
> gcc/
>
> PR target/124759
> PR target/124789
> * config/i386/i386.cc (ix86_need_alignment_p_2): New function.
> Exclude memory with SYMBOLIC_CONST.
> (ix86_need_alignment_p_1): Call ix86_need_alignment_p_2.
> (ix86_find_max_used_stack_alignment): Restore
> hard_stack_slot_access handling.
>
> gcc/testsuite/
>
> PR target/124759
> PR target/124789
> * gcc.target/i386/pr124759.c: New test.
>
>
From eeb8b623766f5bbc3a6801445f1b48734e6ee899 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 3 Apr 2026 15:55:17 +0800
Subject: [PATCH v3 2/2] Correct x86: Call ix86_access_stack_p only for larger
alignment
commit f511bf93f947199a9f9099fee87b7052e5515fb9
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sun Mar 29 14:30:28 2026 -0700
x86: Call ix86_access_stack_p only for larger alignment
has 2 issues:
1. It didn't exclude memory with SYMBOLIC_CONST when checking for stack
access.
2. It replaced:
HARD_REG_SET hard_stack_slot_access = stack_slot_access;
...
bool symbolic_const_load_p = false;
if (!TEST_HARD_REG_BIT (hard_stack_slot_access, regno))
...
symbolic_const_load_p = true;
...
if (!symbolic_const_load_p
|| ix86_access_stack_p...)
call ix86_update_stack_alignment.
with
if (ix86_need_alignment_p...
&& ix86_access_stack_p...)
call ix86_update_stack_alignment.
Since ix86_access_stack_p excludes registers on hard_stack_slot_access,
stack alignment isn't updated for registers on hard_stack_slot_access.
Instead, we should do
if (ix86_need_alignment_p...
&& (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
|| ix86_access_stack_p...))
call ix86_update_stack_alignment.
The compile times of PR target/124165 and PR target/124684 test are
unchanged.
if (ix86_need_alignment_p...
&& (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
|| ix86_access_stack_p...))
call ix86_update_stack_alignment.
gcc/
PR target/124759
PR target/124789
* config/i386/i386.cc (ix86_need_alignment_p_2): New function.
Exclude memory with SYMBOLIC_CONST.
(ix86_need_alignment_p_1): Call ix86_need_alignment_p_2.
(ix86_find_max_used_stack_alignment): Restore
hard_stack_slot_access handling.
gcc/testsuite/
PR target/124759
PR target/124789
* gcc.target/i386/pr124759.c: New test.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
gcc/config/i386/i386.cc | 40 ++++++++++++++++++++----
gcc/testsuite/gcc.target/i386/pr124759.c | 29 +++++++++++++++++
2 files changed, 63 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr124759.c
@@ -8781,6 +8781,29 @@ ix86_access_stack_p (unsigned int regno, basic_block bb,
return false;
}
+/* Return true if OP isn't a memory operand with SYMBOLIC_CONST and
+ needs alignment > ALIGNMENT. */
+
+static bool
+ix86_need_alignment_p_2 (const_rtx op, unsigned int alignment)
+{
+ bool need_alignment = MEM_ALIGN (op) > alignment;
+ tree mem_expr = MEM_EXPR (op);
+ if (!mem_expr)
+ return need_alignment;
+
+ tree var = get_base_address (mem_expr);
+ if (!VAR_P (var) || !DECL_RTL_SET_P (var))
+ return need_alignment;
+
+ rtx x = DECL_RTL (var);
+ if (!MEM_P (x))
+ return need_alignment;
+
+ x = XEXP (x, 0);
+ return !SYMBOLIC_CONST (x) && need_alignment;
+}
+
/* Return true if SET needs alignment > ALIGNMENT. */
static bool
@@ -8789,7 +8812,7 @@ ix86_need_alignment_p_1 (rtx set, unsigned int alignment)
rtx dest = SET_DEST (set);
if (MEM_P (dest))
- return MEM_ALIGN (dest) > alignment;
+ return ix86_need_alignment_p_2 (dest, alignment);
const_rtx src = SET_SRC (set);
@@ -8799,7 +8822,7 @@ ix86_need_alignment_p_1 (rtx set, unsigned int alignment)
auto op = *iter;
if (MEM_P (op))
- return MEM_ALIGN (op) > alignment;
+ return ix86_need_alignment_p_2 (op, alignment);
}
return false;
@@ -8890,6 +8913,9 @@ ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
bitmap_set_bit (worklist, HARD_FRAME_POINTER_REGNUM);
}
+ /* Registers on HARD_STACK_SLOT_ACCESS always access stack. */
+ HARD_REG_SET hard_stack_slot_access = stack_slot_access;
+
calculate_dominance_info (CDI_DOMINATORS);
unsigned int regno;
@@ -8926,10 +8952,12 @@ ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
/* Call ix86_access_stack_p only if INSN needs alignment >
STACK_ALIGNMENT. */
if (ix86_need_alignment_p (insn, stack_alignment)
- && ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
- set_up_by_prologue, prologue_used,
- reg_dominate_bbs_known,
- reg_dominate_bbs))
+ && (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
+ || ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
+ set_up_by_prologue,
+ prologue_used,
+ reg_dominate_bbs_known,
+ reg_dominate_bbs)))
{
/* Update stack alignment if REGNO is used for stack
access. */
new file mode 100644
@@ -0,0 +1,29 @@
+/* { dg-do run { target avx_runtime } } */
+/* { dg-options "-fhardened -O3 -mavx" } */
+
+struct a {
+ unsigned long long b;
+ unsigned long long c;
+ int d;
+ char e;
+ int f;
+} g;
+int h = 1, i, j;
+long long k, l, n;
+int m[1]={};
+short o;
+static inline short p(short q, short r) { return q + r; }
+int main() {
+ for (; h < 3; h = p(h, 1))
+ if (h) {
+ k |= 4;
+ struct a s = {8, 2, 2, 4, 15};
+ for (int n = 0; n != 54; n++)
+ if (m[l])
+ if (i)
+ o = 0;
+ g = s;
+ j &= 4073709551610LL;
+ }
+ return 0;
+}
--
2.53.0