Wire up -mrdrnd for X86.

For some reason GCC decided to call the feature rdrnd instead of rdrand,
which requires translating it for LLVM.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159897 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 918718a..5d33d70 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -809,6 +809,7 @@
 def mno_avx : Flag<"-mno-avx">, Group<m_x86_Features_Group>;
 def mno_avx2 : Flag<"-mno-avx2">, Group<m_x86_Features_Group>;
 def mno_lzcnt : Flag<"-mno-lzcnt">, Group<m_x86_Features_Group>;
+def mno_rdrnd : Flag<"-mno-rdrnd">, Group<m_x86_Features_Group>;
 def mno_bmi : Flag<"-mno-bmi">, Group<m_x86_Features_Group>;
 def mno_bmi2 : Flag<"-mno-bmi2">, Group<m_x86_Features_Group>;
 def mno_popcnt : Flag<"-mno-popcnt">, Group<m_x86_Features_Group>;
@@ -845,6 +846,7 @@
 def mavx : Flag<"-mavx">, Group<m_x86_Features_Group>;
 def mavx2 : Flag<"-mavx2">, Group<m_x86_Features_Group>;
 def mlzcnt : Flag<"-mlzcnt">, Group<m_x86_Features_Group>;
+def mrdrnd : Flag<"-mrdrnd">, Group<m_x86_Features_Group>;
 def mbmi : Flag<"-mbmi">, Group<m_x86_Features_Group>;
 def mbmi2 : Flag<"-mbmi2">, Group<m_x86_Features_Group>;
 def mpopcnt : Flag<"-mpopcnt">, Group<m_x86_Features_Group>;
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index bc3cbf2..5165193 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1323,6 +1323,7 @@
   bool HasAES;
   bool HasPCLMUL;
   bool HasLZCNT;
+  bool HasRDRND;
   bool HasBMI;
   bool HasBMI2;
   bool HasPOPCNT;
@@ -1474,9 +1475,9 @@
 public:
   X86TargetInfo(const std::string& triple)
     : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
-      HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasBMI(false),
-      HasBMI2(false), HasPOPCNT(false), HasSSE4a(false), HasFMA4(false),
-      HasFMA(false), HasXOP(false), CPU(CK_Generic) {
+      HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false),
+      HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasSSE4a(false),
+      HasFMA4(false), HasFMA(false), HasXOP(false), CPU(CK_Generic) {
     BigEndian = false;
     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
   }
@@ -1662,6 +1663,7 @@
   Features["avx"] = false;
   Features["avx2"] = false;
   Features["lzcnt"] = false;
+  Features["rdrand"] = false;
   Features["bmi"] = false;
   Features["bmi2"] = false;
   Features["popcnt"] = false;
@@ -1723,11 +1725,17 @@
     setFeatureEnabled(Features, "sse4", true);
     break;
   case CK_Corei7AVX:
+    setFeatureEnabled(Features, "mmx", true);
+    setFeatureEnabled(Features, "avx", true);
+    setFeatureEnabled(Features, "aes", true);
+    setFeatureEnabled(Features, "pclmul", true);
+    break;
   case CK_CoreAVXi:
     setFeatureEnabled(Features, "mmx", true);
     setFeatureEnabled(Features, "avx", true);
     setFeatureEnabled(Features, "aes", true);
     setFeatureEnabled(Features, "pclmul", true);
+    setFeatureEnabled(Features, "rdrnd", true);
     break;
   case CK_CoreAVX2:
     setFeatureEnabled(Features, "mmx", true);
@@ -1735,6 +1743,7 @@
     setFeatureEnabled(Features, "aes", true);
     setFeatureEnabled(Features, "pclmul", true);
     setFeatureEnabled(Features, "lzcnt", true);
+    setFeatureEnabled(Features, "rdrnd", true);
     setFeatureEnabled(Features, "bmi", true);
     setFeatureEnabled(Features, "bmi2", true);
     setFeatureEnabled(Features, "fma", true);
@@ -1802,7 +1811,8 @@
   // FIXME: This *really* should not be here.  We need some way of translating
   // options into llvm subtarget features.
   if (!Features.count(Name) &&
-      (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
+      (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" &&
+       Name != "rdrnd"))
     return false;
 
   // FIXME: this should probably use a switch with fall through.
@@ -1862,6 +1872,8 @@
         Features["sse4a"] = true;
     else if (Name == "lzcnt")
       Features["lzcnt"] = true;
+    else if (Name == "rdrnd")
+      Features["rdrand"] = true;
     else if (Name == "bmi")
       Features["bmi"] = true;
     else if (Name == "bmi2")
@@ -1916,6 +1928,8 @@
       Features["sse4a"] = Features["fma4"] = Features["xop"] = false;
     else if (Name == "lzcnt")
       Features["lzcnt"] = false;
+    else if (Name == "rdrnd")
+      Features["rdrand"] = false;
     else if (Name == "bmi")
       Features["bmi"] = false;
     else if (Name == "bmi2")
@@ -1957,6 +1971,11 @@
       continue;
     }
 
