Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Driver/ToolChains/Arch/X86.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- X86.cpp - X86 Helpers for Tools ------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "X86.h"
10
#include "ToolChains/CommonArgs.h"
11
#include "clang/Driver/Driver.h"
12
#include "clang/Driver/DriverDiagnostic.h"
13
#include "clang/Driver/Options.h"
14
#include "llvm/ADT/StringSwitch.h"
15
#include "llvm/Option/ArgList.h"
16
17
using namespace clang::driver;
18
using namespace clang::driver::tools;
19
using namespace clang;
20
using namespace llvm::opt;
21
22
const char *x86::getX86TargetCPU(const ArgList &Args,
23
15.1k
                                 const llvm::Triple &Triple) {
24
15.1k
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
25
525
    if (StringRef(A->getValue()) != "native")
26
525
      return A->getValue();
27
0
28
0
    // FIXME: Reject attempts to use -march=native unless the target matches
29
0
    // the host.
30
0
    //
31
0
    // FIXME: We should also incorporate the detected target features for use
32
0
    // with -native.
33
0
    std::string CPU = llvm::sys::getHostCPUName();
34
0
    if (!CPU.empty() && CPU != "generic")
35
0
      return Args.MakeArgString(CPU);
36
14.6k
  }
37
14.6k
38
14.6k
  if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) {
39
29
    // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap().
40
29
    StringRef Arch = A->getValue();
41
29
    const char *CPU = nullptr;
42
29
    if (Triple.getArch() == llvm::Triple::x86) {  // 32-bit-only /arch: flags.
43
18
      CPU = llvm::StringSwitch<const char *>(Arch)
44
18
                .Case("IA32", "i386")
45
18
                .Case("SSE", "pentium3")
46
18
                .Case("SSE2", "pentium4")
47
18
                .Default(nullptr);
48
18
    }
49
29
    if (CPU == nullptr) {  // 32-bit and 64-bit /arch: flags.
50
22
      CPU = llvm::StringSwitch<const char *>(Arch)
51
22
                .Case("AVX", "sandybridge")
52
22
                .Case("AVX2", "haswell")
53
22
                .Case("AVX512F", "knl")
54
22
                .Case("AVX512", "skylake-avx512")
55
22
                .Default(nullptr);
56
22
    }
57
29
    if (CPU) {
58
15
      A->claim();
59
15
      return CPU;
60
15
    }
61
14.6k
  }
62
14.6k
63
14.6k
  // Select the default CPU if none was given (or detection failed).
64
14.6k
65
14.6k
  if (Triple.getArch() != llvm::Triple::x86_64 &&
66
14.6k
      
Triple.getArch() != llvm::Triple::x862.86k
)
67
0
    return nullptr; // This routine is only handling x86 targets.
68
14.6k
69
14.6k
  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
70
14.6k
71
14.6k
  // FIXME: Need target hooks.
72
14.6k
  if (Triple.isOSDarwin()) {
73
10.4k
    if (Triple.getArchName() == "x86_64h")
74
688
      return "core-avx2";
75
9.78k
    // macosx10.12 drops support for all pre-Penryn Macs.
76
9.78k
    // Simulators can still run on 10.11 though, like Xcode.
77
9.78k
    if (Triple.isMacOSX() && 
!Triple.isOSVersionLT(10, 12)8.84k
)
78
7.94k
      return "penryn";
79
1.83k
    // The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
80
1.83k
    return Is64Bit ? 
"core2"1.41k
:
"yonah"423
;
81
1.83k
  }
82
4.18k
83
4.18k
  // Set up default CPU name for PS4 compilers.
84
4.18k
  if (Triple.isPS4CPU())
85
116
    return "btver2";
86
4.07k
87
4.07k
  // On Android use targets compatible with gcc
88
4.07k
  if (Triple.isAndroid())
89
38
    return Is64Bit ? 
"x86-64"15
:
"i686"23
;
90
4.03k
91
4.03k
  // Everything else goes to x86-64 in 64-bit mode.
92
4.03k
  if (Is64Bit)
