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.

Reply via email to