https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128625

            Bug ID: 128625
           Summary: x86-64 ABI: struct with one __int128 vector_size(16)
                    member is passed in 8 bytes; high half lost
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---

int printf(const char *, ...);
typedef __int128 V __attribute__((vector_size(16)));
struct S { V m; };
int f(struct S s) { return s.m[0] >> 64; }
int main(void) {
  struct S s = { { -1 } };
  printf("%d\n", f(s));
}

$ gcc -O0 t.c && ./a.out
0
$ gcc -O3 t.c && ./a.out
-1

Expected: -1. s.m[0] is -1, so s.m[0] >> 64 is -1. The callee gets only the low
8 bytes. -O3 inlines f and is correct; -O1 -fno-inline also gives 0. Returning
such a struct also loses the high half.

Suspected cause: i386 classify_argument / construct_container: an aggregate
with a V1TImode member gets one SSE eightbyte, with no SSEUP class for the
second eightbyte.

Known to fail: 7.5.0, 8.5.0, 10.5.0, 11.4.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0,
16.2.0, 17.0.

-O0 -fsanitize=undefined,address is clean.

gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release

Reply via email to