From: Rafael Espindola Date: Tue, 20 Aug 2013 18:57:55 +0000 (+0000) Subject: Centralize the logic for handling -m* options and fix pr16943. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c84ed54f9786638c228fdc9b4db9920fa676d48d;p=clang Centralize the logic for handling -m* options and fix pr16943. This moves the logic for handling -mfoo -mno-foo from the driver to -cc1. It also changes -cc1 to apply the options in order, fixing pr16943. The handling of -mno-mmx -msse is now an explicit special case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188817 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 788579de7a..9d6406be25 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -2089,7 +2089,8 @@ void X86TargetInfo::setSSELevel(llvm::StringMap &Features, case SSE2: Features["sse2"] = true; case SSE1: - setMMXLevel(Features, MMX, Enabled); + if (!Features.count("mmx")) + setMMXLevel(Features, MMX, Enabled); Features["sse"] = true; case NoSSE: break; @@ -5468,34 +5469,29 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::StringMap Features; Target->getDefaultFeatures(Features); - // Apply the user specified deltas. - // First the enables. - for (std::vector::const_iterator - it = Opts->FeaturesAsWritten.begin(), - ie = Opts->FeaturesAsWritten.end(); - it != ie; ++it) { - const char *Name = it->c_str(); - - if (Name[0] != '+') - continue; - - // Apply the feature via the target. - Target->setFeatureEnabled(Features, Name + 1, true); + // Fist the last of each option; + llvm::StringMap LastOpt; + for (unsigned I = 0, N = Opts->FeaturesAsWritten.size(); + I < N; ++I) { + const char *Name = Opts->FeaturesAsWritten[I].c_str() + 1; + LastOpt[Name] = I; } - // Then the disables. - for (std::vector::const_iterator - it = Opts->FeaturesAsWritten.begin(), - ie = Opts->FeaturesAsWritten.end(); - it != ie; ++it) { - const char *Name = it->c_str(); - - if (Name[0] == '+') + // Apply the user specified deltas. + for (unsigned I = 0, N = Opts->FeaturesAsWritten.size(); + I < N; ++I) { + const char *Name = Opts->FeaturesAsWritten[I].c_str(); + + // If this option was overridden, ignore it. + llvm::StringMap::iterator LastI = LastOpt.find(Name + 1); + assert(LastI != LastOpt.end()); + unsigned Last = LastI->second; + if (Last != I) continue; // Apply the feature via the target. - assert(Name[0] == '-'); - Target->setFeatureEnabled(Features, Name + 1, false); + bool Enabled = Name[0] == '+'; + Target->setFeatureEnabled(Features, Name + 1, Enabled); } // Add the features to the compile options. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 3257946d28..fc7c726a78 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1335,14 +1335,6 @@ void Clang::AddX86TargetArgs(const ArgList &Args, CmdArgs.push_back(CPUName); } - // The required algorithm here is slightly strange: the options are applied - // in order (so -mno-sse -msse2 disables SSE3), but any option that gets - // directly overridden later is ignored (so "-mno-sse -msse2 -mno-sse2 -msse" - // is equivalent to "-mno-sse2 -msse"). The -cc1 handling deals with the - // former correctly, but not the latter; handle directly-overridden - // attributes here. - llvm::StringMap PrevFeature; - std::vector Features; for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group), ie = Args.filtered_end(); it != ie; ++it) { StringRef Name = (*it)->getOption().getName(); @@ -1356,17 +1348,8 @@ void Clang::AddX86TargetArgs(const ArgList &Args, if (IsNegative) Name = Name.substr(3); - unsigned& Prev = PrevFeature[Name]; - if (Prev) - Features[Prev - 1] = 0; - Prev = Features.size() + 1; - Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); - } - for (unsigned i = 0; i < Features.size(); i++) { - if (Features[i]) { - CmdArgs.push_back("-target-feature"); - CmdArgs.push_back(Features[i]); - } + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); } } diff --git a/test/Driver/x86_features.c b/test/Driver/x86_features.c index 5c65e31ff4..5470bbcdea 100644 --- a/test/Driver/x86_features.c +++ b/test/Driver/x86_features.c @@ -1,3 +1,2 @@ -// RUN: %clang -target i386-unknown-unknown -### -S %s -msse -msse4 -mno-sse -mno-mmx -msse 2> %t -// RUN: grep '"pentium4" "-target-feature" "+sse4" "-target-feature" "-mmx" "-target-feature" "+sse"' %t -// Note that we filter out all but the last -m(no)sse. +// RUN: %clang -target i386-unknown-unknown -### -S %s -msse -msse4 -mno-sse -mno-mmx -msse 2>&1 | FileCheck %s +// CHECK: "pentium4" "-target-feature" "+sse" "-target-feature" "+sse4" "-target-feature" "-sse" "-target-feature" "-mmx" "-target-feature" "+sse" diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c index 036a5da1de..4cdd3425cc 100644 --- a/test/Preprocessor/x86_target_features.c +++ b/test/Preprocessor/x86_target_features.c @@ -30,3 +30,15 @@ // SSE2: #define __SSE_MATH__ 1 // SSE2: #define __SSE__ 1 // SSE2-NOT: #define __SSSE3__ 1 + +// RUN: %clang -target i386-unknown-unknown -march=pentium-m -mno-sse -mavx -x c -E -dM -o - %s | FileCheck --check-prefix=AVX %s + +// AVX: #define __AVX__ 1 +// AVX: #define __SSE2_MATH__ 1 +// AVX: #define __SSE2__ 1 +// AVX: #define __SSE3__ 1 +// AVX: #define __SSE4_1__ 1 +// AVX: #define __SSE4_2__ 1 +// AVX: #define __SSE_MATH__ 1 +// AVX: #define __SSE__ 1 +// AVX: #define __SSSE3__ 1