[llvm] [RISCV][llvm-exegesis] Add unittests. NFC (PR #121862)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 6 21:57:26 PST 2025
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/121862
>From c96caf47d53abb03d8c915f63857210e2bdca1db Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 6 Jan 2025 15:31:54 -0800
Subject: [PATCH 1/3] [RISCV][llvm-exegesis] Add unittests. NFC
This is largely a copy paste from Mips or PowerPC.
---
.../tools/llvm-exegesis/CMakeLists.txt | 3 +
.../tools/llvm-exegesis/RISCV/CMakeLists.txt | 21 +++
.../RISCV/SnippetGeneratorTest.cpp | 122 ++++++++++++++++++
.../tools/llvm-exegesis/RISCV/TargetTest.cpp | 62 +++++++++
.../tools/llvm-exegesis/RISCV/TestBase.h | 43 ++++++
5 files changed, 251 insertions(+)
create mode 100644 llvm/unittests/tools/llvm-exegesis/RISCV/CMakeLists.txt
create mode 100644 llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp
create mode 100644 llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
create mode 100644 llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h
diff --git a/llvm/unittests/tools/llvm-exegesis/CMakeLists.txt b/llvm/unittests/tools/llvm-exegesis/CMakeLists.txt
index 3ee3a0dc6b5d04..735f17ab03e612 100644
--- a/llvm/unittests/tools/llvm-exegesis/CMakeLists.txt
+++ b/llvm/unittests/tools/llvm-exegesis/CMakeLists.txt
@@ -53,6 +53,9 @@ endif()
if(LLVM_TARGETS_TO_BUILD MATCHES "Mips")
include(Mips/CMakeLists.txt)
endif()
+if(LLVM_TARGETS_TO_BUILD MATCHES "RISCV")
+ include(RISCV/CMakeLists.txt)
+endif()
include_directories(${exegesis_includes})
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/CMakeLists.txt b/llvm/unittests/tools/llvm-exegesis/RISCV/CMakeLists.txt
new file mode 100644
index 00000000000000..1984819be7738b
--- /dev/null
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_llvm_exegesis_unittest_includes(
+ ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV
+ ${LLVM_BINARY_DIR}/lib/Target/RISCV
+ ${LLVM_MAIN_SRC_DIR}/tools/llvm-exegesis/lib
+ )
+
+add_llvm_exegesis_unittest_link_components(
+ MC
+ MCParser
+ Object
+ Support
+ Symbolize
+ RISCV
+ )
+
+add_llvm_exegesis_unittest_sources(
+ SnippetGeneratorTest.cpp
+ TargetTest.cpp
+ )
+add_llvm_exegesis_unittest_link_libraries(
+ LLVMExegesisRISCV)
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp
new file mode 100644
index 00000000000000..8ea8623e0d373f
--- /dev/null
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp
@@ -0,0 +1,122 @@
+//===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../Common/AssemblerUtils.h"
+#include "LlvmState.h"
+#include "MCInstrDescView.h"
+#include "RISCVInstrInfo.h"
+#include "ParallelSnippetGenerator.h"
+#include "RegisterAliasing.h"
+#include "SerialSnippetGenerator.h"
+#include "TestBase.h"
+
+namespace llvm {
+namespace exegesis {
+namespace {
+
+using testing::AnyOf;
+using testing::ElementsAre;
+using testing::HasSubstr;
+using testing::SizeIs;
+
+MATCHER(IsInvalid, "") { return !arg.isValid(); }
+MATCHER(IsReg, "") { return arg.isReg(); }
+
+template <typename SnippetGeneratorT>
+class RISCVSnippetGeneratorTest : public RISCVTestBase {
+protected:
+ RISCVSnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {}
+
+ std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
+ randomGenerator().seed(0); // Initialize seed.
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
+ auto CodeTemplateOrError = Generator.generateCodeTemplates(
+ &Instr, State.getRATC().emptyRegisters());
+ EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
+ return std::move(CodeTemplateOrError.get());
+ }
+
+ SnippetGeneratorT Generator;
+};
+
+using RISCVSerialSnippetGeneratorTest = RISCVSnippetGeneratorTest<SerialSnippetGenerator>;
+
+using RISCVParallelSnippetGeneratorTest =
+ RISCVSnippetGeneratorTest<ParallelSnippetGenerator>;
+
+TEST_F(RISCVSerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
+ // - ADD
+ // - Op0 Explicit Def RegClass(GPR)
+ // - Op1 Explicit Use RegClass(GPR)
+ // - Op2 Explicit Use RegClass(GPR)
+ // - Var0 [Op0]
+ // - Var1 [Op1]
+ // - Var2 [Op2]
+ // - hasAliasingRegisters
+ const unsigned Opcode = RISCV::ADD;
+ const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
+ ASSERT_THAT(CodeTemplates, SizeIs(1));
+ const auto &CT = CodeTemplates[0];
+ EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
+ ASSERT_THAT(CT.Instructions, SizeIs(1));
+ const InstructionTemplate &IT = CT.Instructions[0];
+ EXPECT_THAT(IT.getOpcode(), Opcode);
+ ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
+ EXPECT_THAT(IT.getVariableValues(),
+ AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
+ ElementsAre(IsReg(), IsReg(), IsInvalid())))
+ << "Op0 is either set to Op1 or to Op2";
+}
+
+TEST_F(RISCVSerialSnippetGeneratorTest,
+ ImplicitSelfDependencyThroughExplicitRegsForbidAll) {
+ // - XOR
+ // - Op0 Explicit Def RegClass(GPR)
+ // - Op1 Explicit Use RegClass(GPR)
+ // - Op2 Explicit Use RegClass(GPR)
+ // - Var0 [Op0]
+ // - Var1 [Op1]
+ // - Var2 [Op2]
+ // - hasAliasingRegisters
+ randomGenerator().seed(0); // Initialize seed.
+ const Instruction &Instr = State.getIC().getInstr(RISCV::XOR);
+ auto AllRegisters = State.getRATC().emptyRegisters();
+ AllRegisters.flip();
+ auto Error =
+ Generator.generateCodeTemplates(&Instr, AllRegisters).takeError();
+ EXPECT_TRUE((bool)Error);
+ consumeError(std::move(Error));
+}
+
+TEST_F(RISCVParallelSnippetGeneratorTest, MemoryUse) {
+ // LB reads from memory.
+ // - LB
+ // - Op0 Explicit Def RegClass(GPR)
+ // - Op1 Explicit Use Memory RegClass(GPR)
+ // - Op2 Explicit Use Memory
+ // - Var0 [Op0]
+ // - Var1 [Op1]
+ // - Var2 [Op2]
+ // - hasMemoryOperands
+ const unsigned Opcode = RISCV::LB;
+ const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
+ ASSERT_THAT(CodeTemplates, SizeIs(1));
+ const auto &CT = CodeTemplates[0];
+ EXPECT_THAT(CT.Info, HasSubstr("instruction has no tied variables"));
+ EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
+ ASSERT_THAT(CT.Instructions,
+ SizeIs(ParallelSnippetGenerator::kMinNumDifferentAddresses));
+ const InstructionTemplate &IT = CT.Instructions[0];
+ EXPECT_THAT(IT.getOpcode(), Opcode);
+ ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
+ EXPECT_EQ(IT.getVariableValues()[1].getReg(), RISCV::X10);
+}
+
+} // namespace
+} // namespace exegesis
+} // namespace llvm
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
new file mode 100644
index 00000000000000..db4a73d994259c
--- /dev/null
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
@@ -0,0 +1,62 @@
+//===-- TargetTest.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Target.h"
+
+#include <cassert>
+#include <memory>
+
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace llvm{
+namespace exegesis {
+
+void InitializeRISCVExegesisTarget();
+
+namespace {
+
+using testing::NotNull;
+using testing::IsEmpty;
+using testing::Not;
+
+constexpr const char kTriple[] = "riscv64-unknown-linux";
+
+class RISCVTargetTest : public ::testing::Test {
+protected:
+ RISCVTargetTest()
+ : ExegesisTarget_(ExegesisTarget::lookup(Triple(kTriple))) {
+ EXPECT_THAT(ExegesisTarget_, NotNull());
+ std::string error;
+ Target_ = TargetRegistry::lookupTarget(kTriple, error);
+ EXPECT_THAT(Target_, NotNull());
+ }
+ static void SetUpTestCase() {
+ LLVMInitializeRISCVTargetInfo();
+ LLVMInitializeRISCVTarget();
+ LLVMInitializeRISCVTargetMC();
+ InitializeRISCVExegesisTarget();
+ }
+
+ const Target *Target_;
+ const ExegesisTarget *const ExegesisTarget_;
+};
+
+TEST_F(RISCVTargetTest, SetRegToConstant) {
+ const std::unique_ptr<MCSubtargetInfo> STI(
+ Target_->createMCSubtargetInfo(kTriple, "generic", ""));
+ const auto Insts = ExegesisTarget_->setRegTo(*STI, RISCV::X10, APInt());
+ EXPECT_THAT(Insts, Not(IsEmpty()));
+}
+
+} // namespace
+} // namespace exegesis
+} // namespace llvm
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h b/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h
new file mode 100644
index 00000000000000..a5a32819ecdf23
--- /dev/null
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h
@@ -0,0 +1,43 @@
+//===-- TestBase.h ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Test fixture common to all RISC-V tests.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_UNITTESTS_TOOLS_LLVMEXEGESIS_RISCV_TESTBASE_H
+#define LLVM_UNITTESTS_TOOLS_LLVMEXEGESIS_RISCV_TESTBASE_H
+
+#include "LlvmState.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace exegesis {
+
+void InitializeRISCVExegesisTarget();
+
+class RISCVTestBase : public ::testing::Test {
+protected:
+ RISCVTestBase()
+ : State(cantFail(LLVMState::Create("riscv64-unknown-linux", "generic-rv64"))) {}
+
+ static void SetUpTestCase() {
+ LLVMInitializeRISCVTargetInfo();
+ LLVMInitializeRISCVTargetMC();
+ LLVMInitializeRISCVTarget();
+ InitializeRISCVExegesisTarget();
+ }
+
+ const LLVMState State;
+};
+
+} // namespace exegesis
+} // namespace llvm
+
+#endif
>From 4dd0cc4aaaff7ece1fccd7363039bca188af61b7 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 6 Jan 2025 17:33:03 -0800
Subject: [PATCH 2/3] fixup! clang-format
---
.../tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp | 8 +++++---
llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp | 7 +++----
llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h | 3 ++-
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp
index 8ea8623e0d373f..22c25d92dfd3eb 100644
--- a/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/SnippetGeneratorTest.cpp
@@ -9,8 +9,8 @@
#include "../Common/AssemblerUtils.h"
#include "LlvmState.h"
#include "MCInstrDescView.h"
-#include "RISCVInstrInfo.h"
#include "ParallelSnippetGenerator.h"
+#include "RISCVInstrInfo.h"
#include "RegisterAliasing.h"
#include "SerialSnippetGenerator.h"
#include "TestBase.h"
@@ -44,12 +44,14 @@ class RISCVSnippetGeneratorTest : public RISCVTestBase {
SnippetGeneratorT Generator;
};
-using RISCVSerialSnippetGeneratorTest = RISCVSnippetGeneratorTest<SerialSnippetGenerator>;
+using RISCVSerialSnippetGeneratorTest =
+ RISCVSnippetGeneratorTest<SerialSnippetGenerator>;
using RISCVParallelSnippetGeneratorTest =
RISCVSnippetGeneratorTest<ParallelSnippetGenerator>;
-TEST_F(RISCVSerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
+TEST_F(RISCVSerialSnippetGeneratorTest,
+ ImplicitSelfDependencyThroughExplicitRegs) {
// - ADD
// - Op0 Explicit Def RegClass(GPR)
// - Op1 Explicit Use RegClass(GPR)
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
index db4a73d994259c..06fa553ea5a9c9 100644
--- a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
@@ -17,23 +17,22 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
-namespace llvm{
+namespace llvm {
namespace exegesis {
void InitializeRISCVExegesisTarget();
namespace {
-using testing::NotNull;
using testing::IsEmpty;
using testing::Not;
+using testing::NotNull;
constexpr const char kTriple[] = "riscv64-unknown-linux";
class RISCVTargetTest : public ::testing::Test {
protected:
- RISCVTargetTest()
- : ExegesisTarget_(ExegesisTarget::lookup(Triple(kTriple))) {
+ RISCVTargetTest() : ExegesisTarget_(ExegesisTarget::lookup(Triple(kTriple))) {
EXPECT_THAT(ExegesisTarget_, NotNull());
std::string error;
Target_ = TargetRegistry::lookupTarget(kTriple, error);
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h b/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h
index a5a32819ecdf23..66748fb9a2ce1b 100644
--- a/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/TestBase.h
@@ -25,7 +25,8 @@ void InitializeRISCVExegesisTarget();
class RISCVTestBase : public ::testing::Test {
protected:
RISCVTestBase()
- : State(cantFail(LLVMState::Create("riscv64-unknown-linux", "generic-rv64"))) {}
+ : State(cantFail(
+ LLVMState::Create("riscv64-unknown-linux", "generic-rv64"))) {}
static void SetUpTestCase() {
LLVMInitializeRISCVTargetInfo();
>From a43d447206c8b06d8699144508f036fbfad80685 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 6 Jan 2025 21:52:27 -0800
Subject: [PATCH 3/3] fixup! inherit from RISCVTestBase
---
.../tools/llvm-exegesis/RISCV/TargetTest.cpp | 26 +++++--------------
1 file changed, 6 insertions(+), 20 deletions(-)
diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
index 06fa553ea5a9c9..745a6c68c9a0e1 100644
--- a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
+++ b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp
@@ -12,6 +12,7 @@
#include <memory>
#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "TestBase.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "gmock/gmock.h"
@@ -28,31 +29,16 @@ using testing::IsEmpty;
using testing::Not;
using testing::NotNull;
-constexpr const char kTriple[] = "riscv64-unknown-linux";
-
-class RISCVTargetTest : public ::testing::Test {
+class RISCVTargetTest : public RISCVTestBase {
protected:
- RISCVTargetTest() : ExegesisTarget_(ExegesisTarget::lookup(Triple(kTriple))) {
- EXPECT_THAT(ExegesisTarget_, NotNull());
- std::string error;
- Target_ = TargetRegistry::lookupTarget(kTriple, error);
- EXPECT_THAT(Target_, NotNull());
- }
- static void SetUpTestCase() {
- LLVMInitializeRISCVTargetInfo();
- LLVMInitializeRISCVTarget();
- LLVMInitializeRISCVTargetMC();
- InitializeRISCVExegesisTarget();
+ std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) {
+ return State.getExegesisTarget().setRegTo(State.getSubtargetInfo(), Reg,
+ Value);
}
-
- const Target *Target_;
- const ExegesisTarget *const ExegesisTarget_;
};
TEST_F(RISCVTargetTest, SetRegToConstant) {
- const std::unique_ptr<MCSubtargetInfo> STI(
- Target_->createMCSubtargetInfo(kTriple, "generic", ""));
- const auto Insts = ExegesisTarget_->setRegTo(*STI, RISCV::X10, APInt());
+ const auto Insts = setRegTo(RISCV::X10, APInt());
EXPECT_THAT(Insts, Not(IsEmpty()));
}
More information about the llvm-commits
mailing list