[llvm] [BOLT][RISCV] Add basic RISC-V initialization support for unit tests (PR #222883)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 01:31:38 PDT 2026


https://github.com/Thrrreeee created https://github.com/llvm/llvm-project/pull/222883

This change addresses the uninstantiated test suite failures in RISC-V-only builds discussed in #217604. That PR proposed a temporary workaround using GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.

Add the basic setup needed to instantiate and initialize the existing test suites for riscv64, including the correct ELF machine type and subtarget features, and remove the temporary allowances.

>From 2eb1a074ee4c51b5a201843732ed7ec6ff006abf Mon Sep 17 00:00:00 2001
From: shijinrui <shijinrui at bytedance.com>
Date: Fri, 11 Sep 2026 16:27:06 +0800
Subject: [PATCH] [BOLT][RISCV] Add basic RISC-V initialization support for
 unit tests

---
 bolt/unittests/Core/BinaryContext.cpp  | 40 +++++++++++++++++++------
 bolt/unittests/Core/MCPlusBuilder.cpp  |  8 ++---
 bolt/unittests/Core/MemoryMaps.cpp     | 40 +++++++++++++++++++------
 bolt/unittests/Profile/PerfScripts.cpp | 41 ++++++++++++++++++++------
 4 files changed, 96 insertions(+), 33 deletions(-)

diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index c7c23ba33dcf9..418111f68ac2d 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -10,8 +10,10 @@
 #include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -45,17 +47,34 @@ struct BinaryContextTester : public testing::TestWithParam<Triple::ArchType> {
     ELF64LE::Ehdr *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(ElfBuf);
     EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64;
     EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB;
-    EHdr->e_machine = GetParam() == Triple::aarch64 ? EM_AARCH64 : EM_X86_64;
+    switch (GetParam()) {
+    case Triple::aarch64:
+      EHdr->e_machine = EM_AARCH64;
+      break;
+    case Triple::riscv64:
+      EHdr->e_machine = EM_RISCV;
+      break;
+    case Triple::x86_64:
+      EHdr->e_machine = EM_X86_64;
+      break;
+    default:
+      llvm_unreachable("Unsupported architecture");
+      break;
+    }
     MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF");
     ObjFile = cantFail(ObjectFile::createObjectFile(Source));
   }
 
   void initializeBOLT() {
-    Relocation::Arch = ObjFile->makeTriple().getArch();
+    const Triple TheTriple = GetParam();
+    Relocation::Arch = TheTriple.getArch();
+    // Minimal test ELFs have no RISC-V attributes. RISC-V needs an empty
+    // feature set for +relax, while other targets reject a non-null one.
+    SubtargetFeatures Features;
     BC = cantFail(BinaryContext::createBinaryContext(
-        ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
-        ObjFile->getFileName(), nullptr, true, DWARFContext::create(*ObjFile),
-        {llvm::outs(), llvm::errs()}));
+        TheTriple, std::make_shared<orc::SymbolStringPool>(),
+        ObjFile->getFileName(), TheTriple.isRISCV() ? &Features : nullptr, true,
+        DWARFContext::create(*ObjFile), {llvm::outs(), llvm::errs()}));
     ASSERT_FALSE(!BC);
   }
 
