diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp | 400 |
1 files changed, 319 insertions, 81 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp index 5c4bd364b06a..a68b662d9401 100644 --- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp +++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp @@ -17,26 +17,27 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/X86TargetParser.h" +#include "llvm/TargetParser/X86TargetParser.h" +#include <optional> namespace clang { namespace targets { -const Builtin::Info BuiltinInfoX86[] = { +static constexpr Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/BuiltinsX86.def" #define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, + {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, #include "clang/Basic/BuiltinsX86_64.def" }; @@ -118,6 +119,14 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabled(Features, F, true); std::vector<std::string> UpdatedFeaturesVec; + std::vector<std::string> UpdatedAVX10FeaturesVec; + enum { FE_NOSET = -1, FE_FALSE, FE_TRUE }; + int HasEVEX512 = FE_NOSET; + bool HasAVX512F = Features.lookup("avx512f"); + bool HasAVX10 = Features.lookup("avx10.1-256"); + bool HasAVX10_512 = Features.lookup("avx10.1-512"); + std::string LastAVX10; + std::string LastAVX512; for (const auto &Feature : FeaturesVec) { // Expand general-regs-only to -x86, -mmx and -sse if (Feature == "+general-regs-only") { @@ -127,8 +136,51 @@ bool X86TargetInfo::initFeatureMap( continue; } + if (Feature.substr(1, 6) == "avx10.") { + if (Feature[0] == '+') { + HasAVX10 = true; + if (Feature.substr(Feature.size() - 3, 3) == "512") + HasAVX10_512 = true; + LastAVX10 = Feature; + } else if (HasAVX10 && Feature == "-avx10.1-256") { + HasAVX10 = false; + HasAVX10_512 = false; + } else if (HasAVX10_512 && Feature == "-avx10.1-512") { + HasAVX10_512 = false; + } + // Postpone AVX10 features handling after AVX512 settled. + UpdatedAVX10FeaturesVec.push_back(Feature); + continue; + } else if (!HasAVX512F && Feature.substr(0, 7) == "+avx512") { + HasAVX512F = true; + LastAVX512 = Feature; + } else if (HasAVX512F && Feature == "-avx512f") { + HasAVX512F = false; + } else if (HasEVEX512 != FE_TRUE && Feature == "+evex512") { + HasEVEX512 = FE_TRUE; + continue; + } else if (HasEVEX512 != FE_FALSE && Feature == "-evex512") { + HasEVEX512 = FE_FALSE; + continue; + } + UpdatedFeaturesVec.push_back(Feature); } + llvm::append_range(UpdatedFeaturesVec, UpdatedAVX10FeaturesVec); + // HasEVEX512 is a three-states flag. We need to turn it into [+-]evex512 + // according to other features. + if (HasAVX512F) { + UpdatedFeaturesVec.push_back(HasEVEX512 == FE_FALSE ? "-evex512" + : "+evex512"); + if (HasAVX10 && !HasAVX10_512 && HasEVEX512 != FE_FALSE) + Diags.Report(diag::warn_invalid_feature_combination) + << LastAVX512 + " " + LastAVX10 + "; will be promoted to avx10.1-512"; + } else if (HasAVX10) { + if (HasEVEX512 != FE_NOSET) + Diags.Report(diag::warn_invalid_feature_combination) + << LastAVX10 + (HasEVEX512 == FE_TRUE ? " +evex512" : " -evex512"); + UpdatedFeaturesVec.push_back(HasAVX10_512 ? "+evex512" : "-evex512"); + } if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec)) return false; @@ -227,6 +279,12 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasF16C = true; } else if (Feature == "+gfni") { HasGFNI = true; + } else if (Feature == "+evex512") { + HasEVEX512 = true; + } else if (Feature == "+avx10.1-256") { + HasAVX10_1 = true; + } else if (Feature == "+avx10.1-512") { + HasAVX10_1_512 = true; } else if (Feature == "+avx512cd") { HasAVX512CD = true; } else if (Feature == "+avx512vpopcntdq") { @@ -237,11 +295,13 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasAVX512BF16 = true; } else if (Feature == "+avx512er") { HasAVX512ER = true; + Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+avx512fp16") { HasAVX512FP16 = true; - HasFloat16 = true; + HasLegalHalfType = true; } else if (Feature == "+avx512pf") { HasAVX512PF = true; + Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+avx512dq") { HasAVX512DQ = true; } else if (Feature == "+avx512bitalg") { @@ -260,8 +320,14 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasAVX512VP2INTERSECT = true; } else if (Feature == "+sha") { HasSHA = true; + } else if (Feature == "+sha512") { + HasSHA512 = true; } else if (Feature == "+shstk") { HasSHSTK = true; + } else if (Feature == "+sm3") { + HasSM3 = true; + } else if (Feature == "+sm4") { + HasSM4 = true; } else if (Feature == "+movbe") { HasMOVBE = true; } else if (Feature == "+sgx") { @@ -290,14 +356,19 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasCLWB = true; } else if (Feature == "+wbnoinvd") { HasWBNOINVD = true; + } else if (Feature == "+prefetchi") { + HasPREFETCHI = true; } else if (Feature == "+prefetchwt1") { HasPREFETCHWT1 = true; + Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+clzero") { HasCLZERO = true; } else if (Feature == "+cldemote") { HasCLDEMOTE = true; } else if (Feature == "+rdpid") { HasRDPID = true; + } else if (Feature == "+rdpru") { + HasRDPRU = true; } else if (Feature == "+kl") { HasKL = true; } else if (Feature == "+widekl") { @@ -324,22 +395,54 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasHRESET = true; } else if (Feature == "+amx-bf16") { HasAMXBF16 = true; + } else if (Feature == "+amx-fp16") { + HasAMXFP16 = true; } else if (Feature == "+amx-int8") { HasAMXINT8 = true; } else if (Feature == "+amx-tile") { HasAMXTILE = true; + } else if (Feature == "+amx-complex") { + HasAMXCOMPLEX = true; + } else if (Feature == "+cmpccxadd") { + HasCMPCCXADD = true; + } else if (Feature == "+raoint") { + HasRAOINT = true; + } else if (Feature == "+avxifma") { + HasAVXIFMA = true; + } else if (Feature == "+avxneconvert") { + HasAVXNECONVERT= true; } else if (Feature == "+avxvnni") { HasAVXVNNI = true; + } else if (Feature == "+avxvnniint16") { + HasAVXVNNIINT16 = true; + } else if (Feature == "+avxvnniint8") { + HasAVXVNNIINT8 = true; } else if (Feature == "+serialize") { HasSERIALIZE = true; } else if (Feature == "+tsxldtrk") { HasTSXLDTRK = true; } else if (Feature == "+uintr") { HasUINTR = true; + } else if (Feature == "+usermsr") { + HasUSERMSR = true; } else if (Feature == "+crc32") { HasCRC32 = true; } else if (Feature == "+x87") { HasX87 = true; + } else if (Feature == "+fullbf16") { + HasFullBFloat16 = true; + } else if (Feature == "+egpr") { + HasEGPR = true; + } else if (Feature == "+push2pop2") { + HasPush2Pop2 = true; + } else if (Feature == "+ppx") { + HasPPX = true; + } else if (Feature == "+ndd") { + HasNDD = true; + } else if (Feature == "+ccmp") { + HasCCMP = true; + } else if (Feature == "+cf") { + HasCF = true; } X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -355,6 +458,19 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, .Default(NoSSE); SSELevel = std::max(SSELevel, Level); + HasFloat16 = SSELevel >= SSE2; + + // X86 target has bfloat16 emulation support in the backend, where + // bfloat16 is treated as a 32-bit float, arithmetic operations are + // performed in 32-bit, and the result is converted back to bfloat16. + // Truncation and extension between bfloat16 and 32-bit float are supported + // by the compiler-rt library. However, native bfloat16 support is currently + // not available in the X86 target. Hence, HasFullBFloat16 will be false + // until native bfloat16 support is available. HasFullBFloat16 is used to + // determine whether to automatically use excess floating point precision + // for bfloat16 arithmetic operations in the front-end. + HasBFloat16 = SSELevel >= SSE2; + MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature) .Case("+3dnowa", AMD3DNowAthlon) .Case("+3dnow", AMD3DNow) @@ -379,9 +495,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, return false; } - SimdDefaultAlign = - hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; - // FIXME: We should allow long double type on 32-bits to match with GCC. // This requires backend to be able to lower f80 without x87 first. if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) @@ -441,7 +554,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_PentiumMMX: Builder.defineMacro("__pentium_mmx__"); Builder.defineMacro("__tune_pentium_mmx__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_i586: case CK_Pentium: defineCPUMacros(Builder, "i586"); @@ -450,11 +563,11 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Pentium3: case CK_PentiumM: Builder.defineMacro("__tune_pentium3__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_Pentium2: case CK_C3_2: Builder.defineMacro("__tune_pentium2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_PentiumPro: case CK_i686: defineCPUMacros(Builder, "i686"); @@ -487,6 +600,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Tremont: defineCPUMacros(Builder, "tremont"); break; + // Gracemont and later atom-cores use P-core cpu macros. + case CK_Gracemont: case CK_Nehalem: case CK_Westmere: case CK_SandyBridge: @@ -504,6 +619,18 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Tigerlake: case CK_SapphireRapids: case CK_Alderlake: + case CK_Raptorlake: + case CK_Meteorlake: + case CK_Arrowlake: + case CK_ArrowlakeS: + case CK_Lunarlake: + case CK_Pantherlake: + case CK_Sierraforest: + case CK_Grandridge: + case CK_Graniterapids: + case CK_GraniterapidsD: + case CK_Emeraldrapids: + case CK_Clearwaterforest: // FIXME: Historically, we defined this legacy name, it would be nice to // remove it at some point. We've never exposed fine-grained names for // recent primary x86 CPUs, and we should keep it that way. @@ -522,7 +649,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_K6_2: Builder.defineMacro("__k6_2__"); Builder.defineMacro("__tune_k6_2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_K6_3: if (CPU != CK_K6_2) { // In case of fallthrough // FIXME: GCC may be enabling these in cases where some other k6 @@ -531,7 +658,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__k6_3__"); Builder.defineMacro("__tune_k6_3__"); } - LLVM_FALLTHROUGH; + [[fallthrough]]; case CK_K6: defineCPUMacros(Builder, "k6"); break; @@ -582,6 +709,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_ZNVER3: defineCPUMacros(Builder, "znver3"); break; + case CK_ZNVER4: + defineCPUMacros(Builder, "znver4"); + break; case CK_Geode: defineCPUMacros(Builder, "geode"); break; @@ -657,13 +787,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, switch (XOPLevel) { case XOP: Builder.defineMacro("__XOP__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case FMA4: Builder.defineMacro("__FMA4__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE4A: Builder.defineMacro("__SSE4A__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoXOP: break; } @@ -677,6 +807,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasGFNI) Builder.defineMacro("__GFNI__"); + if (HasEVEX512) + Builder.defineMacro("__EVEX512__"); + if (HasAVX10_1) + Builder.defineMacro("__AVX10_1__"); + if (HasAVX10_1_512) + Builder.defineMacro("__AVX10_1_512__"); if (HasAVX512CD) Builder.defineMacro("__AVX512CD__"); if (HasAVX512VPOPCNTDQ) @@ -697,8 +833,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512BITALG__"); if (HasAVX512BW) Builder.defineMacro("__AVX512BW__"); - if (HasAVX512VL) + if (HasAVX512VL) { Builder.defineMacro("__AVX512VL__"); + Builder.defineMacro("__EVEX256__"); + } if (HasAVX512VBMI) Builder.defineMacro("__AVX512VBMI__"); if (HasAVX512VBMI2) @@ -709,6 +847,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512VP2INTERSECT__"); if (HasSHA) Builder.defineMacro("__SHA__"); + if (HasSHA512) + Builder.defineMacro("__SHA512__"); if (HasFXSR) Builder.defineMacro("__FXSR__"); @@ -732,6 +872,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__SHSTK__"); if (HasSGX) Builder.defineMacro("__SGX__"); + if (HasSM3) + Builder.defineMacro("__SM3__"); + if (HasSM4) + Builder.defineMacro("__SM4__"); + if (HasPREFETCHI) + Builder.defineMacro("__PREFETCHI__"); if (HasPREFETCHWT1) Builder.defineMacro("__PREFETCHWT1__"); if (HasCLZERO) @@ -742,6 +888,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__WIDEKL__"); if (HasRDPID) Builder.defineMacro("__RDPID__"); + if (HasRDPRU) + Builder.defineMacro("__RDPRU__"); if (HasCLDEMOTE) Builder.defineMacro("__CLDEMOTE__"); if (HasWAITPKG) @@ -761,53 +909,83 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasHRESET) Builder.defineMacro("__HRESET__"); if (HasAMXTILE) - Builder.defineMacro("__AMXTILE__"); + Builder.defineMacro("__AMX_TILE__"); if (HasAMXINT8) - Builder.defineMacro("__AMXINT8__"); + Builder.defineMacro("__AMX_INT8__"); if (HasAMXBF16) - Builder.defineMacro("__AMXBF16__"); + Builder.defineMacro("__AMX_BF16__"); + if (HasAMXFP16) + Builder.defineMacro("__AMX_FP16__"); + if (HasAMXCOMPLEX) + Builder.defineMacro("__AMX_COMPLEX__"); + if (HasCMPCCXADD) + Builder.defineMacro("__CMPCCXADD__"); + if (HasRAOINT) + Builder.defineMacro("__RAOINT__"); + if (HasAVXIFMA) + Builder.defineMacro("__AVXIFMA__"); + if (HasAVXNECONVERT) + Builder.defineMacro("__AVXNECONVERT__"); if (HasAVXVNNI) Builder.defineMacro("__AVXVNNI__"); + if (HasAVXVNNIINT16) + Builder.defineMacro("__AVXVNNIINT16__"); + if (HasAVXVNNIINT8) + Builder.defineMacro("__AVXVNNIINT8__"); if (HasSERIALIZE) Builder.defineMacro("__SERIALIZE__"); if (HasTSXLDTRK) Builder.defineMacro("__TSXLDTRK__"); if (HasUINTR) Builder.defineMacro("__UINTR__"); + if (HasUSERMSR) + Builder.defineMacro("__USERMSR__"); if (HasCRC32) Builder.defineMacro("__CRC32__"); + if (HasEGPR) + Builder.defineMacro("__EGPR__"); + if (HasPush2Pop2) + Builder.defineMacro("__PUSH2POP2__"); + if (HasPPX) + Builder.defineMacro("__PPX__"); + if (HasNDD) + Builder.defineMacro("__NDD__"); + if (HasCCMP) + Builder.defineMacro("__CCMP__"); + if (HasCF) + Builder.defineMacro("__CF__"); // Each case falls through to the previous one here. switch (SSELevel) { case AVX512F: Builder.defineMacro("__AVX512F__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case AVX2: Builder.defineMacro("__AVX2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case AVX: Builder.defineMacro("__AVX__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE42: Builder.defineMacro("__SSE4_2__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE41: Builder.defineMacro("__SSE4_1__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSSE3: Builder.defineMacro("__SSSE3__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE3: Builder.defineMacro("__SSE3__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE2: Builder.defineMacro("__SSE2__"); Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. - LLVM_FALLTHROUGH; + [[fallthrough]]; case SSE1: Builder.defineMacro("__SSE__"); Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoSSE: break; } @@ -837,13 +1015,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, switch (MMX3DNowLevel) { case AMD3DNowAthlon: Builder.defineMacro("__3dNOW_A__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case AMD3DNow: Builder.defineMacro("__3dNOW__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case MMX: Builder.defineMacro("__MMX__"); - LLVM_FALLTHROUGH; + [[fallthrough]]; case NoMMX3DNow: break; } @@ -869,9 +1047,13 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("adx", true) .Case("aes", true) .Case("amx-bf16", true) + .Case("amx-complex", true) + .Case("amx-fp16", true) .Case("amx-int8", true) .Case("amx-tile", true) .Case("avx", true) + .Case("avx10.1-256", true) + .Case("avx10.1-512", true) .Case("avx2", true) .Case("avx512f", true) .Case("avx512cd", true) @@ -889,16 +1071,22 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("avx512vbmi2", true) .Case("avx512ifma", true) .Case("avx512vp2intersect", true) + .Case("avxifma", true) + .Case("avxneconvert", true) .Case("avxvnni", true) + .Case("avxvnniint16", true) + .Case("avxvnniint8", true) .Case("bmi", true) .Case("bmi2", true) .Case("cldemote", true) .Case("clflushopt", true) .Case("clwb", true) .Case("clzero", true) + .Case("cmpccxadd", true) .Case("crc32", true) .Case("cx16", true) .Case("enqcmd", true) + .Case("evex512", true) .Case("f16c", true) .Case("fma", true) .Case("fma4", true) @@ -921,10 +1109,13 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("pconfig", true) .Case("pku", true) .Case("popcnt", true) + .Case("prefetchi", true) .Case("prefetchwt1", true) .Case("prfchw", true) .Case("ptwrite", true) + .Case("raoint", true) .Case("rdpid", true) + .Case("rdpru", true) .Case("rdrnd", true) .Case("rdseed", true) .Case("rtm", true) @@ -932,7 +1123,10 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("serialize", true) .Case("sgx", true) .Case("sha", true) + .Case("sha512", true) .Case("shstk", true) + .Case("sm3", true) + .Case("sm4", true) .Case("sse", true) .Case("sse2", true) .Case("sse3", true) @@ -944,6 +1138,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("tbm", true) .Case("tsxldtrk", true) .Case("uintr", true) + .Case("usermsr", true) .Case("vaes", true) .Case("vpclmulqdq", true) .Case("wbnoinvd", true) @@ -954,6 +1149,12 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("xsavec", true) .Case("xsaves", true) .Case("xsaveopt", true) + .Case("egpr", true) + .Case("push2pop2", true) + .Case("ppx", true) + .Case("ndd", true) + .Case("ccmp", true) + .Case("cf", true) .Default(false); } @@ -962,10 +1163,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("adx", HasADX) .Case("aes", HasAES) .Case("amx-bf16", HasAMXBF16) + .Case("amx-complex", HasAMXCOMPLEX) + .Case("amx-fp16", HasAMXFP16) .Case("amx-int8", HasAMXINT8) .Case("amx-tile", HasAMXTILE) - .Case("avxvnni", HasAVXVNNI) .Case("avx", SSELevel >= AVX) + .Case("avx10.1-256", HasAVX10_1) + .Case("avx10.1-512", HasAVX10_1_512) .Case("avx2", SSELevel >= AVX2) .Case("avx512f", SSELevel >= AVX512F) .Case("avx512cd", HasAVX512CD) @@ -983,16 +1187,23 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx512vbmi2", HasAVX512VBMI2) .Case("avx512ifma", HasAVX512IFMA) .Case("avx512vp2intersect", HasAVX512VP2INTERSECT) + .Case("avxifma", HasAVXIFMA) + .Case("avxneconvert", HasAVXNECONVERT) + .Case("avxvnni", HasAVXVNNI) + .Case("avxvnniint16", HasAVXVNNIINT16) + .Case("avxvnniint8", HasAVXVNNIINT8) .Case("bmi", HasBMI) .Case("bmi2", HasBMI2) .Case("cldemote", HasCLDEMOTE) .Case("clflushopt", HasCLFLUSHOPT) .Case("clwb", HasCLWB) .Case("clzero", HasCLZERO) + .Case("cmpccxadd", HasCMPCCXADD) .Case("crc32", HasCRC32) .Case("cx8", HasCX8) .Case("cx16", HasCX16) .Case("enqcmd", HasENQCMD) + .Case("evex512", HasEVEX512) .Case("f16c", HasF16C) .Case("fma", HasFMA) .Case("fma4", XOPLevel >= FMA4) @@ -1016,10 +1227,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("pconfig", HasPCONFIG) .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) + .Case("prefetchi", HasPREFETCHI) .Case("prefetchwt1", HasPREFETCHWT1) .Case("prfchw", HasPRFCHW) .Case("ptwrite", HasPTWRITE) + .Case("raoint", HasRAOINT) .Case("rdpid", HasRDPID) + .Case("rdpru", HasRDPRU) .Case("rdrnd", HasRDRND) .Case("rdseed", HasRDSEED) .Case("retpoline-external-thunk", HasRetpolineExternalThunk) @@ -1028,7 +1242,10 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("serialize", HasSERIALIZE) .Case("sgx", HasSGX) .Case("sha", HasSHA) + .Case("sha512", HasSHA512) .Case("shstk", HasSHSTK) + .Case("sm3", HasSM3) + .Case("sm4", HasSM4) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) .Case("sse3", SSELevel >= SSE3) @@ -1039,6 +1256,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("tbm", HasTBM) .Case("tsxldtrk", HasTSXLDTRK) .Case("uintr", HasUINTR) + .Case("usermsr", HasUSERMSR) .Case("vaes", HasVAES) .Case("vpclmulqdq", HasVPCLMULQDQ) .Case("wbnoinvd", HasWBNOINVD) @@ -1052,6 +1270,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("xsavec", HasXSAVEC) .Case("xsaves", HasXSAVES) .Case("xsaveopt", HasXSAVEOPT) + .Case("fullbf16", HasFullBFloat16) + .Case("egpr", HasEGPR) + .Case("push2pop2", HasPush2Pop2) + .Case("ppx", HasPPX) + .Case("ndd", HasNDD) + .Case("ccmp", HasCCMP) + .Case("cf", HasCF) .Default(false); } @@ -1063,7 +1288,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { return llvm::StringSwitch<bool>(FeatureStr) #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true) -#include "llvm/Support/X86TargetParser.def" +#define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY) .Case(STR, true) +#include "llvm/TargetParser/X86TargetParser.def" .Default(false); } @@ -1072,7 +1298,7 @@ static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { #define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ .Case(STR, llvm::X86::FEATURE_##ENUM) -#include "llvm/Support/X86TargetParser.def" +#include "llvm/TargetParser/X86TargetParser.def" ; // Note, this function should only be used after ensuring the value is // correct, so it asserts if the value is out of range. @@ -1094,35 +1320,19 @@ unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { } bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) -#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true) -#include "llvm/Support/X86TargetParser.def" - .Default(false); -} - -static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { - return llvm::StringSwitch<StringRef>(Name) -#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME) -#include "llvm/Support/X86TargetParser.def" - .Default(Name); + return llvm::X86::validateCPUSpecificCPUDispatch(Name); } char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { - return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name)) -#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) -#include "llvm/Support/X86TargetParser.def" - .Default(0); + return llvm::X86::getCPUDispatchMangling(Name); } void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { - StringRef WholeList = - llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name)) -#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) -#include "llvm/Support/X86TargetParser.def" - .Default(""); - WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); + SmallVector<StringRef, 32> TargetCPUFeatures; + llvm::X86::getFeaturesForCPU(Name, TargetCPUFeatures, true); + for (auto &F : TargetCPUFeatures) + Features.push_back(F); } // We can't use a generic validation scheme for the cpus accepted here @@ -1134,12 +1344,13 @@ bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const { #define X86_VENDOR(ENUM, STRING) .Case(STRING, true) #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true) +#define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true) -#include "llvm/Support/X86TargetParser.def" +#include "llvm/TargetParser/X86TargetParser.def" .Default(false); } -static unsigned matchAsmCCConstraint(const char *&Name) { +static unsigned matchAsmCCConstraint(const char *Name) { auto RV = llvm::StringSwitch<unsigned>(Name) .Case("@cca", 4) .Case("@ccae", 5) @@ -1207,6 +1418,14 @@ bool X86TargetInfo::validateAsmConstraint( case 'O': Info.setRequiresImmediate(0, 127); return true; + case 'W': + switch (*++Name) { + default: + return false; + case 's': + Info.setAllowsRegister(); + return true; + } // Register constraints. case 'Y': // 'Y' is the first character for several 2-character constraints. // Shift the pointer to the second character of the constraint. @@ -1279,7 +1498,7 @@ bool X86TargetInfo::validateAsmConstraint( // | Sandy Bridge | 64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html | // | Ivy Bridge | 64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html | // | Haswell | 64 | https://www.7-cpu.com/cpu/Haswell.html | -// | Boadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html | +// | Broadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html | // | Skylake (including skylake-avx512) | 64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy" | // | Cascade Lake | 64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy" | // | Skylake | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy" | @@ -1287,7 +1506,7 @@ bool X86TargetInfo::validateAsmConstraint( // | Knights Landing | 64 | https://software.intel.com/en-us/articles/intel-xeon-phi-processor-7200-family-memory-management-optimizations "The Intel® Xeon Phi™ Processor Architecture" | // | Knights Mill | 64 | https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf?countrylabel=Colombia "2.5.5.2 L1 DCache " | // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { +std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { using namespace llvm::X86; switch (CPU) { // i386 @@ -1330,6 +1549,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_Goldmont: case CK_GoldmontPlus: case CK_Tremont: + case CK_Gracemont: case CK_Westmere: case CK_SandyBridge: @@ -1348,6 +1568,18 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_Rocketlake: case CK_IcelakeServer: case CK_Alderlake: + case CK_Raptorlake: + case CK_Meteorlake: + case CK_Arrowlake: + case CK_ArrowlakeS: + case CK_Lunarlake: + case CK_Pantherlake: + case CK_Sierraforest: + case CK_Grandridge: + case CK_Graniterapids: + case CK_GraniterapidsD: + case CK_Emeraldrapids: + case CK_Clearwaterforest: case CK_KNL: case CK_KNM: // K7 @@ -1369,6 +1601,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_ZNVER1: case CK_ZNVER2: case CK_ZNVER3: + case CK_ZNVER4: // Deprecated case CK_x86_64: case CK_x86_64_v2: @@ -1382,7 +1615,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { // The following currently have unknown cache line sizes (but they are probably all 64): // Core case CK_None: - return None; + return std::nullopt; } llvm_unreachable("Unknown CPU kind"); } @@ -1391,8 +1624,7 @@ bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap, StringRef Constraint, unsigned Size) const { // Strip off constraint modifiers. - while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') - Constraint = Constraint.substr(1); + Constraint = Constraint.ltrim("=+&"); return validateOperandSize(FeatureMap, Constraint, Size); } @@ -1428,8 +1660,9 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, return Size <= 64; case 'z': // XMM0/YMM/ZMM0 - if (hasFeatureEnabled(FeatureMap, "avx512f")) - // ZMM0 can be used if target supports AVX512F. + if (hasFeatureEnabled(FeatureMap, "avx512f") && + hasFeatureEnabled(FeatureMap, "evex512")) + // ZMM0 can be used if target supports AVX512F and EVEX512 is set. return Size <= 512U; else if (hasFeatureEnabled(FeatureMap, "avx")) // YMM0 can be used if target supports AVX. @@ -1448,8 +1681,10 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, break; case 'v': case 'x': - if (hasFeatureEnabled(FeatureMap, "avx512f")) - // 512-bit zmm registers can be used if target supports AVX512F. + if (hasFeatureEnabled(FeatureMap, "avx512f") && + hasFeatureEnabled(FeatureMap, "evex512")) + // 512-bit zmm registers can be used if target supports AVX512F and + // EVEX512 is set. return Size <= 512U; else if (hasFeatureEnabled(FeatureMap, "avx")) // 256-bit ymm registers can be used if target supports AVX. @@ -1482,12 +1717,15 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("{si}"); case 'D': return std::string("{di}"); - case 'p': // address - return std::string("im"); + case 'p': // Keep 'p' constraint (address). + return std::string("p"); case 't': // top of floating point stack. return std::string("{st}"); case 'u': // second from top of floating point stack. return std::string("{st(1)}"); // second from top of floating point stack. + case 'W': + assert(Constraint[1] == 's'); + return '^' + std::string(Constraint++, 2); case 'Y': switch (Constraint[1]) { default: @@ -1506,7 +1744,7 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { // to the next constraint. return std::string("^") + std::string(Constraint++, 2); } - LLVM_FALLTHROUGH; + [[fallthrough]]; default: return std::string(1, *Constraint); } @@ -1522,19 +1760,19 @@ void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) con } ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const { - return llvm::makeArrayRef(GCCRegNames); + return llvm::ArrayRef(GCCRegNames); } ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const { - return llvm::makeArrayRef(AddlRegNames); + return llvm::ArrayRef(AddlRegNames); } ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - - Builtin::FirstTSBuiltin + 1); + return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - + Builtin::FirstTSBuiltin + 1); } ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const { - return llvm::makeArrayRef(BuiltinInfoX86, - X86::LastTSBuiltin - Builtin::FirstTSBuiltin); + return llvm::ArrayRef(BuiltinInfoX86, + X86::LastTSBuiltin - Builtin::FirstTSBuiltin); } |