On 8/26/26 1:55 PM, Matt Turner wrote:
The unaligned load and store expanders build the byte address of the
access as a raw (plus ADDR CONST) and drop it straight into a SET,
bypassing insn recognition.  ADDR is frequently virtual-stack-vars, so
the constant is only resolved to the real frame offset in the vregs
pass, and add_operand accepts a CONST_INT only when it satisfies K (a
16-bit signed value, lda) or L (a multiple of 65536, ldah).  A stack
slot more than 64K into a large frame therefore yields an insn no
adddi3 pattern matches, and the first extract_insn on it dies:

   internal compiler error: in extract_insn, at recog.cc:2894

adddi3 is a bodyless expander with add_operand on operand 2, so there
is no fallback that would split an arbitrary constant.  Use
copy_addr_to_reg instead, which routes the address through
force_operand and materialises whatever sequence the constant needs;
alpha_expand_unaligned_store already does this.

This is not specific to the stack protector, but the canary reliably
pushes an otherwise in-range array past the boundary, so enabling
-fstack-protector makes it easy to hit.

gcc/ChangeLog:

        * config/alpha/alpha.cc (alpha_expand_unaligned_load): Use
        copy_addr_to_reg to compute the byte address.
        (alpha_expand_unaligned_store_safe_partial): Likewise.

gcc/testsuite/ChangeLog:

        * gcc.target/alpha/unaligned-big-frame.c: New test.

Thanks.  I've pushed this to the trunk.


Jeff


Reply via email to