about summary refs log tree commit diff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-08-25 11:01:03 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-08-25 11:44:24 -0700
commitace02433fe2f0ce124d191bb273f738ef56fe387 (patch)
tree95f8ae66e11e12d68f2cbaad727a82db21f6b829
parent7ab70c98e87b6fbcb3c2c02075b0949ed239ad7e (diff)
downloadglibc-ace02433fe2f0ce124d191bb273f738ef56fe387.tar.gz
glibc-ace02433fe2f0ce124d191bb273f738ef56fe387.tar.xz
glibc-ace02433fe2f0ce124d191bb273f738ef56fe387.zip
x86: Add MathVec_Prefer_No_AVX512 to cpu-features [BZ #21967] hjl/pr21967/master
AVX512 functions in mathvec are used on machines with AVX512.  An AVX2
wrapper is also provided and it can be used when the AVX512 version
isn't profitable.  MathVec_Prefer_No_AVX512 is addded to cpu-features.
If glibc.tune.hwcaps=MathVec_Prefer_No_AVX512 is set in GLIBC_TUNABLES
environment variable, the AVX2 wrapper will be used.

	[BZ #21967]
	* sysdeps/x86/cpu-features.h (bit_arch_MathVec_Prefer_No_AVX512):
	New.
	(index_arch_MathVec_Prefer_No_AVX512): Likewise.
	* sysdeps/x86/cpu-tunables.c (TUNABLE_CALLBACK (set_hwcaps)):
	Handle MathVec_Prefer_No_AVX512.
-rw-r--r--sysdeps/x86/cpu-features.h2
-rw-r--r--sysdeps/x86/cpu-tunables.c7
-rw-r--r--sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h13
3 files changed, 17 insertions, 5 deletions
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 9e01781424..a032a2e168 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -40,6 +40,7 @@
 #define bit_arch_Use_dl_runtime_resolve_opt	(1 << 20)
 #define bit_arch_Use_dl_runtime_resolve_slow	(1 << 21)
 #define bit_arch_Prefer_No_AVX512		(1 << 22)
+#define bit_arch_MathVec_Prefer_No_AVX512	(1 << 23)
 
 /* CPUID Feature flags.  */
 
@@ -239,6 +240,7 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define index_arch_Use_dl_runtime_resolve_opt FEATURE_INDEX_1
 # define index_arch_Use_dl_runtime_resolve_slow FEATURE_INDEX_1
 # define index_arch_Prefer_No_AVX512	FEATURE_INDEX_1
+# define index_arch_MathVec_Prefer_No_AVX512 FEATURE_INDEX_1
 
 #endif	/* !__ASSEMBLER__ */
 
diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
index 0ab708cca8..ec72d86f08 100644
--- a/sysdeps/x86/cpu-tunables.c
+++ b/sysdeps/x86/cpu-tunables.c
@@ -303,6 +303,13 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
 		 disable, 23);
 	    }
 	  break;
+	case 24:
+	    {
+	      CHECK_GLIBC_IFUNC_ARCH_NEED_ARCH_BOTH
+		(n, cpu_features, MathVec_Prefer_No_AVX512,
+		 AVX512F_Usable, disable, 24);
+	    }
+	  break;
 	case 26:
 	    {
 	      CHECK_GLIBC_IFUNC_ARCH_NEED_CPU_BOTH
diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h
index 1857e1f760..fffc9da114 100644
--- a/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h
+++ b/sysdeps/x86_64/fpu/multiarch/ifunc-mathvec-avx512.h
@@ -32,11 +32,14 @@ IFUNC_SELECTOR (void)
 {
   const struct cpu_features* cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURES_ARCH_P (cpu_features, AVX512DQ_Usable))
-    return OPTIMIZE (skx);
-
-  if (CPU_FEATURES_ARCH_P (cpu_features, AVX512F_Usable))
-    return OPTIMIZE (knl);
+  if (!CPU_FEATURES_ARCH_P (cpu_features, MathVec_Prefer_No_AVX512))
+    {
+      if (CPU_FEATURES_ARCH_P (cpu_features, AVX512DQ_Usable))
+	return OPTIMIZE (skx);
+
+      if (CPU_FEATURES_ARCH_P (cpu_features, AVX512F_Usable))
+	return OPTIMIZE (knl);
+    }
 
   return OPTIMIZE (avx2_wrapper);
 }