Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/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
#include "llvm/Support/Host.h"
17
18
using namespace clang::driver;
19
using namespace clang::driver::tools;
20
using namespace clang;
21
using namespace llvm::opt;
22
23
const char *x86::getX86TargetCPU(const ArgList &Args,
24
22.2k
                                 const llvm::Triple &Triple) {
25
22.2k
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
26
355
    if (StringRef(A->getValue()) != "native")
27
355
      return A->getValue();
28
0
29
0
    // FIXME: Reject attempts to use -march=native unless the target matches
30
0
    // the host.
31
0
    //
32
0
    // FIXME: We should also incorporate the detected target features for use
33
0
    // with -native.
34
0
    std::string CPU = std::string(llvm::sys::getHostCPUName());
35
0
    if (!CPU.empty() && CPU != "generic")
36
0
      return Args.MakeArgString(CPU);
37
21.9k
  }
38
21.9k
39
21.9k
  if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) {
40
29
    // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap().
41
29
    StringRef Arch = A->getValue();
42
29
    const char *CPU = nullptr;
43
29
    if (Triple.getArch() == llvm::Triple::x86) {  // 32-bit-only /arch: flags.
44
18
      CPU = llvm::StringSwitch<const char *>(Arch)
45
18
                .Case("IA32", "i386")
46
18
                .Case("SSE", "pentium3")
47
18
                .Case("SSE2", "pentium4")
48
18
                .Default(nullptr);
49
18
    }
50
29
    if (CPU == nullptr) {  // 32-bit and 64-bit /arch: flags.
51
22
      CPU = llvm::StringSwitch<const char *>(Arch)
52
22
                .Case("AVX", "sandybridge")
53
22
                .Case("AVX2", "haswell")
54
22
                .Case("AVX512F", "knl")
55
22
                .Case("AVX512", "skylake-avx512")
56
22
                .Default(nullptr);
57
22
    }
58
29
    if (CPU) {
59
15
      A->claim();
60
15
      return CPU;
61
15
    }
62
21.9k
  }
63
21.9k
64
21.9k
  // Select the default CPU if none was given (or detection failed).
65
21.9k
66
21.9k
  if (!Triple.isX86())
67
0
    return nullptr; // This routine is only handling x86 targets.
68
21.9k
69
21.9k
  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
70
21.9k
71
21.9k
  // FIXME: Need target hooks.
72
21.9k
  if (Triple.isOSDarwin()) {
73
17.0k
    if (Triple.getArchName() == "x86_64h")
74
5
      return "core-avx2";
75
17.0k
    // macosx10.12 drops support for all pre-Penryn Macs.
76
17.0k
    // Simulators can still run on 10.11 though, like Xcode.
77
17.0k
    if (Triple.isMacOSX() && 
!Triple.isOSVersionLT(10, 12)17.0k
)
78
16.7k
      return "penryn";
79
310
    // The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
80
310
    return Is64Bit ? 
"core2"243
:
"yonah"67
;
81
310
  }
82
4.82k
83
4.82k
  // Set up default CPU name for PS4 compilers.
84
4.82k
  if (Triple.isPS4CPU())
85
119
    return "btver2";
86
4.70k
87
4.70k
  // On Android use targets compatible with gcc
88
4.70k
  if (Triple.isAndroid())
89
37
    return Is64Bit ? 
"x86-64"15
:
"i686"22
;
90
4.66k
91
4.66k
  // Everything else goes to x86-64 in 64-bit mode.
92
4.66k
  if (Is64Bit)
93
2.03k
    return "x86-64";
94
2.63k
95
2.63k
  switch (Triple.getOS()) {
96
63
  case llvm::Triple::FreeBSD:
97
63
  case llvm::Triple::NetBSD:
98
63
  case llvm::Triple::OpenBSD:
99
63
    return "i486";
100
63
  case llvm::Triple::Haiku:
101
0
    return "i586";
102
2.56k
  default:
103
2.56k
    // Fallback to p4.
104
2.56k
    return "pentium4";
105
2.63k
  }
106
2.63k
}
107
108
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
109
                               const ArgList &Args,
110
22.2k
                               std::vector<StringRef> &Features) {
111
22.2k
  // If -march=native, autodetect the feature list.
112
22.2k
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
113
355
    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
355
  }
121
22.2k
122
22.2k
  if (Triple.getArchName() == "x86_64h") {
123
6
    // x86_64h implies quite a few of the more modern subtarget features
124
6
    // for Haswell class CPUs, but not all of them. Opt-out of a few.
125
6
    Features.push_back("-rdrnd");
126
6
    Features.push_back("-aes");
127
6
    Features.push_back("-pclmul");
128
6
    Features.push_back("-rtm");
129
6
    Features.push_back("-fsgsbase");
130
6
  }
131
22.2k
132
22.2k
  const llvm::Triple::ArchType ArchType = Triple.getArch();
133
22.2k
  // Add features to be compatible with gcc for Android.
134
22.2k
  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
22.2k
143
22.2k
  // Translate the high level `-mretpoline` flag to the specific target feature
144
22.2k
  // flags. We also detect if the user asked for retpoline external thunks but
145
22.2k
  // failed to ask for retpolines themselves (through any of the different
146
22.2k
  // flags). This is a bit hacky but keeps existing usages working. We should
147
22.2k
  // consider deprecating this and instead warn if the user requests external
148
22.2k
  // retpoline thunks and *doesn't* request some form of retpolines.
149
22.2k
  if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline,
150
22.2k
                         options::OPT_mspeculative_load_hardening,
151
22.2k
                         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
22.2k
  } else if (Args.hasFlag(options::OPT_mretpoline_external_thunk,
164
22.2k
                          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
22.2k
171
22.2k
  // Now add any that the user explicitly requested on the command line,
172
22.2k
  // which may override the defaults.
173
22.2k
  handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
174
22.2k
}