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 //===----------------------------------------------------------------------===//
8 
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"
17 
18 #include "gtest/gtest.h"
19 
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 {                                                                     \
29   }
30 
31 using namespace llvm;
32 
33 class HostTest : public testing::Test {
34   Triple Host;
35 
36 protected:
isSupportedArchAndOS()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.isPPC64() && Host.isOSLinux()) ||
44            (Host.isSystemZ() && (Host.isOSLinux() || Host.isOSzOS()));
45   }
46 
HostTest()47   HostTest() : Host(Triple::normalize(sys::getProcessTriple())) {}
48 };
49 
TEST_F(HostTest,NumPhysicalCoresSupported)50 TEST_F(HostTest, NumPhysicalCoresSupported) {
51   if (!isSupportedArchAndOS())
52     GTEST_SKIP();
53   int Num = sys::getHostNumPhysicalCores();
54   ASSERT_GT(Num, 0);
55 }
56 
TEST_F(HostTest,NumPhysicalCoresUnsupported)57 TEST_F(HostTest, NumPhysicalCoresUnsupported) {
58   if (isSupportedArchAndOS())
59     GTEST_SKIP();
60   int Num = sys::getHostNumPhysicalCores();
61   ASSERT_EQ(Num, -1);
62 }
63 
TEST(getLinuxHostCPUName,ARM)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
75 
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
85 
86 Hardware        : Generic OMAP4 (Flattened Device Tree)
87 Revision        : 0000
88 Serial          : 0000000000000000
89 )";
90 
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");
103 }
104 
TEST(getLinuxHostCPUName,AArch64)105 TEST(getLinuxHostCPUName, AArch64) {
106   EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
107                                               "CPU part        : 0xd03"),
108             "cortex-a53");
109 
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");
135 
136   EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0xc0\n"
137                                               "CPU part        : 0xac3"),
138             "ampere1");
139 
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
155 
156 Hardware        : Qualcomm Technologies, Inc MSM8992
157 )";
158 
159   EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo),
160             "cortex-a53");
161 
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
170 
171 processor       : 1
172 Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
173 CPU implementer : 0x53
174 CPU architecture: 8
175 )";
176 
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");
192 
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
201 )";
202 
203   // Verify different versions of ThunderX2T99.
204   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
205                                               "CPU implementer	: 0x42\n"
206                                               "CPU part	: 0x516"),
207             "thunderx2t99");
208 
209   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
210                                               "CPU implementer	: 0x42\n"
211                                               "CPU part	: 0x0516"),
212             "thunderx2t99");
213 
214   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
215                                               "CPU implementer	: 0x43\n"
216                                               "CPU part	: 0x516"),
217             "thunderx2t99");
218 
219   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
220                                               "CPU implementer	: 0x43\n"
221                                               "CPU part	: 0x0516"),
222             "thunderx2t99");
223 
224   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
225                                               "CPU implementer	: 0x42\n"
226                                               "CPU part	: 0xaf"),
227             "thunderx2t99");
228 
229   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
230                                               "CPU implementer	: 0x42\n"
231                                               "CPU part	: 0x0af"),
232             "thunderx2t99");
233 
234   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
235                                               "CPU implementer	: 0x43\n"
236                                               "CPU part	: 0xaf"),
237             "thunderx2t99");
238 
239   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
240                                               "CPU implementer	: 0x43\n"
241                                               "CPU part	: 0x0af"),
242             "thunderx2t99");
243 
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
253 )";
254 
255   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
256                                               "CPU implementer	: 0x43\n"
257                                               "CPU part	: 0x0a1"),
258             "thunderxt88");
259 
260   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
261                                               "CPU implementer	: 0x43\n"
262                                               "CPU part	: 0xa1"),
263             "thunderxt88");
264 
265   // Verify HiSilicon processors.
266   EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n"
267                                               "CPU part        : 0xd01"),
268             "tsv110");
269 
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
279 )";
280 
281   EXPECT_EQ(sys::detail::getHostCPUNameForARM(A64FXProcCpuInfo), "a64fx");
282 
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
294 )";
295 
296   EXPECT_EQ(sys::detail::getHostCPUNameForARM(CarmelProcCpuInfo), "carmel");
297 
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
321 )";
322   EXPECT_EQ(sys::detail::getHostCPUNameForARM(Snapdragon865ProcCPUInfo), "cortex-a77");
323 }
324 
TEST(getLinuxHostCPUName,s390x)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;
330 
331   // Model Id: 3931
332   ExpectedCPUs.push_back("zEC12");
333   ExpectedCPUs.push_back("z16");
334 
335   // Model Id: 8561
336   ExpectedCPUs.push_back("zEC12");
337   ExpectedCPUs.push_back("z15");
338 
339   // Model Id: 3906
340   ExpectedCPUs.push_back("zEC12");
341   ExpectedCPUs.push_back("z14");
342 
343   // Model Id: 2964
344   ExpectedCPUs.push_back("zEC12");
345   ExpectedCPUs.push_back("z13");
346 
347   // Model Id: 2827
348   ExpectedCPUs.push_back("zEC12");
349   ExpectedCPUs.push_back("zEC12");
350 
351   // Model Id: 2817
352   ExpectedCPUs.push_back("z196");
353   ExpectedCPUs.push_back("z196");
354 
355   // Model Id: 2097
356   ExpectedCPUs.push_back("z10");
357   ExpectedCPUs.push_back("z10");
358 
359   // Model Id: 2064
360   ExpectedCPUs.push_back("generic");
361   ExpectedCPUs.push_back("generic");
362 
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 = ";
368 
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++]);
377     }
378   }
379 }
380 
TEST(getLinuxHostCPUName,RISCV)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
388 )";
389   EXPECT_EQ(sys::detail::getHostCPUNameForRISCV(SifiveU74MCProcCPUInfo),
390             "sifive-u74");
391   EXPECT_EQ(
392       sys::detail::getHostCPUNameForRISCV("uarch           : sifive,bullet0\n"),
393       "sifive-u74");
394 }
395 
runAndGetCommandOutput(const char * ExePath,ArrayRef<llvm::StringRef> argv,std::unique_ptr<char[]> & Buffer,off_t & Size)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));
404 
405     SmallString<128> OutputFile(TestDirectory);
406     path::append(OutputFile, "out");
407     StringRef OutputPath = OutputFile.str();
408 
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);
413 
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);
422 
423     ASSERT_NO_ERROR(fs::remove(OutputPath));
424     ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
425     Success = true;
426   }();
427   return Success;
428 }
429 
TEST_F(HostTest,DummyRunAndGetCommandOutputUse)430 TEST_F(HostTest, DummyRunAndGetCommandOutputUse) {
431   // Suppress defined-but-not-used warnings when the tests using the helper are
432   // disabled.
433   (void)&runAndGetCommandOutput;
434 }
435 
TEST_F(HostTest,getMacOSHostVersion)436 TEST_F(HostTest, getMacOSHostVersion) {
437   llvm::Triple HostTriple(llvm::sys::getProcessTriple());
438   if (!HostTriple.isMacOSX())
439     GTEST_SKIP();
440 
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();
447 
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);
455 
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());
465   }
466 }
467 
468 // Helper to return AIX system version. Must return void to use ASSERT_*.
getAIXSystemVersion(VersionTuple & SystemVersion)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();
476 
477   SystemVersion =
478       llvm::Triple((Twine("powerpc-ibm-aix") + SystemVersionStr))
479           .getOSVersion();
480 }
481 
TEST_F(HostTest,AIXHostVersionDetect)482 TEST_F(HostTest, AIXHostVersionDetect) {
483   llvm::Triple HostTriple(llvm::sys::getProcessTriple());
484   if (HostTriple.getOS() != Triple::AIX)
485     GTEST_SKIP();
486 
487   llvm::Triple ConfiguredHostTriple(LLVM_HOST_TRIPLE);
488   ASSERT_EQ(ConfiguredHostTriple.getOS(), Triple::AIX);
489 
490   VersionTuple SystemVersion;
491   getAIXSystemVersion(SystemVersion);
492 
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();
503   }
504   ASSERT_EQ(SysMajor, HostVersion.getMajor());
505   ASSERT_EQ(SysMinor, HostVersion.getMinor());
506 }
507 
TEST_F(HostTest,AIXTargetVersionDetect)508 TEST_F(HostTest, AIXTargetVersionDetect) {
509   llvm::Triple TargetTriple(llvm::sys::getDefaultTargetTriple());
510   if (TargetTriple.getOS() != Triple::AIX)
511     GTEST_SKIP();
512 
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.
518 
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());
524 }
525 
TEST_F(HostTest,AIXHostCPUDetect)526 TEST_F(HostTest, AIXHostCPUDetect) {
527   llvm::Triple HostTriple(llvm::sys::getProcessTriple());
528   if (HostTriple.getOS() != Triple::AIX)
529     GTEST_SKIP();
530 
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");
547 
548   StringRef HostCPU = sys::getHostCPUName();
549 
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');
555 
556   EXPECT_EQ(HostCPU, MCPU);
557 }
558