From eeb7e65c5fca09825cfcd7a24a7670bbcb010cbb Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 15 Jul 2014 18:27:51 +0000 Subject: [PATCH] clang-cl: Implement the -arch flag Summary: This implements the -arch flag for both x86 and x86-64 by letting them affect the default target features we pass to cc1. -m machine flags will override the features set by -arch. Reviewers: hansw Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D4519 llvm-svn: 213083 --- clang/include/clang/Driver/CLCompatOptions.td | 4 +- clang/lib/Driver/Tools.cpp | 30 ++++++++++- clang/test/Driver/cl-options.c | 1 - clang/test/Driver/cl-x86-flags.c | 71 +++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td index 90e3aca..7278bf8 100644 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ b/clang/include/clang/Driver/CLCompatOptions.td @@ -138,6 +138,9 @@ def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, // 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 @@ def _SLASH_Zm : CLIgnoredJoined<"Zm">; // 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+">; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index bc64d5c..c5bf7e4 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1423,7 +1423,8 @@ static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU)); } -static void getX86TargetFeatures(const llvm::Triple &Triple, +static void getX86TargetFeatures(const Driver & D, + const llvm::Triple &Triple, const ArgList &Args, std::vector &Features) { if (Triple.getArchName() == "x86_64h") { @@ -1446,6 +1447,31 @@ static void getX86TargetFeatures(const llvm::Triple &Triple, Features.push_back("+ssse3"); } + // Set features according to the -arch flag on MSVC + if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { + StringRef Arch = A->getValue(); + bool ArchUsed = false; + // 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") { + ArchUsed = true; + Features.push_back(Args.MakeArgString("+" + Arch.lower())); + } + } + // Then, look for x86-specific flags. + if (Triple.getArch() == llvm::Triple::x86) { + if (Arch == "IA32") { + ArchUsed = true; + } else if (Arch == "SSE" || Arch == "SSE2") { + ArchUsed = true; + Features.push_back(Args.MakeArgString("+" + Arch.lower())); + } + } + if (!ArchUsed) + D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args); + } + // 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), @@ -1608,7 +1634,7 @@ static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, break; case llvm::Triple::x86: case llvm::Triple::x86_64: - getX86TargetFeatures(Triple, Args, Features); + getX86TargetFeatures(D, Triple, Args, Features); break; } diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 2e03084..6288391 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/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+ \ diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c index 87eb3f5..4ddde7e 100644 --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -8,5 +8,76 @@ // 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: argument unused during compilation +// IA32-NOT: -target-feature + +// RUN: %clang_cl -m32 -arch:ia32 -### -- 2>&1 %s | FileCheck -check-prefix=ia32 %s +// ia32: argument unused during compilation +// ia32-NOT: -target-feature + +// RUN: %clang_cl -m64 -arch:IA32 -### -- 2>&1 %s | FileCheck -check-prefix=IA3264 %s +// IA3264: argument unused during compilation +// IA3264-NOT: -target-feature + +// RUN: %clang_cl -m32 -arch:SSE -### -- 2>&1 %s | FileCheck -check-prefix=SSE %s +// SSE: -target-feature +// SSE: +sse +// SSE-NOT: argument unused during compilation + +// RUN: %clang_cl -m32 -arch:sse -### -- 2>&1 %s | FileCheck -check-prefix=sse %s +// sse: argument unused during compilation +// sse-NOT: -target-feature + +// RUN: %clang_cl -m32 -arch:SSE2 -### -- 2>&1 %s | FileCheck -check-prefix=SSE2 %s +// SSE2: -target-feature +// SSE2: +sse2 +// SSE2-NOT: argument unused during compilation + +// RUN: %clang_cl -m32 -arch:sse2 -### -- 2>&1 %s | FileCheck -check-prefix=sse %s +// sse2: argument unused during compilation +// sse2-NOT: -target-feature + +// RUN: %clang_cl -m64 -arch:SSE -### -- 2>&1 %s | FileCheck -check-prefix=SSE64 %s +// SSE64: argument unused during compilation +// SSE64-NOT: -target-feature + +// RUN: %clang_cl -m64 -arch:SSE2 -### -- 2>&1 %s | FileCheck -check-prefix=SSE264 %s +// SSE264: argument unused during compilation +// 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:avx -### -- 2>&1 %s | FileCheck -check-prefix=avx %s +// avx: argument unused during compilation +// avx-NOT: -target-feature + +// RUN: %clang_cl -m32 -arch:AVX2 -### -- 2>&1 %s | FileCheck -check-prefix=AVX2 %s +// AVX2: -target-feature +// AVX2: +avx2 + +// RUN: %clang_cl -m32 -arch:avx2 -### -- 2>&1 %s | FileCheck -check-prefix=avx2 %s +// avx2: argument unused during compilation +// avx2-NOT: -target-feature + +// RUN: %clang_cl -m64 -arch:AVX -### -- 2>&1 %s | FileCheck -check-prefix=AVX64 %s +// AVX64: -target-feature +// AVX64: +avx + +// RUN: %clang_cl -m64 -arch:avx -### -- 2>&1 %s | FileCheck -check-prefix=avx64 %s +// avx64: argument unused during compilation +// avx64-NOT: -target-feature + +// RUN: %clang_cl -m64 -arch:AVX2 -### -- 2>&1 %s | FileCheck -check-prefix=AVX264 %s +// AVX264: -target-feature +// AVX264: +avx2 + +// RUN: %clang_cl -m64 -arch:avx2 -### -- 2>&1 %s | FileCheck -check-prefix=avx264 %s +// avx264: argument unused during compilation +// avx264-NOT: -target-feature + void f() { } -- 2.7.4