https://gcc.gnu.org/g:c464028a7c0d57f655d9f83cb38eded52e5ee4b5
commit r17-4927-gc464028a7c0d57f655d9f83cb38eded52e5ee4b5 Author: Oleg Tolmatcev <[email protected]> Date: Wed Sep 30 19:46:02 2026 +0200 i386: Fix va_arg of 256/512-bit vectors from a SysV va_list A SysV caller passes unnamed 256 and 512-bit vectors on the stack. For a SysV va_list, ix86_gimplify_va_arg only reads them from the stack if the function containing the va_arg uses the SysV ABI; in an MS ABI function it reads them from the register save area instead. Always read them from the stack. va-arg-abi-attribute-2.c passes on x86_64-w64-mingw32. gcc/ChangeLog: * config/i386/i386.cc (ix86_gimplify_va_arg): Always read unnamed 256 and 512-bit vectors from the stack. gcc/testsuite/ChangeLog: * gcc.target/i386/va-arg-abi-attribute-2.c: New test. * gcc.target/i386/va-arg-abi-attribute-3.c: New test. Signed-off-by: Oleg Tolmatcev <[email protected]> Signed-off-by: Jonathan Yong <[email protected]> Diff: --- gcc/config/i386/i386.cc | 8 +--- .../gcc.target/i386/va-arg-abi-attribute-2.c | 46 +++++++++++++++++++++ .../gcc.target/i386/va-arg-abi-attribute-3.c | 47 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 6 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 527be92c7310..2aad91ecf46e 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -5055,12 +5055,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, case E_V8DFmode: case E_V8DImode: /* Unnamed 256 and 512bit vector mode parameters are passed on stack. */ - if (!TARGET_64BIT_MS_ABI) - { - container = NULL; - break; - } - /* FALLTHRU */ + container = NULL; + break; default: container = construct_container (nat_mode, TYPE_MODE (type), diff --git a/gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c b/gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c new file mode 100644 index 000000000000..247ff277b090 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c @@ -0,0 +1,46 @@ +/* ix86_gimplify_va_arg must read an unnamed 256-bit vector from the stack + area of a SysV va_list, also in a function using the MS ABI. */ +/* { dg-do run { target { lp64 || llp64 } } } */ +/* { dg-options "-O2 -mavx" } */ +/* { dg-require-effective-target avx_runtime } */ + +#include "avx-check.h" + +typedef int v8si __attribute__ ((vector_size (32))); + +#define READER(name, abi) \ +static __attribute__ ((abi, noipa)) void \ +name (__builtin_sysv_va_list ap) \ +{ \ + int i = __builtin_va_arg (ap, int); \ + v8si v = __builtin_va_arg (ap, v8si); \ + int j = __builtin_va_arg (ap, int); \ + if (i != 1 \ + || v[0] != 2 || v[1] != 3 || v[2] != 4 || v[3] != 5 \ + || v[4] != 6 || v[5] != 7 || v[6] != 8 || v[7] != 9 \ + || j != 10) \ + abort (); \ +} + +READER (sysv_reads_sysv, sysv_abi) +READER (ms_reads_sysv, ms_abi) + +static __attribute__ ((sysv_abi, noipa)) void +sysv_varargs (int n, ...) +{ + __builtin_sysv_va_list ap; + __builtin_sysv_va_start (ap, n); + sysv_reads_sysv (ap); + __builtin_sysv_va_end (ap); + __builtin_sysv_va_start (ap, n); + ms_reads_sysv (ap); + __builtin_sysv_va_end (ap); +} + +static void +avx_test (void) +{ + v8si v = { 2, 3, 4, 5, 6, 7, 8, 9 }; + + sysv_varargs (0, 1, v, 10); +} diff --git a/gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c b/gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c new file mode 100644 index 000000000000..3a3661b11047 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c @@ -0,0 +1,47 @@ +/* ix86_gimplify_va_arg must read an unnamed 512-bit vector from the stack + area of a SysV va_list, also in a function using the MS ABI. */ +/* { dg-do run { target { lp64 || llp64 } } } */ +/* { dg-options "-O2 -mavx512f" } */ +/* { dg-require-effective-target avx512f_runtime } */ + +#include "avx512f-check.h" + +typedef int v16si __attribute__ ((vector_size (64))); + +#define READER(name, abi) \ +static __attribute__ ((abi, noipa)) void \ +name (__builtin_sysv_va_list ap) \ +{ \ + int i = __builtin_va_arg (ap, int); \ + v16si v = __builtin_va_arg (ap, v16si); \ + int j = __builtin_va_arg (ap, int); \ + int k; \ + if (i != 1 || j != 18) \ + abort (); \ + for (k = 0; k < 16; k++) \ + if (v[k] != k + 2) \ + abort (); \ +} + +READER (sysv_reads_sysv, sysv_abi) +READER (ms_reads_sysv, ms_abi) + +static __attribute__ ((sysv_abi, noipa)) void +sysv_varargs (int n, ...) +{ + __builtin_sysv_va_list ap; + __builtin_sysv_va_start (ap, n); + sysv_reads_sysv (ap); + __builtin_sysv_va_end (ap); + __builtin_sysv_va_start (ap, n); + ms_reads_sysv (ap); + __builtin_sysv_va_end (ap); +} + +static void +test_512 (void) +{ + v16si v = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + + sysv_varargs (0, 1, v, 18); +}
