Make llc use getHostCPUFeatures when 'native' is specified for cpu.
authorCraig Topper <craig.topper@gmail.com>
Tue, 31 Mar 2015 05:52:57 +0000 (05:52 +0000)
committerCraig Topper <craig.topper@gmail.com>
Tue, 31 Mar 2015 05:52:57 +0000 (05:52 +0000)
This is necessary for x86 where not all Sandybridge, Ivybrige, Haswell, and Broadwell CPUs support AVX. Currently we modify the CPU name back to Nehalem for this case, but that turns off additional features for these CPUs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233673 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/SubtargetFeature.h
lib/MC/SubtargetFeature.cpp
tools/llc/llc.cpp

index bfecb8ba6ab0a22dba299302c1faa480c4295ff9..6f195d7be99cffc8ecccefd0ae08ce7a1fedbc5d 100644 (file)
@@ -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.
index fcb43d63cb9bc375039953c52dcd6c09abfb2af4..3880d883389dee680ecfe05b3ceb2fb58d71bd98 100644 (file)
@@ -81,11 +81,12 @@ static std::string Join(const std::vector<std::string> &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.
index 000948c10a0c7db9c0fac432d6f53fff7d5f8a00..d46cbb3181b6898576f533f9b2414cbbd49bef1c 100644 (file)
@@ -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<bool> 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: