diff --git a/compiler-rt/lib/builtins/cpu_model/x86.c b/compiler-rt/lib/builtins/cpu_model/x86.c index 7e8acb3e73eda..50b0f141cf4d3 100644 --- a/compiler-rt/lib/builtins/cpu_model/x86.c +++ b/compiler-rt/lib/builtins/cpu_model/x86.c @@ -125,8 +125,8 @@ enum ProcessorFeatures { FEATURE_AVX512BW, FEATURE_AVX512DQ, FEATURE_AVX512CD, - FEATURE_AVX512ER, - FEATURE_AVX512PF, + FEATURE_NF, + FEATURE_CF, FEATURE_AVX512VBMI, FEATURE_AVX512IFMA, FEATURE_AVX5124VNNIW, @@ -142,10 +142,10 @@ enum ProcessorFeatures { // FIXME: Below Features has some missings comparing to gcc, it's because gcc // has some not one-to-one mapped in llvm. FEATURE_3DNOW, - // FEATURE_3DNOWP, + // FEATURE_3DNOWA, FEATURE_ADX = 40, - // FEATURE_ABM, - FEATURE_CLDEMOTE = 42, + FEATURE_64BIT, + FEATURE_CLDEMOTE, FEATURE_CLFLUSHOPT, FEATURE_CLWB, FEATURE_CLZERO, @@ -157,7 +157,7 @@ enum ProcessorFeatures { FEATURE_ENQCMD = 48, FEATURE_F16C, FEATURE_FSGSBASE, - // FEATURE_FXSAVE, + FEATURE_CRC32, // FEATURE_HLE, // FEATURE_IBT, FEATURE_LAHF_LM = 54, @@ -171,7 +171,7 @@ enum ProcessorFeatures { // FEATURE_OSXSAVE, FEATURE_PCONFIG = 63, FEATURE_PKU, - FEATURE_PREFETCHWT1, + FEATURE_EVEX512, FEATURE_PRFCHW, FEATURE_PTWRITE, FEATURE_RDPID, @@ -205,6 +205,7 @@ enum ProcessorFeatures { FEATURE_X86_64_V2, FEATURE_X86_64_V3, FEATURE_X86_64_V4, + FEATURE_APXF, FEATURE_AVXIFMA, FEATURE_AVXVNNIINT8, FEATURE_AVXNECONVERT, @@ -217,7 +218,7 @@ enum ProcessorFeatures { FEATURE_SM3, FEATURE_SHA512, FEATURE_SM4, - FEATURE_APXF, + FEATUE_EGPR, FEATURE_USERMSR, FEATURE_AVX10_1_256, FEATURE_AVX10_1_512, @@ -804,8 +805,10 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(FEATURE_CMPXCHG16B); if ((ECX >> 19) & 1) setFeature(FEATURE_SSE4_1); - if ((ECX >> 20) & 1) + if ((ECX >> 20) & 1) { setFeature(FEATURE_SSE4_2); + setFeature(FEATURE_CRC32); + } if ((ECX >> 22) & 1) setFeature(FEATURE_MOVBE); if ((ECX >> 23) & 1) @@ -858,8 +861,10 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(FEATURE_BMI2); if (HasLeaf7 && ((EBX >> 11) & 1)) setFeature(FEATURE_RTM); - if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) + if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) { setFeature(FEATURE_AVX512F); + setFeature(FEATURE_EVEX512); + } if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) setFeature(FEATURE_AVX512DQ); if (HasLeaf7 && ((EBX >> 18) & 1)) @@ -868,12 +873,10 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(FEATURE_ADX); if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save) setFeature(FEATURE_AVX512IFMA); + if (HasLeaf7 && ((EBX >> 23) & 1)) + setFeature(FEATURE_CLFLUSHOPT); if (HasLeaf7 && ((EBX >> 24) & 1)) setFeature(FEATURE_CLWB); - if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save) - setFeature(FEATURE_AVX512PF); - if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save) - setFeature(FEATURE_AVX512ER); if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save) setFeature(FEATURE_AVX512CD); if (HasLeaf7 && ((EBX >> 29) & 1)) @@ -883,8 +886,6 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save) setFeature(FEATURE_AVX512VL); - if (HasLeaf7 && ((ECX >> 0) & 1)) - setFeature(FEATURE_PREFETCHWT1); if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save) setFeature(FEATURE_AVX512VBMI); if (HasLeaf7 && ((ECX >> 4) & 1)) @@ -1028,7 +1029,7 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(FEATURE_MWAITX); if (((EDX >> 29) & 1)) - setFeature(FEATURE_LM); + setFeature(FEATURE_64BIT); } bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 && @@ -1048,7 +1049,7 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, if (HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1)) setFeature(FEATURE_WIDEKL); - if (hasFeature(FEATURE_LM) && hasFeature(FEATURE_SSE2)) { + if (hasFeature(FEATURE_64BIT) && hasFeature(FEATURE_SSE2)) { setFeature(FEATURE_X86_64_BASELINE); if (hasFeature(FEATURE_CMPXCHG16B) && hasFeature(FEATURE_POPCNT) && hasFeature(FEATURE_LAHF_LM) && hasFeature(FEATURE_SSE4_2)) { diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def b/llvm/include/llvm/TargetParser/X86TargetParser.def index 0e4ad873e3639..21628ed9697c2 100644 --- a/llvm/include/llvm/TargetParser/X86TargetParser.def +++ b/llvm/include/llvm/TargetParser/X86TargetParser.def @@ -191,8 +191,8 @@ X86_FEATURE_COMPAT(FSGSBASE, "fsgsbase", 0) X86_FEATURE (CRC32, "crc32") X86_FEATURE (INVPCID, "invpcid") X86_FEATURE (RDPRU, "rdpru") -X86_FEATURE (SAHF, "sahf") -X86_FEATURE (VZEROUPPER, "vzeroupper") +X86_FEATURE (LAHF_LM, "sahf") +X86_FEATURE (LM, "lm") X86_FEATURE_COMPAT(LWP, "lwp", 0) X86_FEATURE_COMPAT(LZCNT, "lzcnt", 0) X86_FEATURE_COMPAT(MOVBE, "movbe", 0) @@ -250,7 +250,7 @@ X86_FEATURE_COMPAT(SHA512, "sha512", 0) X86_FEATURE_COMPAT(SM4, "sm4", 0) X86_FEATURE (EGPR, "egpr") X86_FEATURE_COMPAT(USERMSR, "usermsr", 0) -X86_FEATURE_COMPAT(AVX10_1, "avx10.1-256", 36) +X86_FEATURE_COMPAT(AVX10_1_256, "avx10.1-256", 36) X86_FEATURE_COMPAT(AVX10_1_512, "avx10.1-512", 37) X86_FEATURE (ZU, "zu") // These features aren't really CPU features, but the frontend can set them. @@ -264,7 +264,7 @@ X86_MICROARCH_LEVEL(X86_64_BASELINE,"x86-64", 95) X86_MICROARCH_LEVEL(X86_64_V2, "x86-64-v2", 96) X86_MICROARCH_LEVEL(X86_64_V3, "x86-64-v3", 97) X86_MICROARCH_LEVEL(X86_64_V4, "x86-64-v4", 98) -X86_MICROARCH_LEVEL(APXF, "apxf", 111) +X86_MICROARCH_LEVEL(APXF, "apxf", 99) #undef X86_FEATURE_COMPAT #undef X86_FEATURE #undef X86_MICROARCH_LEVEL diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 2ea56746aff24..0a1ebd9ec0921 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1225,11 +1225,10 @@ getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, unsigned *Features) { - unsigned EAX, EBX; + unsigned EAX = 0, EBX = 0; - auto setFeature = [&](unsigned F) { - Features[F / 32] |= 1U << (F % 32); - }; +#define hasFeature(F) ((Features[F / 32] >> (F % 32)) & 1) +#define setFeature(F) Features[F / 32] |= 1U << (F % 32) if ((EDX >> 15) & 1) setFeature(X86::FEATURE_CMOV); @@ -1248,26 +1247,31 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(X86::FEATURE_SSSE3); if ((ECX >> 12) & 1) setFeature(X86::FEATURE_FMA); + if ((ECX >> 13) & 1) + setFeature(X86::FEATURE_CMPXCHG16B); if ((ECX >> 19) & 1) setFeature(X86::FEATURE_SSE4_1); if ((ECX >> 20) & 1) { setFeature(X86::FEATURE_SSE4_2); setFeature(X86::FEATURE_CRC32); } + if ((ECX >> 22) & 1) + setFeature(X86::FEATURE_MOVBE); if ((ECX >> 23) & 1) setFeature(X86::FEATURE_POPCNT); if ((ECX >> 25) & 1) setFeature(X86::FEATURE_AES); - - if ((ECX >> 22) & 1) - setFeature(X86::FEATURE_MOVBE); + if ((ECX >> 29) & 1) + setFeature(X86::FEATURE_F16C); + if ((ECX >> 30) & 1) + setFeature(X86::FEATURE_RDRND); // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV // indicates that the AVX registers will be saved and restored on context // switch, then we have full AVX support. const unsigned AVXBits = (1 << 27) | (1 << 28); - bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && - ((EAX & 0x6) == 0x6); + bool HasAVXSave = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && + ((EAX & 0x6) == 0x6); #if defined(__APPLE__) // Darwin lazily saves the AVX512 context on first use: trust that the OS will // save the AVX512 context if we use AVX512 instructions, even the bit is not @@ -1275,33 +1279,50 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, bool HasAVX512Save = true; #else // AVX512 requires additional context to be saved by the OS. - bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); + bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); #endif + // AMX requires additional context to be saved by the OS. + const unsigned AMXBits = (1 << 17) | (1 << 18); + bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX); + bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits); - if (HasAVX) + if (HasAVXSave) setFeature(X86::FEATURE_AVX); + if (((ECX >> 26) & 1) && HasAVXSave) + setFeature(X86::FEATURE_XSAVE); + bool HasLeaf7 = MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf7 && ((EBX >> 0) & 1)) + setFeature(X86::FEATURE_FSGSBASE); + if (HasLeaf7 && ((EBX >> 2) & 1)) + setFeature(X86::FEATURE_SGX); if (HasLeaf7 && ((EBX >> 3) & 1)) setFeature(X86::FEATURE_BMI); - if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) + if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave) setFeature(X86::FEATURE_AVX2); if (HasLeaf7 && ((EBX >> 8) & 1)) setFeature(X86::FEATURE_BMI2); + if (HasLeaf7 && ((EBX >> 11) & 1)) + setFeature(X86::FEATURE_RTM); if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) { setFeature(X86::FEATURE_AVX512F); setFeature(X86::FEATURE_EVEX512); } if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512DQ); + if (HasLeaf7 && ((EBX >> 18) & 1)) + setFeature(X86::FEATURE_RDSEED); if (HasLeaf7 && ((EBX >> 19) & 1)) setFeature(X86::FEATURE_ADX); if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512IFMA); if (HasLeaf7 && ((EBX >> 23) & 1)) setFeature(X86::FEATURE_CLFLUSHOPT); + if (HasLeaf7 && ((EBX >> 24) & 1)) + setFeature(X86::FEATURE_CLWB); if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512CD); if (HasLeaf7 && ((EBX >> 29) & 1)) @@ -1313,11 +1334,19 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512VBMI); + if (HasLeaf7 && ((ECX >> 4) & 1)) + setFeature(X86::FEATURE_PKU); + if (HasLeaf7 && ((ECX >> 5) & 1)) + setFeature(X86::FEATURE_WAITPKG); if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512VBMI2); + if (HasLeaf7 && ((ECX >> 7) & 1)) + setFeature(X86::FEATURE_SHSTK); if (HasLeaf7 && ((ECX >> 8) & 1)) setFeature(X86::FEATURE_GFNI); - if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX) + if (HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave) + setFeature(X86::FEATURE_VAES); + if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave) setFeature(X86::FEATURE_VPCLMULQDQ); if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512VNNI); @@ -1325,36 +1354,169 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(X86::FEATURE_AVX512BITALG); if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512VPOPCNTDQ); + if (HasLeaf7 && ((ECX >> 22) & 1)) + setFeature(X86::FEATURE_RDPID); + if (HasLeaf7 && ((ECX >> 23) & 1)) + setFeature(X86::FEATURE_KL); + if (HasLeaf7 && ((ECX >> 25) & 1)) + setFeature(X86::FEATURE_CLDEMOTE); + if (HasLeaf7 && ((ECX >> 27) & 1)) + setFeature(X86::FEATURE_MOVDIRI); + if (HasLeaf7 && ((ECX >> 28) & 1)) + setFeature(X86::FEATURE_MOVDIR64B); + if (HasLeaf7 && ((ECX >> 29) & 1)) + setFeature(X86::FEATURE_ENQCMD); if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX5124VNNIW); if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX5124FMAPS); + if (HasLeaf7 && ((EDX >> 5) & 1)) + setFeature(X86::FEATURE_UINTR); if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512VP2INTERSECT); + if (HasLeaf7 && ((EDX >> 14) & 1)) + setFeature(X86::FEATURE_SERIALIZE); + if (HasLeaf7 && ((EDX >> 16) & 1)) + setFeature(X86::FEATURE_TSXLDTRK); + if (HasLeaf7 && ((EDX >> 18) & 1)) + setFeature(X86::FEATURE_PCONFIG); + if (HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave) + setFeature(X86::FEATURE_AMX_BF16); + if (HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save) + setFeature(X86::FEATURE_AVX512FP16); + if (HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave) + setFeature(X86::FEATURE_AMX_TILE); + if (HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave) + setFeature(X86::FEATURE_AMX_INT8); // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't // return all 0s for invalid subleaves so check the limit. bool HasLeaf7Subleaf1 = HasLeaf7 && EAX >= 1 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf7Subleaf1 && ((EAX >> 0) & 1)) + setFeature(X86::FEATURE_SHA512); + if (HasLeaf7Subleaf1 && ((EAX >> 1) & 1)) + setFeature(X86::FEATURE_SM3); + if (HasLeaf7Subleaf1 && ((EAX >> 2) & 1)) + setFeature(X86::FEATURE_SM4); + if (HasLeaf7Subleaf1 && ((EAX >> 3) & 1)) + setFeature(X86::FEATURE_RAOINT); + if (HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave) + setFeature(X86::FEATURE_AVXVNNI); if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512BF16); + if (HasLeaf7Subleaf1 && ((EAX >> 7) & 1)) + setFeature(X86::FEATURE_CMPCCXADD); + if (HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave) + setFeature(X86::FEATURE_AMX_FP16); + if (HasLeaf7Subleaf1 && ((EAX >> 22) & 1)) + setFeature(X86::FEATURE_HRESET); + if (HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave) + setFeature(X86::FEATURE_AVXIFMA); + + if (HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave) + setFeature(X86::FEATURE_AVXVNNIINT8); + if (HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave) + setFeature(X86::FEATURE_AVXNECONVERT); + if (HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave) + setFeature(X86::FEATURE_AMX_COMPLEX); + if (HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave) + setFeature(X86::FEATURE_AVXVNNIINT16); + if (HasLeaf7Subleaf1 && ((EDX >> 14) & 1)) + setFeature(X86::FEATURE_PREFETCHI); + if (HasLeaf7Subleaf1 && ((EDX >> 15) & 1)) + setFeature(X86::FEATURE_USERMSR); + if (HasLeaf7Subleaf1 && ((EDX >> 19) & 1)) + setFeature(X86::FEATURE_AVX10_1_256); + if (HasLeaf7Subleaf1 && ((EDX >> 21) & 1)) + setFeature(X86::FEATURE_APXF); + + unsigned MaxLevel; + getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX); + bool HasLeafD = MaxLevel >= 0xd && + !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); + if (HasLeafD && ((EAX >> 0) & 1) && HasAVXSave) + setFeature(X86::FEATURE_XSAVEOPT); + if (HasLeafD && ((EAX >> 1) & 1) && HasAVXSave) + setFeature(X86::FEATURE_XSAVEC); + if (HasLeafD && ((EAX >> 3) & 1) && HasAVXSave) + setFeature(X86::FEATURE_XSAVES); + + bool HasLeaf24 = + MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf7Subleaf1 && ((EDX >> 19) & 1) && HasLeaf24 && ((EBX >> 18) & 1)) + setFeature(X86::FEATURE_AVX10_1_512); unsigned MaxExtLevel; getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); - if (HasExtLeaf1 && ((ECX >> 6) & 1)) - setFeature(X86::FEATURE_SSE4_A); - if (HasExtLeaf1 && ((ECX >> 11) & 1)) - setFeature(X86::FEATURE_XOP); - if (HasExtLeaf1 && ((ECX >> 16) & 1)) - setFeature(X86::FEATURE_FMA4); - - if (HasExtLeaf1 && ((EDX >> 29) & 1)) - setFeature(X86::FEATURE_64BIT); + if (HasExtLeaf1) { + if (ECX & 1) + setFeature(X86::FEATURE_LAHF_LM); + if ((ECX >> 5) & 1) + setFeature(X86::FEATURE_LZCNT); + if (((ECX >> 6) & 1)) + setFeature(X86::FEATURE_SSE4_A); + if (((ECX >> 8) & 1)) + setFeature(X86::FEATURE_PRFCHW); + if (((ECX >> 11) & 1)) + setFeature(X86::FEATURE_XOP); + if (((ECX >> 15) & 1)) + setFeature(X86::FEATURE_LWP); + if (((ECX >> 16) & 1)) + setFeature(X86::FEATURE_FMA4); + if (((ECX >> 21) & 1)) + setFeature(X86::FEATURE_TBM); + if (((ECX >> 29) & 1)) + setFeature(X86::FEATURE_MWAITX); + + if (((EDX >> 29) & 1)) + setFeature(X86::FEATURE_64BIT); + } + + bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 && + !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX); + if (HasExtLeaf8 && ((EBX >> 0) & 1)) + setFeature(X86::FEATURE_CLZERO); + if (HasExtLeaf8 && ((EBX >> 9) & 1)) + setFeature(X86::FEATURE_WBNOINVD); + + bool HasLeaf14 = MaxLevel >= 0x14 && + !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf14 && ((EBX >> 4) & 1)) + setFeature(X86::FEATURE_PTWRITE); + + bool HasLeaf19 = + MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1)) + setFeature(X86::FEATURE_WIDEKL); + + if (hasFeature(X86::FEATURE_64BIT) && hasFeature(X86::FEATURE_SSE2)) { + setFeature(X86::FEATURE_X86_64_BASELINE); + if (hasFeature(X86::FEATURE_CMPXCHG16B) && + hasFeature(X86::FEATURE_POPCNT) && hasFeature(X86::FEATURE_LAHF_LM) && + hasFeature(X86::FEATURE_SSE4_2)) { + setFeature(X86::FEATURE_X86_64_V2); + if (hasFeature(X86::FEATURE_AVX2) && hasFeature(X86::FEATURE_BMI) && + hasFeature(X86::FEATURE_BMI2) && hasFeature(X86::FEATURE_F16C) && + hasFeature(X86::FEATURE_FMA) && hasFeature(X86::FEATURE_LZCNT) && + hasFeature(X86::FEATURE_MOVBE)) { + setFeature(X86::FEATURE_X86_64_V3); + if (hasFeature(X86::FEATURE_AVX512BW) && + hasFeature(X86::FEATURE_AVX512CD) && + hasFeature(X86::FEATURE_AVX512DQ) && + hasFeature(X86::FEATURE_AVX512VL)) + setFeature(X86::FEATURE_X86_64_V4); + } + } + } + +#undef hasFeature +#undef setFeature } StringRef sys::getHostCPUName() { diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp index 141ecb936b708..07e85d3a8f4a8 100644 --- a/llvm/lib/TargetParser/X86TargetParser.cpp +++ b/llvm/lib/TargetParser/X86TargetParser.cpp @@ -66,7 +66,7 @@ constexpr FeatureBitset FeaturesNocona = // Basic 64-bit capable CPU. constexpr FeatureBitset FeaturesX86_64 = FeaturesPentium4 | Feature64BIT; -constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureSAHF | +constexpr FeatureBitset FeaturesX86_64_V2 = FeaturesX86_64 | FeatureLAHF_LM | FeaturePOPCNT | FeatureCRC32 | FeatureSSE4_2 | FeatureCMPXCHG16B; constexpr FeatureBitset FeaturesX86_64_V3 = @@ -78,7 +78,7 @@ constexpr FeatureBitset FeaturesX86_64_V4 = FeaturesX86_64_V3 | FeatureEVEX512 | // Intel Core CPUs constexpr FeatureBitset FeaturesCore2 = - FeaturesNocona | FeatureSAHF | FeatureSSSE3; + FeaturesNocona | FeatureLAHF_LM | FeatureSSSE3; constexpr FeatureBitset FeaturesPenryn = FeaturesCore2 | FeatureSSE4_1; constexpr FeatureBitset FeaturesNehalem = FeaturesPenryn | FeaturePOPCNT | FeatureCRC32 | FeatureSSE4_2; @@ -186,14 +186,14 @@ constexpr FeatureBitset FeaturesK8 = constexpr FeatureBitset FeaturesK8SSE3 = FeaturesK8 | FeatureSSE3; constexpr FeatureBitset FeaturesAMDFAM10 = FeaturesK8SSE3 | FeatureCMPXCHG16B | FeatureLZCNT | FeaturePOPCNT | - FeaturePRFCHW | FeatureSAHF | FeatureSSE4_A; + FeaturePRFCHW | FeatureLAHF_LM | FeatureSSE4_A; // Bobcat architecture processors. constexpr FeatureBitset FeaturesBTVER1 = FeatureX87 | FeatureCMPXCHG8B | FeatureCMPXCHG16B | Feature64BIT | FeatureFXSR | FeatureLZCNT | FeatureMMX | FeaturePOPCNT | FeaturePRFCHW | FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_A | - FeatureSAHF; + FeatureLAHF_LM; constexpr FeatureBitset FeaturesBTVER2 = FeaturesBTVER1 | FeatureAES | FeatureAVX | FeatureBMI | FeatureCRC32 | FeatureF16C | FeatureMOVBE | FeaturePCLMUL | FeatureXSAVE | FeatureXSAVEOPT; @@ -203,7 +203,7 @@ constexpr FeatureBitset FeaturesBDVER1 = FeatureX87 | FeatureAES | FeatureAVX | FeatureCMPXCHG8B | FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT | FeatureFMA4 | FeatureFXSR | FeatureLWP | FeatureLZCNT | FeatureMMX | FeaturePCLMUL | - FeaturePOPCNT | FeaturePRFCHW | FeatureSAHF | FeatureSSE | FeatureSSE2 | + FeaturePOPCNT | FeaturePRFCHW | FeatureLAHF_LM | FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 | FeatureSSE4_2 | FeatureSSE4_A | FeatureXOP | FeatureXSAVE; constexpr FeatureBitset FeaturesBDVER2 = @@ -221,7 +221,7 @@ constexpr FeatureBitset FeaturesZNVER1 = FeatureCMPXCHG8B | FeatureCMPXCHG16B | FeatureCRC32 | Feature64BIT | FeatureF16C | FeatureFMA | FeatureFSGSBASE | FeatureFXSR | FeatureLZCNT | FeatureMMX | FeatureMOVBE | FeatureMWAITX | FeaturePCLMUL | FeaturePOPCNT | - FeaturePRFCHW | FeatureRDRND | FeatureRDSEED | FeatureSAHF | FeatureSHA | + FeaturePRFCHW | FeatureRDRND | FeatureRDSEED | FeatureLAHF_LM | FeatureSHA | FeatureSSE | FeatureSSE2 | FeatureSSE3 | FeatureSSSE3 | FeatureSSE4_1 | FeatureSSE4_2 | FeatureSSE4_A | FeatureXSAVE | FeatureXSAVEC | FeatureXSAVEOPT | FeatureXSAVES; @@ -507,7 +507,8 @@ constexpr FeatureBitset ImpliedFeaturesRDPRU = {}; constexpr FeatureBitset ImpliedFeaturesRDRND = {}; constexpr FeatureBitset ImpliedFeaturesRDSEED = {}; constexpr FeatureBitset ImpliedFeaturesRTM = {}; -constexpr FeatureBitset ImpliedFeaturesSAHF = {}; +constexpr FeatureBitset ImpliedFeaturesLAHF_LM = {}; +constexpr FeatureBitset ImpliedFeaturesLM = {}; constexpr FeatureBitset ImpliedFeaturesSERIALIZE = {}; constexpr FeatureBitset ImpliedFeaturesSGX = {}; constexpr FeatureBitset ImpliedFeaturesSHSTK = {}; @@ -517,7 +518,6 @@ constexpr FeatureBitset ImpliedFeaturesUINTR = {}; constexpr FeatureBitset ImpliedFeaturesUSERMSR = {}; constexpr FeatureBitset ImpliedFeaturesWAITPKG = {}; constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {}; -constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {}; constexpr FeatureBitset ImpliedFeaturesX87 = {}; constexpr FeatureBitset ImpliedFeaturesXSAVE = {}; @@ -615,13 +615,13 @@ constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL; constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2; // AVX10 Features -constexpr FeatureBitset ImpliedFeaturesAVX10_1 = +constexpr FeatureBitset ImpliedFeaturesAVX10_1_256 = FeatureAVX512CD | FeatureAVX512VBMI | FeatureAVX512IFMA | FeatureAVX512VNNI | FeatureAVX512BF16 | FeatureAVX512VPOPCNTDQ | FeatureAVX512VBMI2 | FeatureAVX512BITALG | FeatureVAES | FeatureVPCLMULQDQ | FeatureAVX512FP16; constexpr FeatureBitset ImpliedFeaturesAVX10_1_512 = - FeatureAVX10_1 | FeatureEVEX512; + FeatureAVX10_1_256 | FeatureEVEX512; // APX Features constexpr FeatureBitset ImpliedFeaturesEGPR = {};