On Tue, Jul 29, 2025 at 5:04 PM <a.gra...@ispras.ru> wrote:
>
> On 2025-07-25 11:18, Uros Bizjak wrote:
> > On Thu, Jul 24, 2025 at 5:35 PM Artemiy Granat <a.gra...@ispras.ru>
> > wrote:
> >>
> >> gcc/testsuite/ChangeLog:
> >>
> >>         * g++.dg/abi/regparm1.C: Use regparm attribute only if not in
> >>         64-bit mode.
> >>         * gcc.target/i386/20020224-1.c: Likewise.
> >>         * gcc.target/i386/pr103785.c: Likewise.
> >>         * gcc.target/i386/pr36533.c: Likewise.
> >>         * gcc.target/i386/pr59099.c: Likewise.
> >>         * gcc.target/i386/sibcall-8.c: Likewise.
> >>         * gcc.target/i386/sw-1.c: Likewise.
> >>         * gcc.target/i386/pr15184-2.c: Fix invalid comment.
> >>         * gcc.target/i386/attributes-ignore.c: New test.
> >
> > Please enable testcases that explicitly test regparm attribute only
> > for ix86 targets using ia32 target selector. They are irrelevant for
> > x86_64 anyway.
>
> I've set ia32 target as required for regparm1.C and 20020224-1.c. Other
> tests are useful in 64-bit mode too.
>
> ---8<---
>
>  From 1e966334eda2e4455190455554333fe86cb9ab50 Mon Sep 17 00:00:00 2001
>  From: Artemiy Granat <a.gra...@ispras.ru>
> Date: Tue, 29 Jul 2025 17:20:46 +0300
> Subject: [PATCH] i386: Ignore regparm attribute and warn for it in
> 64-bit mode
>
> The regparm attribute does not affect code generation on x86-64 target.
> Despite this, regparm was accepted silently, unlike other calling
> convention attributes handled in the ix86_handle_cconv_attribute
> function.
>
> Due to lack of diagnostics, Linux kernel attempted to specify regparm(0)
> on vmread_error_trampoline declaration, which is supposed to be invoked
> with all arguments on stack:
> https://lore.kernel.org/all/20220928232015.745948-1-sea...@google.com/
>
> To produce a warning for regparm in 64-bit mode, simply move the block
> that produces diagnostics above the block that handles the regparm
> attribute.
>
> gcc/ChangeLog:
>
>         * config/i386/i386-options.cc (ix86_handle_cconv_attribute):
>         Move 64-bit mode check before regparm handling.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/abi/regparm1.C: Require ia32 target.
>         * gcc.target/i386/20020224-1.c: Likewise.
>         * gcc.target/i386/pr103785.c: Use regparm attribute only if
>         not in 64-bit mode.
>         * gcc.target/i386/pr36533.c: Likewise.
>         * gcc.target/i386/pr59099.c: Likewise.
>         * gcc.target/i386/sibcall-8.c: Likewise.
>         * gcc.target/i386/sw-1.c: Likewise.
>         * gcc.target/i386/pr15184-2.c: Fix invalid comment.
>         * gcc.target/i386/attributes-ignore.c: New test.

OK.

Thanks,
Uros.


