[2/2] i386: Fix va_arg of 256/512-bit vectors from a SysV va_list

Message ID 20260930174600.1369-4-oleg.tolmatcev@gmail.com
State Committed
Commit c464028a7c0d57f655d9f83cb38eded52e5ee4b5
Headers
Series [1/2] i386: Take the va_arg by-reference decision from the va_list type |

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

Oleg Tolmatcev Sept. 30, 2026, 5:46 p.m. UTC
  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

Uros Bizjak Oct. 1, 2026, 6:47 a.m. UTC | #1
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
>
  
Jonathan Yong Oct. 1, 2026, 12:11 p.m. UTC | #2
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.
  
LIU Hao Oct. 1, 2026, 12:59 p.m. UTC | #3
在 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
  
Jonathan Yong Oct. 2, 2026, 1:42 p.m. UTC | #4
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?
  
Oleg Tolmatcev Oct. 2, 2026, 2:19 p.m. UTC | #5
пт, 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
  

Patch

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);
+}