From: H.J. Lu Date: Tue, 17 Feb 2026 01:51:58 +0000 (+0800) Subject: x86: Update stack alignment only if stack is used X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b54533a28632482e91d7dfbbc47c75fb6d5e78bb;p=thirdparty%2Fgcc.git x86: Update stack alignment only if stack is used 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 --- diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 8a54648337d..42a73d65fb1 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 ®set, } } +/* 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 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); +}