From: Nico Weber Date: Thu, 25 Jan 2018 14:38:29 +0000 (+0000) Subject: clang-cl: Simplify handling of /arch: flag. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=96b4d114c73144574569f74e1e04e14f64513026;p=clang clang-cl: Simplify handling of /arch: flag. r213083 initially implemented /arch: support by mapping it to CPU features. Then r241077 additionally mapped it to CPU, which made the feature flags redundant (if harmless). This change here removes the redundant mapping to feature flags, and rewrites test/Driver/cl-x86-flags.c to be a bit more of an integration test that checks for preprocessor defines like AVX (like documented on MSDN) instead of for driver flags. To keep emitting warn_drv_unused_argument, use getLastArgNoClaim() followed by an explicit claim() if needed. This is in preparation for adding support for /arch:AVX512(F). No intended behavior change. https://reviews.llvm.org/D42497 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@323426 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp index a18b2aa35b..f506cd6a34 100644 --- a/lib/Driver/ToolChains/Arch/X86.cpp +++ b/lib/Driver/ToolChains/Arch/X86.cpp @@ -40,8 +40,8 @@ const char *x86::getX86TargetCPU(const ArgList &Args, return Args.MakeArgString(CPU); } - if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { - // Mapping built by referring to X86TargetInfo::getDefaultFeatures(). + if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) { + // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap(). StringRef Arch = A->getValue(); const char *CPU; if (Triple.getArch() == llvm::Triple::x86) { @@ -58,8 +58,10 @@ const char *x86::getX86TargetCPU(const ArgList &Args, .Case("AVX2", "haswell") .Default(nullptr); } - if (CPU) + if (CPU) { + A->claim(); return CPU; + } } // Select the default CPU if none was given (or detection failed). @@ -141,30 +143,6 @@ void x86::getX86TargetFeatures(const Driver &D, 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 (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) { - if (Arch == "AVX" || Arch == "AVX2") { - ArchUsed = true; - Features.push_back(Args.MakeArgString("+" + Arch.lower())); - } - } - // Then, look for x86-specific flags. - if (ArchType == 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. handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group); diff --git a/test/Driver/cl-x86-flags.c b/test/Driver/cl-x86-flags.c index 32cd072ec1..cc5c62904f 100644 --- a/test/Driver/cl-x86-flags.c +++ b/test/Driver/cl-x86-flags.c @@ -1,88 +1,92 @@ // REQUIRES: x86-registered-target +// expected-no-diagnostics + // We support -m32 and -m64. We support all x86 CPU feature flags in gcc's -m // flag space. // RUN: %clang_cl /Zs /WX -m32 -m64 -msse3 -msse4.1 -mavx -mno-avx \ // RUN: --target=i386-pc-win32 -### -- 2>&1 %s | FileCheck -check-prefix=MFLAGS %s // MFLAGS-NOT: argument unused during compilation -// RUN: %clang_cl -m32 -arch:IA32 --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=IA32 %s -// IA32: "-target-cpu" "i386" -// IA32-NOT: -target-feature -// IA32-NOT: argument unused during compilation +// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-windows /c -Xclang -verify -DTEST_32_ARCH_IA32 -- %s +#if defined(TEST_32_ARCH_IA32) +#if _M_IX86_FP || __AVX__ || __AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m32 -arch:ia32 --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=ia32 %s +// arch: args are case-sensitive. +// RUN: %clang_cl -m32 -arch:ia32 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=ia32 %s // ia32: argument unused during compilation -// ia32-NOT: -target-feature -// RUN: %clang_cl -m64 -arch:IA32 --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=IA3264 %s +// RUN: %clang_cl -m64 -arch:IA32 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=IA3264 %s // IA3264: argument unused during compilation -// IA3264-NOT: -target-feature -// RUN: %clang_cl -m32 -arch:SSE --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=SSE %s -// SSE: "-target-cpu" "pentium3" -// SSE: -target-feature -// SSE: +sse -// SSE-NOT: argument unused during compilation +// RUN: %clang_cl -m32 -arch:SSE --target=i386-pc-windows /c -Xclang -verify -DTEST_32_ARCH_SSE -- %s +#if defined(TEST_32_ARCH_SSE) +#if _M_IX86_FP != 1 || __AVX__ || __AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m32 -arch:sse --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=sse %s +// RUN: %clang_cl -m32 -arch:sse --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=sse %s // sse: argument unused during compilation -// sse-NOT: -target-feature -// RUN: %clang_cl -m32 -arch:SSE2 --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=SSE2 %s -// SSE2: "-target-cpu" "pentium4" -// SSE2: -target-feature -// SSE2: +sse2 -// SSE2-NOT: argument unused during compilation +// RUN: %clang_cl -m32 -arch:SSE2 --target=i386-pc-windows /c -Xclang -verify -DTEST_32_ARCH_SSE2 -- %s +#if defined(TEST_32_ARCH_SSE2) +#if _M_IX86_FP != 2 || __AVX__ || __AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m32 -arch:sse2 --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=sse %s +// RUN: %clang_cl -m32 -arch:sse2 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=sse %s // sse2: argument unused during compilation -// sse2-NOT: -target-feature -// RUN: %clang_cl -m64 -arch:SSE --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=SSE64 %s +// RUN: %clang_cl -m64 -arch:SSE --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=SSE64 %s // SSE64: argument unused during compilation -// SSE64-NOT: -target-feature -// SSE64-NOT: pentium3 -// RUN: %clang_cl -m64 -arch:SSE2 --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=SSE264 %s +// RUN: %clang_cl -m64 -arch:SSE2 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=SSE264 %s // SSE264: argument unused during compilation -// SSE264-NOT: -target-feature -// RUN: %clang_cl -m32 -arch:AVX --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=AVX %s -// AVX: "-target-cpu" "sandybridge" -// AVX: -target-feature -// AVX: +avx +// RUN: %clang_cl -m32 -arch:AVX --target=i386-pc-windows /c -Xclang -verify -DTEST_32_ARCH_AVX -- %s +#if defined(TEST_32_ARCH_AVX) +#if _M_IX86_FP != 2 || !__AVX__ || __AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m32 -arch:avx --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=avx %s +// RUN: %clang_cl -m32 -arch:avx --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx %s // avx: argument unused during compilation -// avx-NOT: -target-feature -// RUN: %clang_cl -m32 -arch:AVX2 --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=AVX2 %s -// AVX2: "-target-cpu" "haswell" -// AVX2: -target-feature -// AVX2: +avx2 +// RUN: %clang_cl -m32 -arch:AVX2 --target=i386-pc-windows /c -Xclang -verify -DTEST_32_ARCH_AVX2 -- %s +#if defined(TEST_32_ARCH_AVX2) +#if _M_IX86_FP != 2 || !__AVX__ || !__AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m32 -arch:avx2 --target=i386 -### -- 2>&1 %s | FileCheck -check-prefix=avx2 %s +// RUN: %clang_cl -m32 -arch:avx2 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx2 %s // avx2: argument unused during compilation -// avx2-NOT: -target-feature -// RUN: %clang_cl -m64 -arch:AVX --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=AVX64 %s -// AVX64: "-target-cpu" "sandybridge" -// AVX64: -target-feature -// AVX64: +avx +// RUN: %clang_cl -m64 -arch:AVX --target=x86_64-pc-windows /c -Xclang -verify -DTEST_64_ARCH_AVX -- %s +#if defined(TEST_64_ARCH_AVX) +#if _M_IX86_FP || !__AVX__ || __AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m64 -arch:avx --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=avx64 %s +// RUN: %clang_cl -m64 -arch:avx --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx64 %s // avx64: argument unused during compilation -// avx64-NOT: -target-feature -// RUN: %clang_cl -m64 -arch:AVX2 --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=AVX264 %s -// AVX264: "-target-cpu" "haswell" -// AVX264: -target-feature -// AVX264: +avx2 +// RUN: %clang_cl -m64 -arch:AVX2 --target=x86_64-pc-windows /c -Xclang -verify -DTEST_64_ARCH_AVX2 -- %s +#if defined(TEST_64_ARCH_AVX2) +#if _M_IX86_FP || !__AVX__ || !__AVX2__ || __AVX512F__ || __AVX512BW__ +#error fail +#endif +#endif -// RUN: %clang_cl -m64 -arch:avx2 --target=x86_64 -### -- 2>&1 %s | FileCheck -check-prefix=avx264 %s +// RUN: %clang_cl -m64 -arch:avx2 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx264 %s // avx264: argument unused during compilation -// avx264-NOT: -target-feature void f() { }