diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index bfecb8ba6ab..6f195d7be99 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -78,7 +78,7 @@ public: std::string getString() const; /// Adding Features. - void AddFeature(StringRef String); + void AddFeature(StringRef String, bool Enable = true); /// ToggleFeature - Toggle a feature and returns the newly updated feature /// bits. diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp index fcb43d63cb9..3880d883389 100644 --- a/lib/MC/SubtargetFeature.cpp +++ b/lib/MC/SubtargetFeature.cpp @@ -81,11 +81,12 @@ static std::string Join(const std::vector &V) { } /// Adding features. -void SubtargetFeatures::AddFeature(StringRef String) { +void SubtargetFeatures::AddFeature(StringRef String, bool Enable) { // Don't add empty features. if (!String.empty()) // Convert to lowercase, prepend flag if we don't already have a flag. - Features.push_back(hasFlag(String) ? String.lower() : "+" + String.lower()); + Features.push_back(hasFlag(String) ? String.lower() + : (Enable ? "+" : "-") + String.lower()); } /// Find KV in array using binary search. diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 000948c10a0..d46cbb3181b 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -212,12 +212,6 @@ static int compileModule(char **argv, LLVMContext &Context) { bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); - // If user asked for the 'native' CPU, autodetect here. If autodection fails, - // this will set the CPU to an empty string which tells the target to - // pick a basic default. - if (MCPU == "native") - MCPU = sys::getHostCPUName(); - // If user just wants to list available options, skip module loading if (!SkipModule) { M = parseIRFile(InputFilename, Err, Context); @@ -256,13 +250,31 @@ static int compileModule(char **argv, LLVMContext &Context) { // Package up features to be passed to target/subtarget std::string FeaturesStr; - if (MAttrs.size()) { + if (!MAttrs.empty() || MCPU == "native") { SubtargetFeatures Features; + + // If user asked for the 'native' CPU, we need to autodetect features. + // This is necessary for x86 where the CPU might not support all the + // features the autodetected CPU name lists in the target. For example, + // not all Sandybridge processors support AVX. + if (MCPU == "native") { + StringMap HostFeatures; + if (sys::getHostCPUFeatures(HostFeatures)) + for (auto &F : HostFeatures) + Features.AddFeature(F.first(), F.second); + } + for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } + // If user asked for the 'native' CPU, autodetect here. If autodection fails, + // this will set the CPU to an empty string which tells the target to + // pick a basic default. + if (MCPU == "native") + MCPU = sys::getHostCPUName(); + CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: