diff mbox series

[v2] x86: Don't enable UINTR in 32-bit mode

Message ID 20210713015130.6297-1-hjl.tools@gmail.com
State New
Headers show
Series [v2] x86: Don't enable UINTR in 32-bit mode | expand

Commit Message

H.J. Lu July 13, 2021, 1:51 a.m. UTC
UINTR is available only in 64-bit mode.  Since the codegen target is
unknown when the the gcc driver is processing -march=native, to properly
handle UINTR for -march=native:

1. Pass arch[32|64] and tune[32|64] to host_detect_local_cpu to indicate
32-bit and 64-bit codegen.
2. Change ix86_option_override_internal to enable UINTR only in 64-bit
mode for -march=CPU when PTA_CPU includes PTA_UINTR.

gcc/

	PR target/101395
	* config/i386/driver-i386.c (host_detect_local_cpu): Check
	arch32/tune32 and arch64/tune64 for 32-bit and 64-bit codegen.
	Enable UINTR only for 64-bit codegen.
	* config/i386/i386-options.c
	(ix86_option_override_internal::DEF_PTA): Skip PTA_UINTR if not
	in 64-bit mode.
	* config/i386/i386.h (CC1_CPU_SPEC): Pass arch32/tune32 for
	32-bit codegen and arch64/tune64 for 64-bit codegen.

gcc/testsuite/

	PR target/101395
	* gcc.target/i386/pr101395-1.c: New test.
	* gcc.target/i386/pr101395-2.c: Likewise.
	* gcc.target/i386/pr101395-3.c: Likewise.
---
 gcc/config/i386/driver-i386.c              | 30 ++++++++++++++++------
 gcc/config/i386/i386-options.c             |  1 +
 gcc/config/i386/i386.h                     |  9 ++++---
 gcc/testsuite/gcc.target/i386/pr101395-1.c | 12 +++++++++
 gcc/testsuite/gcc.target/i386/pr101395-2.c | 22 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr101395-3.c |  6 +++++
 6 files changed, 69 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr101395-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr101395-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr101395-3.c

Comments

Jakub Jelinek July 13, 2021, 6:55 a.m. UTC | #1
On Mon, Jul 12, 2021 at 06:51:30PM -0700, H.J. Lu wrote:
> @@ -404,9 +404,18 @@ const char *host_detect_local_cpu (int argc, const char **argv)
>    if (argc < 1)
>      return NULL;

I think it would be simpler to use 2 arguments instead of one.
So change the above to if (argc < 2)

>  
> -  arch = !strcmp (argv[0], "arch");
> +  arch = !strncmp (argv[0], "arch", 4);
>  
> -  if (!arch && strcmp (argv[0], "tune"))
> +  if (!arch && strncmp (argv[0], "tune", 4))
> +    return NULL;

Keep strcmp as is here.

> +
> +  bool codegen_x86_64;
> +
> +  if (!strcmp (argv[0] + 4, "32"))
> +    codegen_x86_64 = false;
> +  else if (!strcmp (argv[0] + 4, "64"))
> +    codegen_x86_64 = true;
> +  else
>      return NULL;

Check argv[1] here instead.

> @@ -813,7 +826,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
>      }
>  
>  done:
> -  return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
> +  const char *moption = arch ? "-march=" : "-mtune=";
> +  return concat (cache, moption, cpu, options, NULL);
>  }
>  #else

You don't need this change.

> diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
> index 7a35c468da3..7cba655595e 100644
> --- a/gcc/config/i386/i386-options.c
> +++ b/gcc/config/i386/i386-options.c
> @@ -2109,6 +2109,7 @@ ix86_option_override_internal (bool main_args_p,
>  #define DEF_PTA(NAME) \
>  	if (((processor_alias_table[i].flags & PTA_ ## NAME) != 0) \
>  	    && PTA_ ## NAME != PTA_64BIT \
> +	    && (TARGET_64BIT || PTA_ ## NAME != PTA_UINTR) \
>  	    && !TARGET_EXPLICIT_ ## NAME ## _P (opts)) \
>  	  SET_TARGET_ ## NAME (opts);
>  #include "i386-isa.def"
> diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
> index 8c3eace56da..ae9f455c48d 100644
> --- a/gcc/config/i386/i386.h
> +++ b/gcc/config/i386/i386.h
> @@ -577,9 +577,12 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
>  #define CC1_CPU_SPEC CC1_CPU_SPEC_1
>  #else
>  #define CC1_CPU_SPEC CC1_CPU_SPEC_1 \
> -"%{march=native:%>march=native %:local_cpu_detect(arch) \
> -  %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} \
> -%{mtune=native:%>mtune=native %:local_cpu_detect(tune)}"
> +"%{" OPT_ARCH32 ":%{march=native:%>march=native %:local_cpu_detect(arch32) \
> +		  %{!mtune=*:%>mtune=native %:local_cpu_detect(tune32)}}}" \
> +"%{" OPT_ARCH32 ":%{mtune=native:%>mtune=native %:local_cpu_detect(tune32)}}" \
> +"%{" OPT_ARCH64 ":%{march=native:%>march=native %:local_cpu_detect(arch64) \
> +		  %{!mtune=*:%>mtune=native %:local_cpu_detect(tune64)}}}" \
> +"%{" OPT_ARCH64 ":%{mtune=native:%>mtune=native %:local_cpu_detect(tune64)}}"

And you can use
#define ARCH_ARG "%{" OPT_ARCH64 ":64;32}"

%:local_cpu_detect(arch, " ARCH_ARG ")
etc.

	Jakub
diff mbox series

Patch

diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index dd9236616b4..b84f86d8f43 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -370,9 +370,9 @@  detect_caches_intel (bool xeon_mp, unsigned max_level,
 }
 
 /* This will be called by the spec parser in gcc.c when it sees
-   a %:local_cpu_detect(args) construct.  Currently it will be called
-   with either "arch" or "tune" as argument depending on if -march=native
-   or -mtune=native is to be substituted.
+   a %:local_cpu_detect(args) construct.  Currently it will be
+   called with either "arch[32|64]" or "tune[32|64]" as argument
+   depending on if -march=native or -mtune=native is to be substituted.
 
    It returns a string containing new command line parameters to be
    put at the place of the above two options, depending on what CPU
@@ -404,9 +404,18 @@  const char *host_detect_local_cpu (int argc, const char **argv)
   if (argc < 1)
     return NULL;
 
-  arch = !strcmp (argv[0], "arch");
+  arch = !strncmp (argv[0], "arch", 4);
 
-  if (!arch && strcmp (argv[0], "tune"))
+  if (!arch && strncmp (argv[0], "tune", 4))
+    return NULL;
+
+  bool codegen_x86_64;
+
+  if (!strcmp (argv[0] + 4, "32"))
+    codegen_x86_64 = false;
+  else if (!strcmp (argv[0] + 4, "64"))
+    codegen_x86_64 = true;
+  else
     return NULL;
 
   struct __processor_model cpu_model = { };
@@ -804,8 +813,12 @@  const char *host_detect_local_cpu (int argc, const char **argv)
 	if (isa_names_table[i].option)
 	  {
 	    if (has_feature (isa_names_table[i].feature))
-	      options = concat (options, " ",
-				isa_names_table[i].option, NULL);
+	      {
+		if (codegen_x86_64
+		    || isa_names_table[i].feature != FEATURE_UINTR)
+		  options = concat (options, " ",
+				    isa_names_table[i].option, NULL);
+	      }
 	    else
 	      options = concat (options, neg_option,
 				isa_names_table[i].option + 2, NULL);
@@ -813,7 +826,8 @@  const char *host_detect_local_cpu (int argc, const char **argv)
     }
 
 done:
-  return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
+  const char *moption = arch ? "-march=" : "-mtune=";
+  return concat (cache, moption, cpu, options, NULL);
 }
 #else
 
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
index 7a35c468da3..7cba655595e 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -2109,6 +2109,7 @@  ix86_option_override_internal (bool main_args_p,
 #define DEF_PTA(NAME) \
 	if (((processor_alias_table[i].flags & PTA_ ## NAME) != 0) \
 	    && PTA_ ## NAME != PTA_64BIT \
+	    && (TARGET_64BIT || PTA_ ## NAME != PTA_UINTR) \
 	    && !TARGET_EXPLICIT_ ## NAME ## _P (opts)) \
 	  SET_TARGET_ ## NAME (opts);
 #include "i386-isa.def"
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 8c3eace56da..ae9f455c48d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -577,9 +577,12 @@  extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define CC1_CPU_SPEC CC1_CPU_SPEC_1
 #else
 #define CC1_CPU_SPEC CC1_CPU_SPEC_1 \
-"%{march=native:%>march=native %:local_cpu_detect(arch) \
-  %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} \
-%{mtune=native:%>mtune=native %:local_cpu_detect(tune)}"
+"%{" OPT_ARCH32 ":%{march=native:%>march=native %:local_cpu_detect(arch32) \
+		  %{!mtune=*:%>mtune=native %:local_cpu_detect(tune32)}}}" \
+"%{" OPT_ARCH32 ":%{mtune=native:%>mtune=native %:local_cpu_detect(tune32)}}" \
+"%{" OPT_ARCH64 ":%{march=native:%>march=native %:local_cpu_detect(arch64) \
+		  %{!mtune=*:%>mtune=native %:local_cpu_detect(tune64)}}}" \
+"%{" OPT_ARCH64 ":%{mtune=native:%>mtune=native %:local_cpu_detect(tune64)}}"
 #endif
 #endif
 
diff --git a/gcc/testsuite/gcc.target/i386/pr101395-1.c b/gcc/testsuite/gcc.target/i386/pr101395-1.c
new file mode 100644
index 00000000000..74c8bfe891a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101395-1.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=sapphirerapids" } */
+
+#ifdef __x86_64__
+# ifndef __UINTR__
+#  error UINTR is not enabled for Sapphirerapids
+# endif
+#else
+# ifdef __UINTR__
+#  error UINTR is not usable in 32-bit mode
+# endif
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/pr101395-2.c b/gcc/testsuite/gcc.target/i386/pr101395-2.c
new file mode 100644
index 00000000000..f2b677f8c80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101395-2.c
@@ -0,0 +1,22 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -march=native" } */
+
+int
+main ()
+{
+  if (__builtin_cpu_supports ("uintr"))
+    {
+#ifdef __x86_64__
+# ifndef __UINTR__
+      __builtin_abort ();
+# endif
+#else
+# ifdef __UINTR__
+      __builtin_abort ();
+# endif
+#endif
+      return 0;
+    }
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr101395-3.c b/gcc/testsuite/gcc.target/i386/pr101395-3.c
new file mode 100644
index 00000000000..bc6ab423c93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101395-3.c
@@ -0,0 +1,6 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=native -mno-uintr" } */
+
+#ifdef __UINTR__
+# error UINTR should be disabled
+#endif