79 lines
2.4 KiB
Diff
79 lines
2.4 KiB
Diff
From 60364b439a80c217174e1830e0b7507d6f4538c4 Mon Sep 17 00:00:00 2001
|
|
From: liuhongt <hongtao.liu@intel.com>
|
|
Date: Fri, 4 Aug 2023 09:27:39 +0800
|
|
Subject: [PATCH 10/32] Workaround possible CPUID bug in Sandy Bridge.
|
|
|
|
Don't access leaf 7 subleaf 1 unless subleaf 0 says it is
|
|
supported via EAX.
|
|
|
|
Intel documentation says invalid subleaves return 0. We had been
|
|
relying on that behavior instead of checking the max sublef number.
|
|
|
|
It appears that some Sandy Bridge CPUs return at least the subleaf 0
|
|
EDX value for subleaf 1. Best guess is that this is a bug in a
|
|
microcode patch since all of the bits we're seeing set in EDX were
|
|
introduced after Sandy Bridge was originally released.
|
|
|
|
This is causing avxvnniint16 to be incorrectly enabled with
|
|
-march=native on these CPUs.
|
|
|
|
gcc/ChangeLog:
|
|
|
|
* common/config/i386/cpuinfo.h (get_available_features): Check
|
|
max_subleaf_level for valid subleaf before use CPUID.
|
|
---
|
|
gcc/common/config/i386/cpuinfo.h | 29 +++++++++++++++++------------
|
|
1 file changed, 17 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
|
|
index 28b2ff0b0..316ad3cb3 100644
|
|
--- a/gcc/common/config/i386/cpuinfo.h
|
|
+++ b/gcc/common/config/i386/cpuinfo.h
|
|
@@ -647,7 +647,9 @@ get_available_features (struct __processor_model *cpu_model,
|
|
/* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */
|
|
if (max_cpuid_level >= 7)
|
|
{
|
|
- __cpuid_count (7, 0, eax, ebx, ecx, edx);
|
|
+ unsigned int max_subleaf_level;
|
|
+
|
|
+ __cpuid_count (7, 0, max_subleaf_level, ebx, ecx, edx);
|
|
if (ebx & bit_BMI)
|
|
set_feature (FEATURE_BMI);
|
|
if (ebx & bit_SGX)
|
|
@@ -759,18 +761,21 @@ get_available_features (struct __processor_model *cpu_model,
|
|
set_feature (FEATURE_AVX512FP16);
|
|
}
|
|
|
|
- __cpuid_count (7, 1, eax, ebx, ecx, edx);
|
|
- if (eax & bit_HRESET)
|
|
- set_feature (FEATURE_HRESET);
|
|
- if (avx_usable)
|
|
- {
|
|
- if (eax & bit_AVXVNNI)
|
|
- set_feature (FEATURE_AVXVNNI);
|
|
- }
|
|
- if (avx512_usable)
|
|
+ if (max_subleaf_level >= 1)
|
|
{
|
|
- if (eax & bit_AVX512BF16)
|
|
- set_feature (FEATURE_AVX512BF16);
|
|
+ __cpuid_count (7, 1, eax, ebx, ecx, edx);
|
|
+ if (eax & bit_HRESET)
|
|
+ set_feature (FEATURE_HRESET);
|
|
+ if (avx_usable)
|
|
+ {
|
|
+ if (eax & bit_AVXVNNI)
|
|
+ set_feature (FEATURE_AVXVNNI);
|
|
+ }
|
|
+ if (avx512_usable)
|
|
+ {
|
|
+ if (eax & bit_AVX512BF16)
|
|
+ set_feature (FEATURE_AVX512BF16);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
--
|
|
2.28.0.windows.1
|
|
|