diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 66779361da1..48c7387af3d 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -80,9 +80,10 @@ def FeatureSSE4A : SubtargetFeature<"sse4a", "HasSSE4A", "true", "Support SSE 4a instructions", [FeatureSSE3]>; -def FeatureAVX : SubtargetFeature<"avx", "HasAVX", "true", - "Enable AVX instructions">; -def FeatureAVX2 : SubtargetFeature<"avx2", "HasAVX2", "true", +def FeatureAVX : SubtargetFeature<"avx", "X86SSELevel", "AVX", + "Enable AVX instructions", + [FeatureSSE42]>; +def FeatureAVX2 : SubtargetFeature<"avx2", "X86SSELevel", "AVX2", "Enable AVX2 instructions", [FeatureAVX]>; def FeatureCLMUL : SubtargetFeature<"clmul", "HasCLMUL", "true", diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index c31db42a756..d78003284ab 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -198,7 +198,7 @@ void X86Subtarget::AutoDetectSubtargetFeatures() { if ((ECX >> 19) & 1) { X86SSELevel = SSE41; ToggleFeature(X86::FeatureSSE41);} if ((ECX >> 20) & 1) { X86SSELevel = SSE42; ToggleFeature(X86::FeatureSSE42);} // FIXME: AVX codegen support is not ready. - //if ((ECX >> 28) & 1) { HasAVX = true; ToggleFeature(X86::FeatureAVX); } + //if ((ECX >> 28) & 1) { X86SSELevel = AVX; ToggleFeature(X86::FeatureAVX); } bool IsIntel = memcmp(text.c, "GenuineIntel", 12) == 0; bool IsAMD = !IsIntel && memcmp(text.c, "AuthenticAMD", 12) == 0; @@ -295,7 +295,7 @@ void X86Subtarget::AutoDetectSubtargetFeatures() { } // FIXME: AVX2 codegen support is not ready. //if ((EBX >> 5) & 0x1) { - // HasAVX2 = true; + // X86SSELevel = AVX2;; // ToggleFeature(X86::FeatureAVX2); //} if ((EBX >> 8) & 0x1) { @@ -317,8 +317,6 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, , HasX86_64(false) , HasPOPCNT(false) , HasSSE4A(false) - , HasAVX(false) - , HasAVX2(false) , HasAES(false) , HasCLMUL(false) , HasFMA3(false) @@ -372,7 +370,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, HasX86_64 = true; ToggleFeature(X86::Feature64Bit); HasCMov = true; ToggleFeature(X86::FeatureCMOV); - if (!HasAVX && X86SSELevel < SSE2) { + if (X86SSELevel < SSE2) { X86SSELevel = SSE2; ToggleFeature(X86::FeatureSSE1); ToggleFeature(X86::FeatureSSE2); @@ -385,9 +383,6 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, if (In64BitMode) ToggleFeature(X86::Mode64Bit); - if (HasAVX) - X86SSELevel = MMX; - DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel << ", 64bit " << HasX86_64 << "\n"); diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index ccb9be0c97a..10ef868968b 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -42,7 +42,7 @@ enum Style { class X86Subtarget : public X86GenSubtargetInfo { protected: enum X86SSEEnum { - NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42 + NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 }; enum X863DNowEnum { @@ -75,12 +75,6 @@ protected: /// HasSSE4A - True if the processor supports SSE4A instructions. bool HasSSE4A; - /// HasAVX - Target has AVX instructions - bool HasAVX; - - /// HasAVX2 - Target has AVX2 instructions - bool HasAVX2; - /// HasAES - Target has AES instructions bool HasAES; @@ -179,24 +173,24 @@ public: bool hasCMov() const { return HasCMov; } bool hasMMX() const { return X86SSELevel >= MMX; } - bool hasSSE1() const { return X86SSELevel >= SSE1; } - bool hasSSE2() const { return X86SSELevel >= SSE2; } - bool hasSSE3() const { return X86SSELevel >= SSE3; } - bool hasSSSE3() const { return X86SSELevel >= SSSE3; } - bool hasSSE41() const { return X86SSELevel >= SSE41; } - bool hasSSE42() const { return X86SSELevel >= SSE42; } + bool hasSSE1() const { return X86SSELevel >= SSE1 && !hasAVX(); } + bool hasSSE2() const { return X86SSELevel >= SSE2 && !hasAVX(); } + bool hasSSE3() const { return X86SSELevel >= SSE3 && !hasAVX(); } + bool hasSSSE3() const { return X86SSELevel >= SSSE3 && !hasAVX(); } + bool hasSSE41() const { return X86SSELevel >= SSE41 && !hasAVX(); } + bool hasSSE42() const { return X86SSELevel >= SSE42 && !hasAVX(); } bool hasSSE4A() const { return HasSSE4A; } bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } bool hasPOPCNT() const { return HasPOPCNT; } - bool hasAVX() const { return HasAVX; } - bool hasAVX2() const { return HasAVX2; } - bool hasXMM() const { return hasSSE1() || hasAVX(); } - bool hasXMMInt() const { return hasSSE2() || hasAVX(); } - bool hasSSE3orAVX() const { return hasSSE3() || hasAVX(); } - bool hasSSSE3orAVX() const { return hasSSSE3() || hasAVX(); } - bool hasSSE41orAVX() const { return hasSSE41() || hasAVX(); } - bool hasSSE42orAVX() const { return hasSSE42() || hasAVX(); } + bool hasAVX() const { return X86SSELevel >= AVX; } + bool hasAVX2() const { return X86SSELevel >= AVX2; } + bool hasXMM() const { return X86SSELevel >= SSE1; } + bool hasXMMInt() const { return X86SSELevel >= SSE2; } + bool hasSSE3orAVX() const { return X86SSELevel >= SSE3; } + bool hasSSSE3orAVX() const { return X86SSELevel >= SSSE3; } + bool hasSSE41orAVX() const { return X86SSELevel >= SSE41; } + bool hasSSE42orAVX() const { return X86SSELevel >= SSE42; } bool hasAES() const { return HasAES; } bool hasCLMUL() const { return HasCLMUL; } bool hasFMA3() const { return HasFMA3; }