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.
---
 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