[2/2] i386: Fix va_arg of 256/512-bit vectors from a SysV va_list
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
Commit Message
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 <oleg.tolmatcev@gmail.com>
---
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(-)
create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c
Comments
On Wed, Sep 30, 2026 at 7:48 PM Oleg Tolmatcev <oleg.tolmatcev@gmail.com> wrote:
>
> 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.
LGTM, but please also CC mingw maintainer on MS ABI stuff.
Thanks,
Uros.
> Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
> ---
> 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(-)
> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c
> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 98b6b3f9d2..2c87b1918b 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -5048,12 +5048,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 0000000000..247ff277b0
> --- /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 0000000000..3a3661b110
> --- /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);
> +}
> --
> 2.56.0.windows.1
>
On 10/1/26 06:47, Uros Bizjak wrote:
> On Wed, Sep 30, 2026 at 7:48 PM Oleg Tolmatcev <oleg.tolmatcev@gmail.com> wrote:
>>
>> 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.
>
> LGTM, but please also CC mingw maintainer on MS ABI stuff.
>
> Thanks,
> Uros.
>
>> Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
>> ---
>> 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(-)
>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c
>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c
+ LH.
在 2026-10-1 20:11, Jonathan Yong 写道:
> On 10/1/26 06:47, Uros Bizjak wrote:
>> On Wed, Sep 30, 2026 at 7:48 PM Oleg Tolmatcev <oleg.tolmatcev@gmail.com> wrote:
>>>
>>> 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.
>>
>> LGTM, but please also CC mingw maintainer on MS ABI stuff.
>>
>> Thanks,
>> Uros.
>>
>>> Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
>>> ---
>>> 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(-)
>>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-2.c
>>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-attribute-3.c
> + LH.
The change looks good to me.
For MS ABI, `va_list` is `char*` and is short-circuit'd by `is_va_list_char_pointer()`, so the code path
in the patch really looks specific to SysV ABI.
And also it shouldn't check for `TARGET_64BIT_MS_ABI` which is a global setting.
--
Best regards,
LIU Hao
On 10/1/26 12:59, LIU Hao wrote:
>>>
>>>> Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
>>>> ---
>>>> 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(-)
>>>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-
>>>> attribute-2.c
>>>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-
>>>> attribute-3.c
>> + LH.
>
> The change looks good to me.
>
> For MS ABI, `va_list` is `char*` and is short-circuit'd by
> `is_va_list_char_pointer()`, so the code path in the patch really looks
> specific to SysV ABI.
>
> And also it shouldn't check for `TARGET_64BIT_MS_ABI` which is a global
> setting.
>
Oleg, are you still working on splitting the patch into target
independent and target part like Uros suggests?
пт, 2 окт. 2026 г. в 15:42, Jonathan Yong <10walls@gmail.com>:
>
> On 10/1/26 12:59, LIU Hao wrote:
> >>>
> >>>> Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
> >>>> ---
> >>>> 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(-)
> >>>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-
> >>>> attribute-2.c
> >>>> create mode 100644 gcc/testsuite/gcc.target/i386/va-arg-abi-
> >>>> attribute-3.c
> >> + LH.
> >
> > The change looks good to me.
> >
> > For MS ABI, `va_list` is `char*` and is short-circuit'd by
> > `is_va_list_char_pointer()`, so the code path in the patch really looks
> > specific to SysV ABI.
> >
> > And also it shouldn't check for `TARGET_64BIT_MS_ABI` which is a global
> > setting.
> >
> Oleg, are you still working on splitting the patch into target
> independent and target part like Uros suggests?
I have already sent v2 of my patch and it was OKed by Uros.
https://gcc.gnu.org/pipermail/gcc-patches/2026-September/733129.html
Oleg
@@ -5048,12 +5048,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),
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}