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