summaryrefslogtreecommitdiff
path: root/bolt/unittests
diff options
context:
space:
mode:
authorVladislav Khmelevsky <och95@yandex.ru>2022-01-28 01:04:31 +0300
committerVladislav Khmelevsky <och95@yandex.ru>2022-01-28 01:24:35 +0300
commite900f0584e904e884207e40c80a8126824ef4c41 (patch)
treed84d86677069e87d193d2efb3941cbbae1d744ac /bolt/unittests
parent11c2ef5638c3cff489744f1d342cd92e2a864614 (diff)
downloadllvm-e900f0584e904e884207e40c80a8126824ef4c41.tar.gz
[BOLT] Fix AARCH64 registers aliasing
The aarch64 platform has special registers like X0_X1_X2_X3_X4_X5_X6_X7. Using the downwards propagation this register will become a super register for all X0..X7 and its super registers which is not right. This patch replaces the downwards propagation with caching all the aliases using MCRegAliasIterator. Vladislav Khmelevsky, Advanced Software Technology Lab, Huawei Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D117394
Diffstat (limited to 'bolt/unittests')
-rw-r--r--bolt/unittests/CMakeLists.txt2
-rw-r--r--bolt/unittests/Core/CMakeLists.txt27
-rw-r--r--bolt/unittests/Core/MCPlusBuilder.cpp112
3 files changed, 141 insertions, 0 deletions
diff --git a/bolt/unittests/CMakeLists.txt b/bolt/unittests/CMakeLists.txt
index 5b0f75d1c88c..b5c7f17ec1d6 100644
--- a/bolt/unittests/CMakeLists.txt
+++ b/bolt/unittests/CMakeLists.txt
@@ -4,3 +4,5 @@ set_target_properties(BoltUnitTests PROPERTIES FOLDER "BOLT tests")
function(add_bolt_unittest test_dirname)
add_unittest(BoltUnitTests ${test_dirname} ${ARGN})
endfunction()
+
+add_subdirectory(Core)
diff --git a/bolt/unittests/Core/CMakeLists.txt b/bolt/unittests/Core/CMakeLists.txt
new file mode 100644
index 000000000000..034831a54e67
--- /dev/null
+++ b/bolt/unittests/Core/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(LLVM_LINK_COMPONENTS
+ BOLTRewrite
+ )
+
+add_bolt_unittest(CoreTests
+ MCPlusBuilder.cpp
+ )
+
+string(FIND "${LLVM_TARGETS_TO_BUILD}" "AArch64" POSITION)
+if (NOT ${POSITION} EQUAL -1)
+ include_directories(
+ ${CMAKE_SOURCE_DIR}/lib/Target/AArch64
+ ${CMAKE_BINARY_DIR}/lib/Target/AArch64
+ )
+
+ target_compile_definitions(CoreTests PRIVATE AARCH64_AVAILABLE)
+endif()
+
+string(FIND "${LLVM_TARGETS_TO_BUILD}" "X86" POSITION)
+if (NOT ${POSITION} EQUAL -1)
+ include_directories(
+ ${LLVM_MAIN_SRC_DIR}/lib/Target/X86
+ ${LLVM_BINARY_DIR}/lib/Target/X86
+ )
+
+ target_compile_definitions(CoreTests PRIVATE X86_AVAILABLE)
+endif()
diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp
new file mode 100644
index 000000000000..ec881bf4ead1
--- /dev/null
+++ b/bolt/unittests/Core/MCPlusBuilder.cpp
@@ -0,0 +1,112 @@
+#ifdef AARCH64_AVAILABLE
+#include "AArch64Subtarget.h"
+#endif // AARCH64_AVAILABLE
+
+#ifdef X86_AVAILABLE
+#include "X86Subtarget.h"
+#endif // X86_AVAILABLE
+
+#include "bolt/Rewrite/RewriteInstance.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::ELF;
+using namespace bolt;
+
+namespace {
+struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
+ void SetUp() override {
+ initalizeLLVM();
+ prepareElf();
+ initializeBolt();
+ }
+
+protected:
+ void initalizeLLVM() {
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllAsmPrinters();
+ }
+
+ void prepareElf() {
+ memcpy(ElfBuf, "\177ELF", 4);
+ 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;
+ MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF");
+ ObjFile = cantFail(ObjectFile::createObjectFile(Source));
+ }
+
+ void initializeBolt() {
+ BC = BinaryContext::createBinaryContext(
+ ObjFile.get(), true, DWARFContext::create(*ObjFile.get()));
+ ASSERT_FALSE(!BC);
+ BC->initializeTarget(std::unique_ptr<MCPlusBuilder>(createMCPlusBuilder(
+ GetParam(), BC->MIA.get(), BC->MII.get(), BC->MRI.get())));
+ }
+
+ void testRegAliases(Triple::ArchType Arch, uint64_t Register,
+ uint64_t *Aliases, size_t Count,
+ bool OnlySmaller = false) {
+ if (GetParam() != Arch)
+ GTEST_SKIP();
+
+ const BitVector &BV = BC->MIB->getAliases(Register, OnlySmaller);
+ ASSERT_EQ(BV.count(), Count);
+ for (size_t I = 0; I < Count; ++I)
+ ASSERT_TRUE(BV[Aliases[I]]);
+ }
+
+ char ElfBuf[sizeof(typename ELF64LE::Ehdr)] = {};
+ std::unique_ptr<ObjectFile> ObjFile;
+ std::unique_ptr<BinaryContext> BC;
+};
+} // namespace
+
+#ifdef AARCH64_AVAILABLE
+
+INSTANTIATE_TEST_SUITE_P(AArch64, MCPlusBuilderTester,
+ ::testing::Values(Triple::aarch64));
+
+TEST_P(MCPlusBuilderTester, AliasX0) {
+ uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0, AArch64::W0_W1,
+ AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7};
+ size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
+ testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count);
+}
+
+TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
+ uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0};
+ size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
+ testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count, true);
+}
+
+#endif // AARCH64_AVAILABLE
+
+#ifdef X86_AVAILABLE
+
+INSTANTIATE_TEST_SUITE_P(X86, MCPlusBuilderTester,
+ ::testing::Values(Triple::x86_64));
+
+TEST_P(MCPlusBuilderTester, AliasAX) {
+ uint64_t AliasesAX[] = {X86::RAX, X86::EAX, X86::AX, X86::AL, X86::AH};
+ size_t AliasesAXCount = sizeof(AliasesAX) / sizeof(*AliasesAX);
+ testRegAliases(Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount);
+}
+
+TEST_P(MCPlusBuilderTester, AliasSmallerAX) {
+ uint64_t AliasesAX[] = {X86::AX, X86::AL, X86::AH};
+ size_t AliasesAXCount = sizeof(AliasesAX) / sizeof(*AliasesAX);
+ testRegAliases(Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount, true);
+}
+
+#endif // X86_AVAILABLE