Since the same hard register may be used for both non-stack access and
stack access, change ix86_find_max_used_stack_alignment to update stack
alignment only if the hard register in the set basic block, which
dominates the use basic block, accesses stack.

gcc/

PR target/124098
* config/i386/i386.cc (ix86_access_stack_p): New.
(ix86_find_max_used_stack_alignment): Update stack alignment only
if stack is used.

gcc/testsuite/

* gcc.target/i386/pr124098.c: New test.


-- 
H.J.
From 0ee8ba0aa6cd16f9bef13ef1781d55024e5e9909 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Tue, 17 Feb 2026 09:51:58 +0800
Subject: [PATCH] x86: Update stack alignment only if stack is used

Since the same hard register may be used for both non-stack access and
stack access, change ix86_find_max_used_stack_alignment to update stack
alignment only if the hard register in the set basic block, which
dominates the use basic block, accesses stack.

gcc/

	PR target/124098
	* config/i386/i386.cc (ix86_access_stack_p): New.
	(ix86_find_max_used_stack_alignment): Update stack alignment only
	if stack is used.

gcc/testsuite/

	* gcc.target/i386/pr124098.c: New test.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/config/i386/i386.cc                  | 49 +++++++++++++++++++++++-
 gcc/testsuite/gcc.target/i386/pr124098.c | 12 ++++++
 2 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr124098.c

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 8a54648337d..c419c828df1 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -8711,6 +8711,37 @@ ix86_find_all_reg_uses (HARD_REG_SET &regset,
     }
 }
 
+/* Return true if hard register REGNO set in the basic block, which
+   dominates basic block BB, accesses stack.  */
+
+static bool
+ix86_access_stack_p (unsigned int regno, basic_block bb,
+		     HARD_REG_SET &set_up_by_prologue,
+		     HARD_REG_SET &prologue_used)
+{
+  /* Get all BBs which set REGNO and dominate the current BB from all
+     DEFs of REGNO.  */
+  for (df_ref def = DF_REG_DEF_CHAIN (regno);
+       def;
+       def = DF_REF_NEXT_REG (def))
+    if (!DF_REF_IS_ARTIFICIAL (def)
+	&& !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)
+	&& !DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
+      {
+	basic_block set_bb = DF_REF_BB (def);
+	if (dominated_by_p (CDI_DOMINATORS, bb, set_bb))
+	  {
+	    rtx_insn *insn = DF_REF_INSN (def);
+	    /* Return true if INSN requires stack.  */
+	    if (requires_stack_frame_p (insn, prologue_used,
+					set_up_by_prologue))
+	      return true;
+	  }
+      }
+
+  return false;
+}
+
 /* Set stack_frame_required to false if stack frame isn't required.
    Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
    slot used if stack frame is required and CHECK_STACK_SLOT is true.  */
@@ -8771,6 +8802,10 @@ ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
       bitmap_set_bit (worklist, HARD_FRAME_POINTER_REGNUM);
     }
 
+  HARD_REG_SET hard_stack_slot_access = stack_slot_access;
+
+  calculate_dominance_info (CDI_DOMINATORS);
+
   unsigned int regno;
 
   do
@@ -8798,9 +8833,19 @@ ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
 	if (!NONJUMP_INSN_P (insn))
 	  continue;
 
-	data.reg = DF_REF_REG (ref);
-	note_stores (insn, ix86_update_stack_alignment, &data);
+	if (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
+	    || ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
+				    set_up_by_prologue, prologue_used))
+	  {
+	    /* Update stack alignment if REGNO accesses stack.  */
+	    data.reg = DF_REF_REG (ref);
+	    note_stores (insn, ix86_update_stack_alignment,
+			 &data);
+	    continue;
+	  }
       }
+
+  free_dominance_info (CDI_DOMINATORS);
 }
 
 /* Finalize stack_realign_needed and frame_pointer_needed flags, which
diff --git a/gcc/testsuite/gcc.target/i386/pr124098.c b/gcc/testsuite/gcc.target/i386/pr124098.c
new file mode 100644
index 00000000000..0b552acc6b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr124098.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -mno-avx512f -mavx2" } */
+
+char c, d;
+_BitInt(2048) b;
+
+void
+foo (__int128, _BitInt(1024) a)
+{
+  b *= 0;
+  c %= (char)(a ?: d);
+}
-- 
2.53.0

Reply via email to