From: Eli Friedman Date: Sat, 2 Jul 2011 00:34:19 +0000 (+0000) Subject: Make clang behave in a gcc-compatible way in the presence of multiple flags for the... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d18eecac712bfbf63372cb78940d662ce9017840;p=clang Make clang behave in a gcc-compatible way in the presence of multiple flags for the same x86 target feature (e.g. -mno-sse -msse). gcc uses a somewhat unintuitive algorithm here in that the enabled SSE instructions is based on the order of the *last* flag for *each* feature-level, so that "-mno-sse -msse2" only enables SSE2, but "-mno-sse -msse2 -msse" enables all SSE levels. Issue reported on cfe-dev. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134296 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 78d8677a8a..8059fa9499 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -839,6 +839,14 @@ 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) { llvm::StringRef Name = (*it)->getOption().getName(); @@ -852,8 +860,17 @@ void Clang::AddX86TargetArgs(const ArgList &Args, if (IsNegative) Name = Name.substr(3); - CmdArgs.push_back("-target-feature"); - CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); + 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]); + } } } diff --git a/test/Driver/x86_features.c b/test/Driver/x86_features.c index 9dbdd0ae90..0db372ec64 100644 --- a/test/Driver/x86_features.c +++ b/test/Driver/x86_features.c @@ -1,3 +1,3 @@ // RUN: %clang -ccc-host-triple i386-unknown-unknown -### -S %s -msse -msse4 -mno-sse -mno-mmx -msse 2> %t -// RUN: grep '"-target-feature" "+sse" "-target-feature" "+sse4" "-target-feature" "-sse" "-target-feature" "-mmx" "-target-feature" "+sse"' %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.