https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118684
Bug ID: 118684 Summary: wrong alignment for stack temporary created during RTL expansion Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org Target Milestone: --- typedef int v4si __attribute__((vector_size(16))); v4si x; int main () { int b __attribute__((aligned(16))); b = 0; x = *(v4si *)&b; } segfaults because we expand 'b' to a register, but then spill it to the stack without honoring it's original alignment, eventually creating a MEM with too large MEM_ALIGN, resulting in a movdqa that faults: main: .LFB0: .cfi_startproc movl $0, -12(%rsp) movdqa -12(%rsp), %xmm0 xorl %eax, %eax movaps %xmm0, x(%rip) ret We go through case MEM_REF: { const bool reverse = REF_REVERSE_STORAGE_ORDER (exp); addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))); machine_mode address_mode; ... unsigned align; /* Handle expansion of non-aliased memory with non-BLKmode. That might end up in a register. */ if (mem_ref_refers_to_non_mem_p (exp)) { ... exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type), bitsize_int (offset * BITS_PER_UNIT)); REF_REVERSE_STORAGE_ORDER (exp) = reverse; return expand_expr (exp, target, tmode, modifier); where the BIT_FIELD_REF expansion does /* Otherwise, if this is a constant or the object is not in memory and need be, put it there. */ else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem)) { memloc = assign_temp (TREE_TYPE (tem), 1, 1); emit_move_insn (memloc, op0); op0 = memloc; clear_mem_expr = true; and then /* Don't set memory attributes if the base expression is SSA_NAME that got expanded as a MEM or a CONSTANT. In that case, we should just honor its original memory attributes. */ if (!(TREE_CODE (tem) == SSA_NAME && (MEM_P (orig_op0) || CONSTANT_P (orig_op0)))) set_mem_attributes (op0, exp, 0); yielding (insn 6 5 7 (set (mem/c:SI (plus:DI (reg/f:DI 93 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [1 S4 A32]) (reg/v:SI 99 [ b ])) "t.c":7:7 -1 (nil)) (insn 7 6 8 (set (reg:V4SI 101) (mem/j:V4SI (plus:DI (reg/f:DI 93 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [1 +0 S16 A128])) "t.c":7:5 -1 (nil)) The issue is that while there's DECL_ALIGN on the decl for 'b', it's type is 'int' with natural alignment. But assign_temp only looks at the type for the alignment, even if you pass it a decl.