diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index 930abc3ea1bac4..be46a53ea73a88 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -585,6 +585,16 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, unsigned Brand_id, unsigned Features, unsigned Features2, unsigned Features3, unsigned *Type, unsigned *Subtype) { + auto testFeature = [&](unsigned F) { + if (F < 32) + return (Features & (1U << (F & 0x1f))) != 0; + if (F < 64) + return (Features2 & (1U << ((F - 32) & 0x1f))) != 0; + if (F < 96) + return (Features3 & (1U << ((F - 64) & 0x1f))) != 0; + llvm_unreachable("Unexpected FeatureBit"); + }; + if (Brand_id != 0) return; switch (Family) { @@ -595,7 +605,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, *Type = X86::INTEL_i486; break; case 5: - if (Features & (1 << X86::FEATURE_MMX)) { + if (testFeature(X86::FEATURE_MMX)) { *Type = X86::INTEL_PENTIUM_MMX; break; } @@ -711,9 +721,9 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, // Skylake Xeon: case 0x55: *Type = X86::INTEL_COREI7; - if (Features2 & (1 << (X86::FEATURE_AVX512BF16 - 32))) + if (testFeature(X86::FEATURE_AVX512BF16)) *Subtype = X86::INTEL_COREI7_COOPERLAKE; // "cooperlake" - else if (Features2 & (1 << (X86::FEATURE_AVX512VNNI - 32))) + else if (testFeature(X86::FEATURE_AVX512VNNI)) *Subtype = X86::INTEL_COREI7_CASCADELAKE; // "cascadelake" else *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512" @@ -777,50 +787,50 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, break; default: // Unknown family 6 CPU, try to guess. - // TODO detect tigerlake host - if (Features2 & (1 << (X86::FEATURE_AVX512VP2INTERSECT - 32))) { + // TODO detect tigerlake host from model + if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_TIGERLAKE; break; } - if (Features & (1 << X86::FEATURE_AVX512VBMI2)) { + if (testFeature(X86::FEATURE_AVX512VBMI2)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT; break; } - if (Features & (1 << X86::FEATURE_AVX512VBMI)) { + if (testFeature(X86::FEATURE_AVX512VBMI)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_CANNONLAKE; break; } - if (Features2 & (1 << (X86::FEATURE_AVX512BF16 - 32))) { + if (testFeature(X86::FEATURE_AVX512BF16)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_COOPERLAKE; break; } - if (Features2 & (1 << (X86::FEATURE_AVX512VNNI - 32))) { + if (testFeature(X86::FEATURE_AVX512VNNI)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_CASCADELAKE; break; } - if (Features & (1 << X86::FEATURE_AVX512VL)) { + if (testFeature(X86::FEATURE_AVX512VL)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; break; } - if (Features & (1 << X86::FEATURE_AVX512ER)) { + if (testFeature(X86::FEATURE_AVX512ER)) { *Type = X86::INTEL_KNL; // knl break; } - if (Features3 & (1 << (X86::FEATURE_CLFLUSHOPT - 64))) { - if (Features3 & (1 << (X86::FEATURE_SHA - 64))) { + if (testFeature(X86::FEATURE_CLFLUSHOPT)) { + if (testFeature(X86::FEATURE_SHA)) { *Type = X86::INTEL_GOLDMONT; } else { *Type = X86::INTEL_COREI7; @@ -828,23 +838,23 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, } break; } - if (Features3 & (1 << (X86::FEATURE_ADX - 64))) { + if (testFeature(X86::FEATURE_ADX)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_BROADWELL; break; } - if (Features & (1 << X86::FEATURE_AVX2)) { + if (testFeature(X86::FEATURE_AVX2)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_HASWELL; break; } - if (Features & (1 << X86::FEATURE_AVX)) { + if (testFeature(X86::FEATURE_AVX)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_SANDYBRIDGE; break; } - if (Features & (1 << X86::FEATURE_SSE4_2)) { - if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) { + if (testFeature(X86::FEATURE_SSE4_2)) { + if (testFeature(X86::FEATURE_MOVBE)) { *Type = X86::INTEL_SILVERMONT; } else { *Type = X86::INTEL_COREI7; @@ -852,13 +862,13 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, } break; } - if (Features & (1 << X86::FEATURE_SSE4_1)) { + if (testFeature(X86::FEATURE_SSE4_1)) { *Type = X86::INTEL_CORE2; // "penryn" *Subtype = X86::INTEL_CORE2_45; break; } - if (Features & (1 << X86::FEATURE_SSSE3)) { - if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) { + if (testFeature(X86::FEATURE_SSSE3)) { + if (testFeature(X86::FEATURE_MOVBE)) { *Type = X86::INTEL_BONNELL; // "bonnell" } else { *Type = X86::INTEL_CORE2; // "core2" @@ -866,24 +876,24 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, } break; } - if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) { + if (testFeature(X86::FEATURE_EM64T)) { *Type = X86::INTEL_CORE2; // "core2" *Subtype = X86::INTEL_CORE2_65; break; } - if (Features & (1 << X86::FEATURE_SSE3)) { + if (testFeature(X86::FEATURE_SSE3)) { *Type = X86::INTEL_CORE_DUO; break; } - if (Features & (1 << X86::FEATURE_SSE2)) { + if (testFeature(X86::FEATURE_SSE2)) { *Type = X86::INTEL_PENTIUM_M; break; } - if (Features & (1 << X86::FEATURE_SSE)) { + if (testFeature(X86::FEATURE_SSE)) { *Type = X86::INTEL_PENTIUM_III; break; } - if (Features & (1 << X86::FEATURE_MMX)) { + if (testFeature(X86::FEATURE_MMX)) { *Type = X86::INTEL_PENTIUM_II; break; } @@ -892,11 +902,11 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, } break; case 15: { - if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) { + if (testFeature(X86::FEATURE_EM64T)) { *Type = X86::INTEL_NOCONA; break; } - if (Features & (1 << X86::FEATURE_SSE3)) { + if (testFeature(X86::FEATURE_SSE3)) { *Type = X86::INTEL_PRESCOTT; break; } @@ -911,6 +921,12 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, unsigned Features, unsigned *Type, unsigned *Subtype) { + auto testFeature = [&](unsigned F) { + if (F < 32) + return (Features & (1U << (F & 0x1f))) != 0; + llvm_unreachable("Unexpected FeatureBit"); + }; + // FIXME: this poorly matches the generated SubtargetFeatureKV table. There // appears to be no way to generate the wide variety of AMD-specific targets // from the information returned from CPUID. @@ -938,14 +954,14 @@ static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, } break; case 6: - if (Features & (1 << X86::FEATURE_SSE)) { + if (testFeature(X86::FEATURE_SSE)) { *Type = X86::AMD_ATHLON_XP; break; // "athlon-xp" } *Type = X86::AMD_ATHLON; break; // "athlon" case 15: - if (Features & (1 << X86::FEATURE_SSE3)) { + if (testFeature(X86::FEATURE_SSE3)) { *Type = X86::AMD_K8SSE3; break; // "k8-sse3" }