]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
x86: Update stack alignment only if stack is used
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 17 Feb 2026 01:51:58 +0000 (09:51 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 18 Feb 2026 05:14:15 +0000 (13:14 +0800)
The same hard register may be used for both stack and non-stack accesses.
Update ix86_find_max_used_stack_alignment to adjust stack alignment only
when a hard register used for a stack access is defined in a basic block
that dominates the block where it is used.

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/

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

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
gcc/config/i386/i386.cc
gcc/testsuite/gcc.target/i386/pr124098.c [new file with mode: 0644]

index 8a54648337dcc218b456d6893f3a53ac13d0a7ec..42a73d65fb1d855bba5883da476b42a077f8a1ce 100644 (file)
@@ -8711,6 +8711,37 @@ ix86_find_all_reg_uses (HARD_REG_SET &regset,
     }
 }
 
+/* Return true if the hard register REGNO used for a stack access is
+   defined in a basic block that dominates the block where it is used.  */
+
+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 is used for stack
+              access.  */
+           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 (file)
index 0000000..0b552ac
--- /dev/null
@@ -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);
+}