https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89544
Bug ID: 89544 Summary: Argument marshalling incorrectly assumes stack slots are naturally aligned. Product: gcc Version: 9.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: rearnsha at gcc dot gnu.org CC: bernd.edlinger at hotmail dot de, ebotcazou at gcc dot gnu.org Target Milestone: --- Target: arm The AAPCS requires that an object which is artificially overaligned is passed at either its natural alignment (if <= 8) or on an 8-byte boundary if it is more aligned than that. So a struct of the form struct s { int a; int b;} __attribute__((aligned(8)); has a natural alignment of 4 and must be passed by value with 4-byte alignment. The middle end code ignores this and assign_parm_find_stack_rtl ends up generating invalid rtl of the form (mem/c:DI (plus:SI (reg/f:SI 104 virtual-incoming-args) (const_int 4 [0x4])) [1 f+0 S8 A32]) ie a DImode object with 32-bit alignment. It then proceeds to ignore the under alignment when expanding to RTL and incorrectly calls gen_movdi directly, rather than falling back to the misaligned move code. Test case: struct s { int a, b; } __attribute__((aligned(8))); struct s f0; int f(int a, int b, int c, int d, int e, struct s f) { f0 = f; return __alignof(f); } When compiled with "-O -march=armv5te" generates: @ args = 12, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. ldrd r0, [sp, #4] <========== Invalid alignment for ldrd ldr r3, .L2 strd r0, [r3] mov r0, #8 bx lr