[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / unittests / Support / Host.cpp
blob523e6e2195e413c50e9dcfe41fd2243022c35c21
1 //========- unittests/Support/Host.cpp - Host.cpp tests --------------========//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/Host.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/Triple.h"
12 #include "llvm/Config/config.h"
13 #include "llvm/Support/FileSystem.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/Program.h"
16 #include "llvm/Support/Threading.h"
18 #include "gtest/gtest.h"
20 #define ASSERT_NO_ERROR(x) \
21 if (std::error_code ASSERT_NO_ERROR_ec = x) { \
22 SmallString<128> MessageStorage; \
23 raw_svector_ostream Message(MessageStorage); \
24 Message << #x ": did not return errc::success.\n" \
25 << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
26 << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
27 GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
28 } else { \
31 using namespace llvm;
33 class HostTest : public testing::Test {
34 Triple Host;
36 protected:
37 bool isSupportedArchAndOS() {
38 // Initially this is only testing detection of the number of
39 // physical cores, which is currently only supported/tested on
40 // some systems.
41 return (Host.isOSWindows() && llvm_is_multithreaded()) ||
42 Host.isOSDarwin() || (Host.isX86() && Host.isOSLinux()) ||
43 (Host.isOSLinux() && !Host.isAndroid()) ||
44 (Host.isSystemZ() && Host.isOSzOS());
47 HostTest() : Host(Triple::normalize(sys::getProcessTriple())) {}
50 TEST_F(HostTest, NumPhysicalCoresSupported) {
51 if (!isSupportedArchAndOS())
52 GTEST_SKIP();
53 int Num = sys::getHostNumPhysicalCores();
54 ASSERT_GT(Num, 0);
57 TEST_F(HostTest, NumPhysicalCoresUnsupported) {
58 if (isSupportedArchAndOS())
59 GTEST_SKIP();
60 int Num = sys::getHostNumPhysicalCores();
61 ASSERT_EQ(Num, -1);
64 TEST(getLinuxHostCPUName, ARM) {
65 StringRef CortexA9ProcCpuinfo = R"(
66 processor : 0
67 model name : ARMv7 Processor rev 10 (v7l)
68 BogoMIPS : 1393.66
69 Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
70 CPU implementer : 0x41
71 CPU architecture: 7
72 CPU variant : 0x2
73 CPU part : 0xc09
74 CPU revision : 10
76 processor : 1
77 model name : ARMv7 Processor rev 10 (v7l)
78 BogoMIPS : 1393.66
79 Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
80 CPU implementer : 0x41
81 CPU architecture: 7
82 CPU variant : 0x2
83 CPU part : 0xc09
84 CPU revision : 10
86 Hardware : Generic OMAP4 (Flattened Device Tree)
87 Revision : 0000
88 Serial : 0000000000000000
89 )";
91 EXPECT_EQ(sys::detail::getHostCPUNameForARM(CortexA9ProcCpuinfo),
92 "cortex-a9");
93 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
94 "CPU part : 0xc0f"),
95 "cortex-a15");
96 // Verify that both CPU implementer and CPU part are checked:
97 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
98 "CPU part : 0xc0f"),
99 "generic");
100 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
101 "CPU part : 0x06f"),
102 "krait");
105 TEST(getLinuxHostCPUName, AArch64) {
106 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
107 "CPU part : 0xd03"),
108 "cortex-a53");
110 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
111 "CPU part : 0xd40"),
112 "neoverse-v1");
113 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
114 "CPU part : 0xd0c"),
115 "neoverse-n1");
116 // Verify that both CPU implementer and CPU part are checked:
117 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
118 "CPU part : 0xd03"),
119 "generic");
120 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
121 "CPU part : 0x201"),
122 "kryo");
123 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
124 "CPU part : 0x800"),
125 "cortex-a73");
126 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
127 "CPU part : 0x801"),
128 "cortex-a73");
129 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
130 "CPU part : 0xc00"),
131 "falkor");
132 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
133 "CPU part : 0xc01"),
134 "saphira");
136 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0xc0\n"
137 "CPU part : 0xac3"),
138 "ampere1");
140 // MSM8992/4 weirdness
141 StringRef MSM8992ProcCpuInfo = R"(
142 Processor : AArch64 Processor rev 3 (aarch64)
143 processor : 0
144 processor : 1
145 processor : 2
146 processor : 3
147 processor : 4
148 processor : 5
149 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
150 CPU implementer : 0x41
151 CPU architecture: 8
152 CPU variant : 0x0
153 CPU part : 0xd03
154 CPU revision : 3
156 Hardware : Qualcomm Technologies, Inc MSM8992
159 EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo),
160 "cortex-a53");
162 // Exynos big.LITTLE weirdness
163 const std::string ExynosProcCpuInfo = R"(
164 processor : 0
165 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
166 CPU implementer : 0x41
167 CPU architecture: 8
168 CPU variant : 0x0
169 CPU part : 0xd05
171 processor : 1
172 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
173 CPU implementer : 0x53
174 CPU architecture: 8
177 // Verify default for Exynos.
178 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
179 "CPU variant : 0xc\n"
180 "CPU part : 0xafe"),
181 "exynos-m3");
182 // Verify Exynos M3.
183 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
184 "CPU variant : 0x1\n"
185 "CPU part : 0x002"),
186 "exynos-m3");
187 // Verify Exynos M4.
188 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
189 "CPU variant : 0x1\n"
190 "CPU part : 0x003"),
191 "exynos-m4");
193 const std::string ThunderX2T99ProcCpuInfo = R"(
194 processor : 0
195 BogoMIPS : 400.00
196 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
197 CPU implementer : 0x43
198 CPU architecture: 8
199 CPU variant : 0x1
200 CPU part : 0x0af
203 // Verify different versions of ThunderX2T99.
204 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
205 "CPU implementer : 0x42\n"
206 "CPU part : 0x516"),
207 "thunderx2t99");
209 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
210 "CPU implementer : 0x42\n"
211 "CPU part : 0x0516"),
212 "thunderx2t99");
214 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
215 "CPU implementer : 0x43\n"
216 "CPU part : 0x516"),
217 "thunderx2t99");
219 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
220 "CPU implementer : 0x43\n"
221 "CPU part : 0x0516"),
222 "thunderx2t99");
224 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
225 "CPU implementer : 0x42\n"
226 "CPU part : 0xaf"),
227 "thunderx2t99");
229 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
230 "CPU implementer : 0x42\n"
231 "CPU part : 0x0af"),
232 "thunderx2t99");
234 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
235 "CPU implementer : 0x43\n"
236 "CPU part : 0xaf"),
237 "thunderx2t99");
239 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
240 "CPU implementer : 0x43\n"
241 "CPU part : 0x0af"),
242 "thunderx2t99");
244 // Verify ThunderXT88.
245 const std::string ThunderXT88ProcCpuInfo = R"(
246 processor : 0
247 BogoMIPS : 200.00
248 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
249 CPU implementer : 0x43
250 CPU architecture: 8
251 CPU variant : 0x1
252 CPU part : 0x0a1
255 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
256 "CPU implementer : 0x43\n"
257 "CPU part : 0x0a1"),
258 "thunderxt88");
260 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
261 "CPU implementer : 0x43\n"
262 "CPU part : 0xa1"),
263 "thunderxt88");
265 // Verify HiSilicon processors.
266 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n"
267 "CPU part : 0xd01"),
268 "tsv110");
270 // Verify A64FX.
271 const std::string A64FXProcCpuInfo = R"(
272 processor : 0
273 BogoMIPS : 200.00
274 Features : fp asimd evtstrm sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm fcma dcpop sve
275 CPU implementer : 0x46
276 CPU architecture: 8
277 CPU variant : 0x1
278 CPU part : 0x001
281 EXPECT_EQ(sys::detail::getHostCPUNameForARM(A64FXProcCpuInfo), "a64fx");
283 // Verify Nvidia Carmel.
284 const std::string CarmelProcCpuInfo = R"(
285 processor : 0
286 model name : ARMv8 Processor rev 0 (v8l)
287 BogoMIPS : 62.50
288 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm dcpop
289 CPU implementer : 0x4e
290 CPU architecture: 8
291 CPU variant : 0x0
292 CPU part : 0x004
293 CPU revision : 0
296 EXPECT_EQ(sys::detail::getHostCPUNameForARM(CarmelProcCpuInfo), "carmel");
298 // Snapdragon mixed implementer quirk
299 const std::string Snapdragon865ProcCPUInfo = R"(
300 processor : 0
301 BogoMIPS : 38.40
302 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
303 CPU implementer : 0x51
304 CPU architecture: 8
305 CPU variant : 0xd
306 CPU part : 0x805
307 CPU revision : 14
308 processor : 1
309 processor : 2
310 processor : 3
311 processor : 4
312 processor : 5
313 processor : 6
314 BogoMIPS : 38.40
315 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
316 CPU implementer : 0x41
317 CPU architecture: 8
318 CPU variant : 0x1
319 CPU part : 0xd0d
320 CPU revision : 0
322 EXPECT_EQ(sys::detail::getHostCPUNameForARM(Snapdragon865ProcCPUInfo), "cortex-a77");
325 TEST(getLinuxHostCPUName, s390x) {
326 SmallVector<std::string> ModelIDs(
327 {"3931", "8561", "3906", "2964", "2827", "2817", "2097", "2064"});
328 SmallVector<std::string> VectorSupport({"", "vx"});
329 SmallVector<StringRef> ExpectedCPUs;
331 // Model Id: 3931
332 ExpectedCPUs.push_back("zEC12");
333 ExpectedCPUs.push_back("z16");
335 // Model Id: 8561
336 ExpectedCPUs.push_back("zEC12");
337 ExpectedCPUs.push_back("z15");
339 // Model Id: 3906
340 ExpectedCPUs.push_back("zEC12");
341 ExpectedCPUs.push_back("z14");
343 // Model Id: 2964
344 ExpectedCPUs.push_back("zEC12");
345 ExpectedCPUs.push_back("z13");
347 // Model Id: 2827
348 ExpectedCPUs.push_back("zEC12");
349 ExpectedCPUs.push_back("zEC12");
351 // Model Id: 2817
352 ExpectedCPUs.push_back("z196");
353 ExpectedCPUs.push_back("z196");
355 // Model Id: 2097
356 ExpectedCPUs.push_back("z10");
357 ExpectedCPUs.push_back("z10");
359 // Model Id: 2064
360 ExpectedCPUs.push_back("generic");
361 ExpectedCPUs.push_back("generic");
363 const std::string DummyBaseVectorInfo =
364 "features : esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs "
365 "te ";
366 const std::string DummyBaseMachineInfo =
367 "processor 0: version = FF, identification = 059C88, machine = ";
369 int CheckIndex = 0;
370 for (size_t I = 0; I < ModelIDs.size(); I++) {
371 for (size_t J = 0; J < VectorSupport.size(); J++) {
372 const std::string DummyCPUInfo = DummyBaseVectorInfo + VectorSupport[J] +
373 "\n" + DummyBaseMachineInfo +
374 ModelIDs[I];
375 EXPECT_EQ(sys::detail::getHostCPUNameForS390x(DummyCPUInfo),
376 ExpectedCPUs[CheckIndex++]);
381 TEST(getLinuxHostCPUName, RISCV) {
382 const StringRef SifiveU74MCProcCPUInfo = R"(
383 processor : 0
384 hart : 2
385 isa : rv64imafdc
386 mmu : sv39
387 uarch : sifive,u74-mc
389 EXPECT_EQ(sys::detail::getHostCPUNameForRISCV(SifiveU74MCProcCPUInfo),
390 "sifive-u74");
391 EXPECT_EQ(
392 sys::detail::getHostCPUNameForRISCV("uarch : sifive,bullet0\n"),
393 "sifive-u74");
396 static bool runAndGetCommandOutput(
397 const char *ExePath, ArrayRef<llvm::StringRef> argv,
398 std::unique_ptr<char[]> &Buffer, off_t &Size) {
399 bool Success = false;
400 [ExePath, argv, &Buffer, &Size, &Success] {
401 using namespace llvm::sys;
402 SmallString<128> TestDirectory;
403 ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
405 SmallString<128> OutputFile(TestDirectory);
406 path::append(OutputFile, "out");
407 StringRef OutputPath = OutputFile.str();
409 const Optional<StringRef> Redirects[] = {
410 /*STDIN=*/None, /*STDOUT=*/OutputPath, /*STDERR=*/None};
411 int RetCode = ExecuteAndWait(ExePath, argv, /*env=*/llvm::None, Redirects);
412 ASSERT_EQ(0, RetCode);
414 int FD = 0;
415 ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
416 Size = ::lseek(FD, 0, SEEK_END);
417 ASSERT_NE(-1, Size);
418 ::lseek(FD, 0, SEEK_SET);
419 Buffer = std::make_unique<char[]>(Size);
420 ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
421 ::close(FD);
423 ASSERT_NO_ERROR(fs::remove(OutputPath));
424 ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
425 Success = true;
426 }();
427 return Success;
430 TEST_F(HostTest, DummyRunAndGetCommandOutputUse) {
431 // Suppress defined-but-not-used warnings when the tests using the helper are
432 // disabled.
433 (void)&runAndGetCommandOutput;
436 TEST_F(HostTest, getMacOSHostVersion) {
437 llvm::Triple HostTriple(llvm::sys::getProcessTriple());
438 if (!HostTriple.isMacOSX())
439 GTEST_SKIP();
441 const char *SwVersPath = "/usr/bin/sw_vers";
442 StringRef argv[] = {SwVersPath, "-productVersion"};
443 std::unique_ptr<char[]> Buffer;
444 off_t Size;
445 ASSERT_EQ(runAndGetCommandOutput(SwVersPath, argv, Buffer, Size), true);
446 StringRef SystemVersionStr = StringRef(Buffer.get(), Size).rtrim();
448 // Ensure that the two versions match.
449 VersionTuple SystemVersion;
450 ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersionStr))
451 .getMacOSXVersion(SystemVersion),
452 true);
453 VersionTuple HostVersion;
454 ASSERT_EQ(HostTriple.getMacOSXVersion(HostVersion), true);
456 if (SystemVersion.getMajor() > 10) {
457 // Don't compare the 'Minor' and 'Micro' versions, as they're always '0' for
458 // the 'Darwin' triples on 11.x.
459 ASSERT_EQ(SystemVersion.getMajor(), HostVersion.getMajor());
460 } else {
461 // Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
462 // triples.
463 ASSERT_EQ(SystemVersion.getMajor(), HostVersion.getMajor());
464 ASSERT_EQ(SystemVersion.getMinor(), HostVersion.getMinor());
468 // Helper to return AIX system version. Must return void to use ASSERT_*.
469 static void getAIXSystemVersion(VersionTuple &SystemVersion) {
470 const char *ExePath = "/usr/bin/oslevel";
471 StringRef argv[] = {ExePath};
472 std::unique_ptr<char[]> Buffer;
473 off_t Size;
474 ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
475 StringRef SystemVersionStr = StringRef(Buffer.get(), Size).rtrim();
477 SystemVersion =
478 llvm::Triple((Twine("powerpc-ibm-aix") + SystemVersionStr))
479 .getOSVersion();
482 TEST_F(HostTest, AIXHostVersionDetect) {
483 llvm::Triple HostTriple(llvm::sys::getProcessTriple());
484 if (HostTriple.getOS() != Triple::AIX)
485 GTEST_SKIP();
487 llvm::Triple ConfiguredHostTriple(LLVM_HOST_TRIPLE);
488 ASSERT_EQ(ConfiguredHostTriple.getOS(), Triple::AIX);
490 VersionTuple SystemVersion;
491 getAIXSystemVersion(SystemVersion);
493 // Ensure that the host triple version (major) and release (minor) numbers,
494 // unless explicitly configured, match with those of the current system.
495 auto SysMajor = SystemVersion.getMajor();
496 auto SysMinor = SystemVersion.getMinor();
497 VersionTuple HostVersion = HostTriple.getOSVersion();
498 if (ConfiguredHostTriple.getOSMajorVersion()) {
499 // Explicitly configured, force a match. We do it this way so the
500 // asserts are always executed.
501 SysMajor = HostVersion.getMajor();
502 SysMinor = HostVersion.getMinor();
504 ASSERT_EQ(SysMajor, HostVersion.getMajor());
505 ASSERT_EQ(SysMinor, HostVersion.getMinor());
508 TEST_F(HostTest, AIXTargetVersionDetect) {
509 llvm::Triple TargetTriple(llvm::sys::getDefaultTargetTriple());
510 if (TargetTriple.getOS() != Triple::AIX)
511 GTEST_SKIP();
513 // Ensure that the target triple version (major) and release (minor) numbers
514 // match with those of the current system.
515 llvm::Triple ConfiguredTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
516 if (ConfiguredTargetTriple.getOSMajorVersion())
517 GTEST_SKIP(); // The version was configured explicitly; skip.
519 VersionTuple SystemVersion;
520 getAIXSystemVersion(SystemVersion);
521 VersionTuple TargetVersion = TargetTriple.getOSVersion();
522 ASSERT_EQ(SystemVersion.getMajor(), TargetVersion.getMajor());
523 ASSERT_EQ(SystemVersion.getMinor(), TargetVersion.getMinor());
526 TEST_F(HostTest, AIXHostCPUDetect) {
527 llvm::Triple HostTriple(llvm::sys::getProcessTriple());
528 if (HostTriple.getOS() != Triple::AIX)
529 GTEST_SKIP();
531 // Return a value based on the current processor implementation mode.
532 const char *ExePath = "/usr/sbin/getsystype";
533 StringRef argv[] = {ExePath, "-i"};
534 std::unique_ptr<char[]> Buffer;
535 off_t Size;
536 ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
537 StringRef CPU(Buffer.get(), Size);
538 StringRef MCPU = StringSwitch<const char *>(CPU)
539 .Case("POWER 4\n", "pwr4")
540 .Case("POWER 5\n", "pwr5")
541 .Case("POWER 6\n", "pwr6")
542 .Case("POWER 7\n", "pwr7")
543 .Case("POWER 8\n", "pwr8")
544 .Case("POWER 9\n", "pwr9")
545 .Case("POWER 10\n", "pwr10")
546 .Default("unknown");
548 StringRef HostCPU = sys::getHostCPUName();
550 // Just do the comparison on the base implementation mode.
551 if (HostCPU == "970")
552 HostCPU = StringRef("pwr4");
553 else
554 HostCPU = HostCPU.rtrim('x');
556 EXPECT_EQ(HostCPU, MCPU);