+    if (Feature == "rdrand") {
+      HasRDRND = true;
+      continue;
+    }
+
     if (Feature == "bmi") {
       HasBMI = true;
       continue;
@@ -2180,6 +2199,9 @@
   if (HasLZCNT)
     Builder.defineMacro("__LZCNT__");
 
+  if (HasRDRND)
+    Builder.defineMacro("__RDRND__");
+
   if (HasBMI)
     Builder.defineMacro("__BMI__");
 
@@ -2267,6 +2289,7 @@
       .Case("fma", HasFMA)
       .Case("fma4", HasFMA4)
       .Case("lzcnt", HasLZCNT)
+      .Case("rdrnd", HasRDRND)
       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
       .Case("mmx", MMX3DNowLevel >= MMX)
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index 691173f..2361abe 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -420,6 +420,7 @@
 // CHECK_COREI7_AVX_M32: #define __AVX__ 1
 // CHECK_COREI7_AVX_M32: #define __MMX__ 1
 // CHECK_COREI7_AVX_M32: #define __PCLMUL__ 1
+// CHECK_COREI7_AVX_M32-NOT: __RDRND__
 // CHECK_COREI7_AVX_M32: #define __POPCNT__ 1
 // CHECK_COREI7_AVX_M32: #define __SSE2__ 1
 // CHECK_COREI7_AVX_M32: #define __SSE3__ 1
@@ -440,6 +441,7 @@
 // CHECK_COREI7_AVX_M64: #define __AVX__ 1
 // CHECK_COREI7_AVX_M64: #define __MMX__ 1
 // CHECK_COREI7_AVX_M64: #define __PCLMUL__ 1
+// CHECK_COREI7_AVX_M64-NOT: __RDRND__
 // CHECK_COREI7_AVX_M64: #define __POPCNT__ 1
 // CHECK_COREI7_AVX_M64: #define __SSE2_MATH__ 1
 // CHECK_COREI7_AVX_M64: #define __SSE2__ 1
@@ -464,6 +466,7 @@
 // CHECK_CORE_AVX_I_M32: #define __AVX__ 1
 // CHECK_CORE_AVX_I_M32: #define __MMX__ 1
 // CHECK_CORE_AVX_I_M32: #define __PCLMUL__ 1
+// CHECK_CORE_AVX_I_M32: #define __RDRND__ 1
 // CHECK_CORE_AVX_I_M32: #define __SSE2__ 1
 // CHECK_CORE_AVX_I_M32: #define __SSE3__ 1
 // CHECK_CORE_AVX_I_M32: #define __SSE4_1__ 1
@@ -483,6 +486,7 @@
 // CHECK_CORE_AVX_I_M64: #define __AVX__ 1
 // CHECK_CORE_AVX_I_M64: #define __MMX__ 1
 // CHECK_CORE_AVX_I_M64: #define __PCLMUL__ 1
+// CHECK_CORE_AVX_I_M64: #define __RDRND__ 1
 // CHECK_CORE_AVX_I_M64: #define __SSE2_MATH__ 1
 // CHECK_CORE_AVX_I_M64: #define __SSE2__ 1
 // CHECK_CORE_AVX_I_M64: #define __SSE3__ 1
@@ -511,6 +515,7 @@
 // CHECK_CORE_AVX2_M32: #define __MMX__ 1
 // CHECK_CORE_AVX2_M32: #define __PCLMUL__ 1
 // CHECK_CORE_AVX2_M32: #define __POPCNT__ 1
+// CHECK_CORE_AVX2_M32: #define __RDRND__ 1
 // CHECK_CORE_AVX2_M32: #define __SSE2__ 1
 // CHECK_CORE_AVX2_M32: #define __SSE3__ 1
 // CHECK_CORE_AVX2_M32: #define __SSE4_1__ 1
@@ -535,6 +540,7 @@
 // CHECK_CORE_AVX2_M64: #define __MMX__ 1
 // CHECK_CORE_AVX2_M64: #define __PCLMUL__ 1
 // CHECK_CORE_AVX2_M64: #define __POPCNT__ 1
+// CHECK_CORE_AVX2_M64: #define __RDRND__ 1
 // CHECK_CORE_AVX2_M64: #define __SSE2_MATH__ 1
 // CHECK_CORE_AVX2_M64: #define __SSE2__ 1
 // CHECK_CORE_AVX2_M64: #define __SSE3__ 1