@@ -72,6 +91,13 @@ INSTANTIATE_TEST_SUITE_P(X86, BinaryContextTester,
 
 #endif
 
+#ifdef RISCV_AVAILABLE
+
+INSTANTIATE_TEST_SUITE_P(RISCV, BinaryContextTester,
+                         ::testing::Values(Triple::riscv64));
+
+#endif
+
 #ifdef AARCH64_AVAILABLE
 
 INSTANTIATE_TEST_SUITE_P(AArch64, BinaryContextTester,
@@ -270,7 +296,3 @@ TEST_P(BinaryContextTester, BaseAddressSegmentsSmallerThanAlignment) {
   ASSERT_TRUE(BaseAddress.has_value());
   ASSERT_EQ(*BaseAddress, 0xaaaaaaaa0000ULL);
 }
-
-#if !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BinaryContextTester);
-#endif // !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp
index ca24a43019605..18e08bd00444f 100644
--- a/bolt/unittests/Core/MCPlusBuilder.cpp
+++ b/bolt/unittests/Core/MCPlusBuilder.cpp
@@ -41,7 +41,7 @@ struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
   void SetUp() override {
     initalizeLLVM();
     prepareElf();
-    initializeBolt();
+    initializeBOLT();
   }
 
 protected:
@@ -80,7 +80,7 @@ struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
     ObjFile = cantFail(ObjectFile::createObjectFile(Source));
   }
 
-  void initializeBolt() {
+  void initializeBOLT() {
     const Triple TheTriple = GetParam();
     Relocation::Arch = TheTriple.getArch();
     // Minimal test ELFs have no RISC-V attributes. RISC-V needs an empty
@@ -1121,7 +1121,3 @@ TEST_P(MCPlusBuilderTester, Annotation) {
   ASSERT_DEATH(BC->MIB->addEHInfo(Inst, MCPlus::MCLandingPad(LPSymbol, Value)),
                "annotation value out of range");
 }
-
-#if !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MCPlusBuilderTester);
-#endif // !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
diff --git a/bolt/unittests/Core/MemoryMaps.cpp b/bolt/unittests/Core/MemoryMaps.cpp
index a53bb4c6240a8..24b35f1c2db23 100644
--- a/bolt/unittests/Core/MemoryMaps.cpp
+++ b/bolt/unittests/Core/MemoryMaps.cpp
@@ -11,7 +11,9 @@
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
@@ -54,17 +56,34 @@ struct MemoryMapsTester : public testing::TestWithParam<Triple::ArchType> {
     ELF64LE::Ehdr *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(ElfBuf);
     EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64;
     EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB;
-    EHdr->e_machine = GetParam() == Triple::aarch64 ? EM_AARCH64 : EM_X86_64;
+    switch (GetParam()) {
+    case Triple::aarch64:
+      EHdr->e_machine = EM_AARCH64;
+      break;
+    case Triple::riscv64:
+      EHdr->e_machine = EM_RISCV;
+      break;
+    case Triple::x86_64:
+      EHdr->e_machine = EM_X86_64;
+      break;
+    default:
+      llvm_unreachable("Unsupported architecture");
+      break;
+    }
     MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF");
     ObjFile = cantFail(ObjectFile::createObjectFile(Source));
   }
 
   void initializeBOLT() {
-    Relocation::Arch = ObjFile->makeTriple().getArch();
+    const Triple TheTriple = GetParam();
+    Relocation::Arch = TheTriple.getArch();
+    // Minimal test ELFs have no RISC-V attributes. RISC-V needs an empty
+    // feature set for +relax, while other targets reject a non-null one.
+    SubtargetFeatures Features;
     BC = cantFail(BinaryContext::createBinaryContext(
-        ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
-        ObjFile->getFileName(), nullptr, true, DWARFContext::create(*ObjFile),
-        {llvm::outs(), llvm::errs()}));
+        TheTriple, std::make_shared<orc::SymbolStringPool>(),
+        ObjFile->getFileName(), TheTriple.isRISCV() ? &Features : nullptr, true,
+        DWARFContext::create(*ObjFile), {llvm::outs(), llvm::errs()}));
     ASSERT_FALSE(!BC);
   }
 
@@ -92,6 +111,13 @@ INSTANTIATE_TEST_SUITE_P(X86, MemoryMapsTester,
 
 #endif
 
+#ifdef RISCV_AVAILABLE
+
+INSTANTIATE_TEST_SUITE_P(RISCV, MemoryMapsTester,
+                         ::testing::Values(Triple::riscv64));
+
+#endif
+
 #ifdef AARCH64_AVAILABLE
 
 INSTANTIATE_TEST_SUITE_P(AArch64, MemoryMapsTester,
@@ -176,7 +202,3 @@ TEST_P(MemoryMapsTester, MultipleSegmentsMismatchedBaseAddress) {
       "Base address on multiple segment mappings should match");
   sys::fs::remove(Path);
 }
-
-#if !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryMapsTester);
-#endif // !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
diff --git a/bolt/unittests/Profile/PerfScripts.cpp b/bolt/unittests/Profile/PerfScripts.cpp
index bf7560ad67434..1aebb90fe0feb 100644
--- a/bolt/unittests/Profile/PerfScripts.cpp
+++ b/bolt/unittests/Profile/PerfScripts.cpp
@@ -11,7 +11,9 @@
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 #include <gmock/gmock.h>
@@ -56,17 +58,35 @@ struct PerfScriptTestHelper : public testing::TestWithParam<Triple::ArchType> {
     ELF64LE::Ehdr *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(ElfBuf);
     EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64;
     EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB;
-    EHdr->e_machine = GetParam() == Triple::aarch64 ? EM_AARCH64 : EM_X86_64;
+    switch (GetParam()) {
+    case Triple::aarch64:
+      EHdr->e_machine = EM_AARCH64;
+      break;
+    case Triple::riscv64:
+      EHdr->e_machine = EM_RISCV;
+      break;
+    case Triple::x86_64:
+      EHdr->e_machine = EM_X86_64;
+      break;
+    default:
+      llvm_unreachable("Unsupported architecture");
+      break;
+    }
     MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF");
     ObjFile = cantFail(ObjectFile::createObjectFile(Source));
   }
 
   void initializeBOLT() {
-    Relocation::Arch = ObjFile->makeTriple().getArch();
+    const Triple TheTriple = GetParam();
+    Relocation::Arch = TheTriple.getArch();
+    // Minimal test ELFs have no RISC-V attributes. RISC-V needs an empty
+    // feature set for +relax, while other targets reject a non-null one.
+    SubtargetFeatures Features;
     BC = cantFail(BinaryContext::createBinaryContext(
-        ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
-        ObjFile->getFileName(), nullptr, /*IsPIC*/ false,
-        DWARFContext::create(*ObjFile), {llvm::outs(), llvm::errs()}));
+        TheTriple, std::make_shared<orc::SymbolStringPool>(),
+        ObjFile->getFileName(), TheTriple.isRISCV() ? &Features : nullptr,
+        /*IsPIC*/ false, DWARFContext::create(*ObjFile),
+        {llvm::outs(), llvm::errs()}));
     ASSERT_FALSE(!BC);
   }
 
@@ -136,6 +156,13 @@ INSTANTIATE_TEST_SUITE_P(X86, PerfScriptTestHelper,
 
 #endif
 
+#ifdef RISCV_AVAILABLE
+
+INSTANTIATE_TEST_SUITE_P(RISCV, PerfScriptTestHelper,
+                         ::testing::Values(Triple::riscv64));
+
+#endif
+
 #ifdef AARCH64_AVAILABLE
 
 INSTANTIATE_TEST_SUITE_P(AArch64, PerfScriptTestHelper,
@@ -240,7 +267,3 @@ TEST_P(PerfScriptTestHelper, ParseAndCheckFileHeader) {
   // should be 'size == 3' after the parsing this dummy MainEvents.
   parseAndCheckPerfScriptProfile(Buffer, Pid, 3);
 }
-
-#if !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PerfScriptTestHelper);
-#endif // !defined(X86_AVAILABLE) && !defined(AARCH64_AVAILABLE)



More information about the llvm-commits mailing list