Index: include/clang/Driver/CLCompatOptions.td =================================================================== --- include/clang/Driver/CLCompatOptions.td +++ include/clang/Driver/CLCompatOptions.td @@ -138,6 +138,9 @@ // Non-aliases: +def _SLASH_arch : CLCompileJoined<"arch:">, + HelpText<"Set architecture for code generation">; + def _SLASH_M_Group : OptionGroup<"">, Group; def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">; @@ -207,7 +210,6 @@ // Unsupported: def _SLASH_AI : CLJoined<"AI">; -def _SLASH_arch : CLJoined<"arch:">; def _SLASH_bigobj : CLFlag<"bigobj">; def _SLASH_clr : CLJoined<"clr">; def _SLASH_d2Zi_PLUS : CLFlag<"d2Zi+">; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -1446,6 +1446,25 @@ Features.push_back("+ssse3"); } + // Set features according to the -arch flag on MSVC + if (Triple.isKnownWindowsMSVCEnvironment()) { + if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { + std::string Arch = A->getValue(); + std::transform(Arch.begin(), Arch.end(), Arch.begin(), std::tolower); + // First, look for flags that are shared in x86 and x86-64. + if (Triple.getArch() == llvm::Triple::x86_64 || + Triple.getArch() == llvm::Triple::x86) { + if (Arch == "avx" || Arch == "avx2") + Features.push_back(Args.MakeArgString("+" + Arch)); + } + // Then, look for x86-specific flags. + if (Triple.getArch() == llvm::Triple::x86) { + if (Arch == "sse" || Arch == "sse2") + Features.push_back(Args.MakeArgString("+" + Arch)); + } + } + } + // Now add any that the user explicitly requested on the command line, // which may override the defaults. for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group), Index: test/Driver/cl-options.c =================================================================== --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -198,7 +198,6 @@ // (/Zs is for syntax-only) // RUN: %clang_cl /Zs \ // RUN: /AIfoo \ -// RUN: /arch:sse2 \ // RUN: /clr:pure \ // RUN: /docname \ // RUN: /d2Zi+ \ Index: test/Driver/cl-x86-flags.c =================================================================== --- test/Driver/cl-x86-flags.c +++ test/Driver/cl-x86-flags.c @@ -8,5 +8,39 @@ // RUN: -### -- 2>&1 %s | FileCheck -check-prefix=MFLAGS %s // MFLAGS-NOT: argument unused during compilation +// -arch:IA32 is no-op. +// RUN: %clang_cl -m32 -arch:IA32 -### -- 2>&1 %s | FileCheck -check-prefix=IA32 %s +// IA32-NOT: -target-feature + +// RUN: %clang_cl -m32 -arch:SSE -### -- 2>&1 %s | FileCheck -check-prefix=SSE %s +// SSE: -target-feature +// SSE: +sse + +// RUN: %clang_cl -m32 -arch:SSE2 -### -- 2>&1 %s | FileCheck -check-prefix=SSE2 %s +// SSE2: -target-feature +// SSE2: +sse2 + +// RUN: %clang_cl -m64 -arch:SSE -### -- 2>&1 %s | FileCheck -check-prefix=SSE64 %s +// SSE64-NOT: -target-feature + +// RUN: %clang_cl -m64 -arch:SSE2 -### -- 2>&1 %s | FileCheck -check-prefix=SSE264 %s +// SSE264-NOT: -target-feature + +// RUN: %clang_cl -m32 -arch:AVX -### -- 2>&1 %s | FileCheck -check-prefix=AVX %s +// AVX: -target-feature +// AVX: +avx + +// RUN: %clang_cl -m32 -arch:AVX2 -### -- 2>&1 %s | FileCheck -check-prefix=AVX2 %s +// AVX2: -target-feature +// AVX2: +avx2 + +// RUN: %clang_cl -m64 -arch:AVX -### -- 2>&1 %s | FileCheck -check-prefix=AVX64 %s +// AVX64: -target-feature +// AVX64: +avx + +// RUN: %clang_cl -m64 -arch:AVX2 -### -- 2>&1 %s | FileCheck -check-prefix=AVX264 %s +// AVX264: -target-feature +// AVX264: +avx2 + void f() { }