https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105549
Bug ID: 105549 Summary: aarch64: Wrong va_arg alignment handling Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: clyon at gcc dot gnu.org Target Milestone: --- While working on enabling DFP for AArch64, I noticed new failures in gcc.dg/compat/struct-layout-1.exp (t028) which were not actually caused by DFP types handling. I reduced the problem to: /* This test is derived from a case generated by struct-layout-1.exp: */ enum E6 { e6_0, e6_1, e6_2, e6_3, e6_65533 = 65533, e6_65534, e6_65535 }; typedef enum E6 Tal16E6 __attribute__((aligned (16))); typedef unsigned int Tuint; int fails; union S2844 { Tuint a:((((10) - 1) & 31) + 1); Tal16E6 __attribute__((aligned (2), packed)) b:31; struct{}c[0]; } ; union S2844 s2844; union S2844 a2844[5]; typedef __builtin_va_list __gnuc_va_list; typedef __gnuc_va_list va_list; void check2844va (int z, ...) { union S2844 arg, *p; va_list ap; __builtin_va_start(ap,z); if (__builtin_va_arg(ap,double) != 1.0) printf ("fail %d.%d\n", 2844, 0), ++fails; p = &s2844; arg = __builtin_va_arg(ap,union S2844); /* This would fail. */ if (p->a != arg.a) printf ("fail %d.%d\n", 2844, 1), ++fails; if (__builtin_va_arg(ap,long long) != 3LL) printf ("fail %d.%d\n", 2844, 2), ++fails; p = &a2844[2]; arg = __builtin_va_arg(ap,union S2844); /* This would fail. */ if (p->a != arg.a) printf ("fail %d.%d\n", 2844, 3), ++fails; arg = __builtin_va_arg(ap,union S2844); /* This would fail. */ if (p->a != arg.a) printf ("fail %d.%d\n", 2844, 4), ++fails; __builtin_va_end(ap); } int main (void) { int i, j; memset (&s2844, '\0', sizeof (s2844)); memset (a2844, '\0', sizeof (a2844)); s2844.a = 799U; a2844[2].a = 586U; check2844va (1, 1.0, s2844, 2LL, a2844[2], a2844[2]); exit (fails != 0); } This is a tough case mixing bitfields and alignment, where aarch64_gimplify_va_arg_expr did not follow the exact same rule as aarch64_layout_arg. When the va_arg parameter uses only one general register, we do not want to introduce double-word alignment.