93
1.65k
    return "x86-64";
94
2.37k
95
2.37k
  switch (Triple.getOS()) {
96
2.37k
  case llvm::Triple::FreeBSD:
97
62
  case llvm::Triple::NetBSD:
98
62
  case llvm::Triple::OpenBSD:
99
62
    return "i486";
100
62
  case llvm::Triple::Haiku:
101
0
    return "i586";
102
2.31k
  default:
103
2.31k
    // Fallback to p4.
104
2.31k
    return "pentium4";
105
2.37k
  }
106
2.37k
}
107
108
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
109
                               const ArgList &Args,
110
15.1k
                               std::vector<StringRef> &Features) {
111
15.1k
  // If -march=native, autodetect the feature list.
112
15.1k
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
113
524
    if (StringRef(A->getValue()) == "native") {
114
0
      llvm::StringMap<bool> HostFeatures;
115
0
      if (llvm::sys::getHostCPUFeatures(HostFeatures))
116
0
        for (auto &F : HostFeatures)
117
0
          Features.push_back(
118
0
              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
119
0
    }
120
524
  }
121
15.1k
122
15.1k
  if (Triple.getArchName() == "x86_64h") {
123
689
    // x86_64h implies quite a few of the more modern subtarget features
124
689
    // for Haswell class CPUs, but not all of them. Opt-out of a few.
125
689
    Features.push_back("-rdrnd");
126
689
    Features.push_back("-aes");
127
689
    Features.push_back("-pclmul");
128
689
    Features.push_back("-rtm");
129
689
    Features.push_back("-fsgsbase");
130
689
  }
131
15.1k
132
15.1k
  const llvm::Triple::ArchType ArchType = Triple.getArch();
133
15.1k
  // Add features to be compatible with gcc for Android.
134
15.1k
  if (Triple.isAndroid()) {
135
37
    if (ArchType == llvm::Triple::x86_64) {
136
15
      Features.push_back("+sse4.2");
137
15
      Features.push_back("+popcnt");
138
15
      Features.push_back("+cx16");
139
15
    } else
140
22
      Features.push_back("+ssse3");
141
37
  }
142
15.1k
143
15.1k
  // Translate the high level `-mretpoline` flag to the specific target feature
144
15.1k
  // flags. We also detect if the user asked for retpoline external thunks but
145
15.1k
  // failed to ask for retpolines themselves (through any of the different
146
15.1k
  // flags). This is a bit hacky but keeps existing usages working. We should
147
15.1k
  // consider deprecating this and instead warn if the user requests external
148
15.1k
  // retpoline thunks and *doesn't* request some form of retpolines.
149
15.1k
  if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline,
150
15.1k
                         options::OPT_mspeculative_load_hardening,
151
15.1k
                         options::OPT_mno_speculative_load_hardening)) {
152
10
    if (Args.hasFlag(options::OPT_mretpoline, options::OPT_mno_retpoline,
153
10
                     false)) {
154
4
      Features.push_back("+retpoline-indirect-calls");
155
4
      Features.push_back("+retpoline-indirect-branches");
156
6
    } else if (Args.hasFlag(options::OPT_mspeculative_load_hardening,
157
6
                            options::OPT_mno_speculative_load_hardening,
158
6
                            false)) {
159
1
      // On x86, speculative load hardening relies on at least using retpolines
160
1
      // for indirect calls.
161
1
      Features.push_back("+retpoline-indirect-calls");
162
1
    }
163
15.1k
  } else if (Args.hasFlag(options::OPT_mretpoline_external_thunk,
164
15.1k
                          options::OPT_mno_retpoline_external_thunk, false)) {
165
0
    // FIXME: Add a warning about failing to specify `-mretpoline` and
166
0
    // eventually switch to an error here.
167
0
    Features.push_back("+retpoline-indirect-calls");
168
0
    Features.push_back("+retpoline-indirect-branches");
169
0
  }
170
15.1k
171
15.1k
  // Now add any that the user explicitly requested on the command line,
172
15.1k
  // which may override the defaults.
173
15.1k
  handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
174
15.1k
}