diff --git a/clang/include/clang/Basic/X86Target.def b/clang/include/clang/Basic/X86Target.def --- a/clang/include/clang/Basic/X86Target.def +++ b/clang/include/clang/Basic/X86Target.def @@ -11,10 +11,6 @@ // //===----------------------------------------------------------------------===// -#ifndef FEATURE -#define FEATURE(ENUM) -#endif - #ifndef CPU_SPECIFIC #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) #endif @@ -23,50 +19,6 @@ #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) #endif -// List of CPU Supports features in order. These need to remain in the order -// required by attribute 'target' checking. Note that not all are supported/ -// prioritized by GCC, so synchronization with GCC's implementation may require -// changing some existing values. -FEATURE(FEATURE_CMOV) -FEATURE(FEATURE_MMX) -FEATURE(FEATURE_SSE) -FEATURE(FEATURE_SSE2) -FEATURE(FEATURE_SSE3) -FEATURE(FEATURE_SSSE3) -FEATURE(FEATURE_SSE4_A) -FEATURE(FEATURE_SSE4_1) -FEATURE(FEATURE_SSE4_2) -FEATURE(FEATURE_POPCNT) -FEATURE(FEATURE_AES) -FEATURE(FEATURE_PCLMUL) -FEATURE(FEATURE_AVX) -FEATURE(FEATURE_BMI) -FEATURE(FEATURE_FMA4) -FEATURE(FEATURE_XOP) -FEATURE(FEATURE_FMA) -FEATURE(FEATURE_BMI2) -FEATURE(FEATURE_AVX2) -FEATURE(FEATURE_AVX512F) -FEATURE(FEATURE_AVX512VL) -FEATURE(FEATURE_AVX512BW) -FEATURE(FEATURE_AVX512DQ) -FEATURE(FEATURE_AVX512CD) -FEATURE(FEATURE_AVX512ER) -FEATURE(FEATURE_AVX512PF) -FEATURE(FEATURE_AVX512VBMI) -FEATURE(FEATURE_AVX512IFMA) -FEATURE(FEATURE_AVX5124VNNIW) -FEATURE(FEATURE_AVX5124FMAPS) -FEATURE(FEATURE_AVX512VPOPCNTDQ) -FEATURE(FEATURE_AVX512VBMI2) -FEATURE(FEATURE_GFNI) -FEATURE(FEATURE_VPCLMULQDQ) -FEATURE(FEATURE_AVX512VNNI) -FEATURE(FEATURE_AVX512BITALG) -FEATURE(FEATURE_AVX512BF16) -FEATURE(FEATURE_AVX512VP2INTERSECT) - - // FIXME: When commented out features are supported in LLVM, enable them here. CPU_SPECIFIC("generic", 'A', "") CPU_SPECIFIC("pentium", 'B', "") @@ -105,6 +57,3 @@ #undef CPU_SPECIFIC_ALIAS #undef CPU_SPECIFIC -#undef PROC_64_BIT -#undef PROC_32_BIT -#undef FEATURE diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/X86TargetParser.h" +#include namespace clang { namespace targets { @@ -1041,14 +1042,16 @@ // X86TargetInfo::hasFeature for a somewhat comprehensive list). bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { return llvm::StringSwitch(FeatureStr) -#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, true) +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true) #include "llvm/Support/X86TargetParser.def" .Default(false); } static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { return llvm::StringSwitch(Name) -#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ + .Case(STR, llvm::X86::FEATURE_##ENUM) + #include "llvm/Support/X86TargetParser.def" ; // Note, this function should only be used after ensuring the value is @@ -1056,15 +1059,28 @@ } static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) { - enum class FeatPriority { -#define FEATURE(FEAT) FEAT, -#include "clang/Basic/X86Target.def" +#ifndef NDEBUG + // Check that priorities are set properly in the .def file. We expect that + // "compat" features are assigned non-duplicate consecutive priorities + // starting from zero (0, 1, ..., num_features - 1). +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) PRIORITY, + unsigned Priorities[] = { +#include "llvm/Support/X86TargetParser.def" + std::numeric_limits::max() // Need to consume last comma. }; + std::array HelperList; + std::iota(HelperList.begin(), HelperList.end(), 0); + assert(std::is_permutation(HelperList.begin(), HelperList.end(), + std::begin(Priorities), + std::prev(std::end(Priorities))) && + "Priorities don't form consecutive range!"); +#endif + switch (Feat) { -#define FEATURE(FEAT) \ - case llvm::X86::FEAT: \ - return static_cast(FeatPriority::FEAT); -#include "clang/Basic/X86Target.def" +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ + case llvm::X86::FEATURE_##ENUM: \ + return PRIORITY; +#include "llvm/Support/X86TargetParser.def" default: llvm_unreachable("No Feature Priority for non-CPUSupports Features"); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -12375,7 +12375,8 @@ for (const StringRef &FeatureStr : FeatureStrs) { unsigned Feature = StringSwitch(FeatureStr) -#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \ + .Case(STR, llvm::X86::FEATURE_##ENUM) #include "llvm/Support/X86TargetParser.def" ; FeaturesMask |= (1ULL << Feature); diff --git a/llvm/include/llvm/Support/X86TargetParser.def b/llvm/include/llvm/Support/X86TargetParser.def --- a/llvm/include/llvm/Support/X86TargetParser.def +++ b/llvm/include/llvm/Support/X86TargetParser.def @@ -91,54 +91,59 @@ X86_CPU_SUBTYPE(INTEL_COREI7_ROCKETLAKE, "rocketlake") #undef X86_CPU_SUBTYPE - -// This macro is used for cpu types present in compiler-rt/libgcc. +// This macro is used for cpu types present in compiler-rt/libgcc. The third +// parameter PRIORITY is as required by the attribute 'target' checking. Note +// that not all are supported/prioritized by GCC, so synchronization with GCC's +// implementation may require changing some existing values. +// +// We cannot just re-sort the list though because its order is dictated by the +// order of bits in CodeGenFunction::GetX86CpuSupportsMask. #ifndef X86_FEATURE_COMPAT -#define X86_FEATURE_COMPAT(ENUM, STR) X86_FEATURE(ENUM, STR) +#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) X86_FEATURE(ENUM, STR) #endif #ifndef X86_FEATURE #define X86_FEATURE(ENUM, STR) #endif -X86_FEATURE_COMPAT(CMOV, "cmov") -X86_FEATURE_COMPAT(MMX, "mmx") -X86_FEATURE_COMPAT(POPCNT, "popcnt") -X86_FEATURE_COMPAT(SSE, "sse") -X86_FEATURE_COMPAT(SSE2, "sse2") -X86_FEATURE_COMPAT(SSE3, "sse3") -X86_FEATURE_COMPAT(SSSE3, "ssse3") -X86_FEATURE_COMPAT(SSE4_1, "sse4.1") -X86_FEATURE_COMPAT(SSE4_2, "sse4.2") -X86_FEATURE_COMPAT(AVX, "avx") -X86_FEATURE_COMPAT(AVX2, "avx2") -X86_FEATURE_COMPAT(SSE4_A, "sse4a") -X86_FEATURE_COMPAT(FMA4, "fma4") -X86_FEATURE_COMPAT(XOP, "xop") -X86_FEATURE_COMPAT(FMA, "fma") -X86_FEATURE_COMPAT(AVX512F, "avx512f") -X86_FEATURE_COMPAT(BMI, "bmi") -X86_FEATURE_COMPAT(BMI2, "bmi2") -X86_FEATURE_COMPAT(AES, "aes") -X86_FEATURE_COMPAT(PCLMUL, "pclmul") -X86_FEATURE_COMPAT(AVX512VL, "avx512vl") -X86_FEATURE_COMPAT(AVX512BW, "avx512bw") -X86_FEATURE_COMPAT(AVX512DQ, "avx512dq") -X86_FEATURE_COMPAT(AVX512CD, "avx512cd") -X86_FEATURE_COMPAT(AVX512ER, "avx512er") -X86_FEATURE_COMPAT(AVX512PF, "avx512pf") -X86_FEATURE_COMPAT(AVX512VBMI, "avx512vbmi") -X86_FEATURE_COMPAT(AVX512IFMA, "avx512ifma") -X86_FEATURE_COMPAT(AVX5124VNNIW, "avx5124vnniw") -X86_FEATURE_COMPAT(AVX5124FMAPS, "avx5124fmaps") -X86_FEATURE_COMPAT(AVX512VPOPCNTDQ, "avx512vpopcntdq") -X86_FEATURE_COMPAT(AVX512VBMI2, "avx512vbmi2") -X86_FEATURE_COMPAT(GFNI, "gfni") -X86_FEATURE_COMPAT(VPCLMULQDQ, "vpclmulqdq") -X86_FEATURE_COMPAT(AVX512VNNI, "avx512vnni") -X86_FEATURE_COMPAT(AVX512BITALG, "avx512bitalg") -X86_FEATURE_COMPAT(AVX512BF16, "avx512bf16") -X86_FEATURE_COMPAT(AVX512VP2INTERSECT, "avx512vp2intersect") +X86_FEATURE_COMPAT(CMOV, "cmov", 0) +X86_FEATURE_COMPAT(MMX, "mmx", 1) +X86_FEATURE_COMPAT(POPCNT, "popcnt", 9) +X86_FEATURE_COMPAT(SSE, "sse", 2) +X86_FEATURE_COMPAT(SSE2, "sse2", 3) +X86_FEATURE_COMPAT(SSE3, "sse3", 4) +X86_FEATURE_COMPAT(SSSE3, "ssse3", 5) +X86_FEATURE_COMPAT(SSE4_1, "sse4.1", 7) +X86_FEATURE_COMPAT(SSE4_2, "sse4.2", 8) +X86_FEATURE_COMPAT(AVX, "avx", 12) +X86_FEATURE_COMPAT(AVX2, "avx2", 18) +X86_FEATURE_COMPAT(SSE4_A, "sse4a", 6) +X86_FEATURE_COMPAT(FMA4, "fma4", 14) +X86_FEATURE_COMPAT(XOP, "xop", 15) +X86_FEATURE_COMPAT(FMA, "fma", 16) +X86_FEATURE_COMPAT(AVX512F, "avx512f", 19) +X86_FEATURE_COMPAT(BMI, "bmi", 13) +X86_FEATURE_COMPAT(BMI2, "bmi2", 17) +X86_FEATURE_COMPAT(AES, "aes", 10) +X86_FEATURE_COMPAT(PCLMUL, "pclmul", 11) +X86_FEATURE_COMPAT(AVX512VL, "avx512vl", 20) +X86_FEATURE_COMPAT(AVX512BW, "avx512bw", 21) +X86_FEATURE_COMPAT(AVX512DQ, "avx512dq", 22) +X86_FEATURE_COMPAT(AVX512CD, "avx512cd", 23) +X86_FEATURE_COMPAT(AVX512ER, "avx512er", 24) +X86_FEATURE_COMPAT(AVX512PF, "avx512pf", 25) +X86_FEATURE_COMPAT(AVX512VBMI, "avx512vbmi", 26) +X86_FEATURE_COMPAT(AVX512IFMA, "avx512ifma", 27) +X86_FEATURE_COMPAT(AVX5124VNNIW, "avx5124vnniw", 28) +X86_FEATURE_COMPAT(AVX5124FMAPS, "avx5124fmaps", 29) +X86_FEATURE_COMPAT(AVX512VPOPCNTDQ, "avx512vpopcntdq", 30) +X86_FEATURE_COMPAT(AVX512VBMI2, "avx512vbmi2", 31) +X86_FEATURE_COMPAT(GFNI, "gfni", 32) +X86_FEATURE_COMPAT(VPCLMULQDQ, "vpclmulqdq", 33) +X86_FEATURE_COMPAT(AVX512VNNI, "avx512vnni", 34) +X86_FEATURE_COMPAT(AVX512BITALG, "avx512bitalg", 35) +X86_FEATURE_COMPAT(AVX512BF16, "avx512bf16", 36) +X86_FEATURE_COMPAT(AVX512VP2INTERSECT, "avx512vp2intersect", 37) // Features below here are not in libgcc/compiler-rt. X86_FEATURE (3DNOW, "3dnow") X86_FEATURE (3DNOWA, "3dnowa")