> ---
>   gcc/config/i386/i386-options.cc               | 24 +++++++++----------
>   gcc/testsuite/g++.dg/abi/regparm1.C           |  2 +-
>   gcc/testsuite/gcc.target/i386/20020224-1.c    |  1 +
>   .../gcc.target/i386/attributes-ignore.c       |  8 +++++++
>   gcc/testsuite/gcc.target/i386/pr103785.c      |  5 +++-
>   gcc/testsuite/gcc.target/i386/pr15184-2.c     |  2 +-
>   gcc/testsuite/gcc.target/i386/pr36533.c       | 24 +++++++++++++++----
>   gcc/testsuite/gcc.target/i386/pr59099.c       |  9 ++++++-
>   gcc/testsuite/gcc.target/i386/sibcall-8.c     | 14 +++++++----
>   gcc/testsuite/gcc.target/i386/sw-1.c          |  5 +++-
>   10 files changed, 69 insertions(+), 25 deletions(-)
>   create mode 100644 gcc/testsuite/gcc.target/i386/attributes-ignore.c
>
> diff --git a/gcc/config/i386/i386-options.cc
> b/gcc/config/i386/i386-options.cc
> index d244b225afe..f07e8bc5303 100644
> --- a/gcc/config/i386/i386-options.cc
> +++ b/gcc/config/i386/i386-options.cc
> @@ -3613,6 +3613,18 @@ ix86_handle_cconv_attribute (tree *node, tree
> name, tree args, int,
>         return NULL_TREE;
>       }
>
> +  if (TARGET_64BIT)
> +    {
> +      /* Do not warn when emulating the MS ABI.  */
> +      if ((TREE_CODE (*node) != FUNCTION_TYPE
> +          && TREE_CODE (*node) != METHOD_TYPE)
> +         || ix86_function_type_abi (*node) != MS_ABI)
> +       warning (OPT_Wattributes, "%qE attribute ignored",
> +                name);
> +      *no_add_attrs = true;
> +      return NULL_TREE;
> +    }
> +
>     /* Can combine regparm with all attributes but fastcall, and
> thiscall.  */
>     if (is_attribute_p ("regparm", name))
>       {
> @@ -3646,18 +3658,6 @@ ix86_handle_cconv_attribute (tree *node, tree
> name, tree args, int,
>         return NULL_TREE;
>       }
>
> -  if (TARGET_64BIT)
> -    {
> -      /* Do not warn when emulating the MS ABI.  */
> -      if ((TREE_CODE (*node) != FUNCTION_TYPE
> -          && TREE_CODE (*node) != METHOD_TYPE)
> -         || ix86_function_type_abi (*node) != MS_ABI)
> -       warning (OPT_Wattributes, "%qE attribute ignored",
> -                name);
> -      *no_add_attrs = true;
> -      return NULL_TREE;
> -    }
> -
>     /* Can combine fastcall with stdcall (redundant) and sseregparm.  */
>     if (is_attribute_p ("fastcall", name))
>       {
> diff --git a/gcc/testsuite/g++.dg/abi/regparm1.C
> b/gcc/testsuite/g++.dg/abi/regparm1.C
> index c4710464acc..3aae3dd207c 100644
> --- a/gcc/testsuite/g++.dg/abi/regparm1.C
> +++ b/gcc/testsuite/g++.dg/abi/regparm1.C
> @@ -1,5 +1,5 @@
>   // PR c++/29911 (9381)
> -// { dg-do run { target i?86-*-* x86_64-*-* } }
> +// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
>   // { dg-require-effective-target c++11 }
>
>   extern "C" int printf(const char *, ...);
> diff --git a/gcc/testsuite/gcc.target/i386/20020224-1.c
> b/gcc/testsuite/gcc.target/i386/20020224-1.c
> index 2905719fa62..769332b37dc 100644
> --- a/gcc/testsuite/gcc.target/i386/20020224-1.c
> +++ b/gcc/testsuite/gcc.target/i386/20020224-1.c
> @@ -4,6 +4,7 @@
>      while callee was actually not poping it up (as the hidden argument
>      was passed in register).  */
>   /* { dg-do run } */
> +/* { dg-require-effective-target ia32 } */
>   /* { dg-options "-O2 -fomit-frame-pointer" } */
>
>   extern void abort (void);
> diff --git a/gcc/testsuite/gcc.target/i386/attributes-ignore.c
> b/gcc/testsuite/gcc.target/i386/attributes-ignore.c
> new file mode 100644
> index 00000000000..93a3770842c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/attributes-ignore.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +
> +void foo1(int i, int j) __attribute__((regparm(0))); /* { dg-warning
> "ignored" } */
> +void foo2(int i, int j) __attribute__((stdcall)); /* { dg-warning
> "ignored" } */
> +void foo3(int i, int j) __attribute__((fastcall)); /* { dg-warning
> "ignored" } */
> +void foo4(int i, int j) __attribute__((cdecl)); /* { dg-warning
> "ignored" } */
> +void foo5(int i, int j) __attribute__((thiscall)); /* { dg-warning
> "ignored" } */
> +void foo6(int i, int j) __attribute__((sseregparm)); /* { dg-warning
> "ignored" } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr103785.c
> b/gcc/testsuite/gcc.target/i386/pr103785.c
> index 5503b965256..49d6c56f8d2 100644
> --- a/gcc/testsuite/gcc.target/i386/pr103785.c
> +++ b/gcc/testsuite/gcc.target/i386/pr103785.c
> @@ -11,7 +11,10 @@ struct wrapper_t
>
>   struct wrapper_t **table;
>
> -__attribute__ ((weak, regparm (2)))
> +#ifndef __x86_64__
> +__attribute__ ((regparm (2)))
> +#endif
> +__attribute__ ((weak))
>   void
>   update (long k, long e)
>   {
> diff --git a/gcc/testsuite/gcc.target/i386/pr15184-2.c
> b/gcc/testsuite/gcc.target/i386/pr15184-2.c
> index cb8201f9731..dd50c42b90d 100644
> --- a/gcc/testsuite/gcc.target/i386/pr15184-2.c
> +++ b/gcc/testsuite/gcc.target/i386/pr15184-2.c
> @@ -1,4 +1,4 @@
> -/* PR 15184 second two tests
> +/* PR 15184 second two tests */
>   /* { dg-do compile { target ia32 } } */
>   /* { dg-options "-O2 -march=pentiumpro" } */
>   /* { dg-additional-options "-fno-PIE" { target ia32 } } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr36533.c
> b/gcc/testsuite/gcc.target/i386/pr36533.c
> index 8d71ece199d..8699d262a59 100644
> --- a/gcc/testsuite/gcc.target/i386/pr36533.c
> +++ b/gcc/testsuite/gcc.target/i386/pr36533.c
> @@ -55,14 +55,22 @@ typedef struct
>     S1 *s18;
>   } S7;
>
> -__attribute__((regparm (3), noinline)) int
> +#ifndef __x86_64__
> +__attribute__((regparm (3)))
> +#endif
> +__attribute__((noinline))
> +int
>   fn1 (const char *x, void *y, S1 *z)
>   {
>     asm volatile ("" : : : "memory");
>     return *x + (y != 0);
>   }
>
> -__attribute__((regparm (3), noinline)) int
> +#ifndef __x86_64__
> +__attribute__((regparm (3)))
> +#endif
> +__attribute__((noinline))
> +int
>   fn2 (const char *x, int y, S2 *z)
>   {
>     asm volatile ("" : : : "memory");
> @@ -84,7 +92,11 @@ fn3 (S3 *p)
>     return (S3 *) ((char *) p + fn4 (p->s9));
>   }
>
> -__attribute__((regparm (3), noinline)) int
> +#ifndef __x86_64__
> +__attribute__((regparm (3)))
> +#endif
> +__attribute__((noinline))
> +int
>   fn5 (void)
>   {
>     asm volatile ("" : : : "memory");
> @@ -116,7 +128,11 @@ fn6 (S3 *w, int x, S2 *y, S4 *z)
>     return a;
>   }
>
> -__attribute__((regparm (3), noinline)) unsigned int
> +#ifndef __x86_64__
> +__attribute__((regparm (3)))
> +#endif
> +__attribute__((noinline))
> +unsigned int
>   test (void *u, S6 *v, S1 **w, S7 *x, S2 *y, S1 *z)
>   {
>     unsigned b = v->s17->s16;
> diff --git a/gcc/testsuite/gcc.target/i386/pr59099.c
> b/gcc/testsuite/gcc.target/i386/pr59099.c
> index cf4a8da7db1..21dfbc2defa 100644
> --- a/gcc/testsuite/gcc.target/i386/pr59099.c
> +++ b/gcc/testsuite/gcc.target/i386/pr59099.c
> @@ -13,10 +13,17 @@ struct s
>   };
>
>
> -void* f (struct s *, struct s *) __attribute__ ((noinline,
> regparm(1)));
> +void* f (struct s *, struct s *)
> +#ifndef __x86_64__
> +__attribute__ ((regparm(1)))
> +#endif
> +__attribute__ ((noinline))
> +;
>
>   void*
> +#ifndef __x86_64__
>   __attribute__ ((regparm(1)))
> +#endif
>   f (struct s *p, struct s *p2)
>   {
>     void *gp, *gp1;
> diff --git a/gcc/testsuite/gcc.target/i386/sibcall-8.c
> b/gcc/testsuite/gcc.target/i386/sibcall-8.c
> index 3ab3809036d..29ebfe59284 100644
> --- a/gcc/testsuite/gcc.target/i386/sibcall-8.c
> +++ b/gcc/testsuite/gcc.target/i386/sibcall-8.c
> @@ -1,23 +1,29 @@
>   /* { dg-do run } */
>   /* { dg-options "-O2" } */
>
> +#ifndef __x86_64__
> +#define REGPARM __attribute__((regparm(1)))
> +#else
> +#define REGPARM
> +#endif
> +
>   extern void abort (void);
>
> -static int __attribute__((regparm(1)))
> +static int REGPARM
>   bar(void *arg)
>   {
>     return arg != bar;
>   }
>
> -static int __attribute__((noinline,noclone,regparm(1)))
> -foo(int (__attribute__((regparm(1))) **bar)(void*))
> +static int __attribute__((noinline,noclone)) REGPARM
> +foo(int (REGPARM **bar)(void*))
>   {
>     return (*bar)(*bar);
>   }
>
>   int main()
>   {
> -  int (__attribute__((regparm(1))) *p)(void*) = bar;
> +  int (REGPARM *p)(void*) = bar;
>     if (foo(&p))
>       abort();
>     return 0;
> diff --git a/gcc/testsuite/gcc.target/i386/sw-1.c
> b/gcc/testsuite/gcc.target/i386/sw-1.c
> index 14db3cee206..025f0e15d51 100644
> --- a/gcc/testsuite/gcc.target/i386/sw-1.c
> +++ b/gcc/testsuite/gcc.target/i386/sw-1.c
> @@ -7,7 +7,10 @@
>
>   int c;
>   int x[2000];
> -__attribute__((regparm(1))) void foo (int a, int b)
> +#ifndef __x86_64__
> +__attribute__((regparm(1)))
> +#endif
> +void foo (int a, int b)
>    {
>      int t[200];
>      if (a == 0 || c == 0)
> --
> 2.50.1
>

Reply via email to