aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests')
-rw-r--r--llvm/unittests/ADT/STLExtrasTest.cpp32
-rw-r--r--llvm/unittests/ADT/SmallVectorTest.cpp39
-rw-r--r--llvm/unittests/Analysis/MemoryProfileInfoTest.cpp22
-rw-r--r--llvm/unittests/AsmParser/AsmParserTest.cpp55
-rw-r--r--llvm/unittests/CAS/CASTestConfig.cpp1
-rw-r--r--llvm/unittests/CAS/OnDiskCommonUtils.h2
-rw-r--r--llvm/unittests/CAS/OnDiskGraphDBTest.cpp2
-rw-r--r--llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp8
-rw-r--r--llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp16
-rw-r--r--llvm/unittests/CodeGen/InstrRefLDVTest.cpp2
-rw-r--r--llvm/unittests/CodeGen/MIR2VecTest.cpp598
-rw-r--r--llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp25
-rw-r--r--llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/EPCGenericMemoryAccessTest.cpp2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp8
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/ReOptimizeLayerTest.cpp2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/ResourceTrackerTest.cpp2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp2
-rw-r--r--llvm/unittests/IR/ModuleTest.cpp30
-rw-r--r--llvm/unittests/Support/GlobPatternTest.cpp66
-rw-r--r--llvm/unittests/TargetParser/RISCVISAInfoTest.cpp10
-rw-r--r--llvm/unittests/TargetParser/TargetParserTest.cpp81
-rw-r--r--llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp29
-rw-r--r--llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp10
-rw-r--r--llvm/unittests/Transforms/Vectorize/VPlanTest.cpp26
-rw-r--r--llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp16
28 files changed, 972 insertions, 120 deletions
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 47469983..966b1f0 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -27,6 +28,7 @@
using namespace llvm;
using testing::ElementsAre;
+using testing::ElementsAreArray;
using testing::UnorderedElementsAre;
namespace {
@@ -772,48 +774,30 @@ TEST(STLExtrasTest, DropBeginTest) {
SmallVector<int, 5> vec{0, 1, 2, 3, 4};
for (int n = 0; n < 5; ++n) {
- int i = n;
- for (auto &v : drop_begin(vec, n)) {
- EXPECT_EQ(v, i);
- i += 1;
- }
- EXPECT_EQ(i, 5);
+ EXPECT_THAT(drop_begin(vec, n),
+ ElementsAreArray(ArrayRef(&vec[n], vec.size() - n)));
}
}
TEST(STLExtrasTest, DropBeginDefaultTest) {
SmallVector<int, 5> vec{0, 1, 2, 3, 4};
- int i = 1;
- for (auto &v : drop_begin(vec)) {
- EXPECT_EQ(v, i);
- i += 1;
- }
- EXPECT_EQ(i, 5);
+ EXPECT_THAT(drop_begin(vec), ElementsAre(1, 2, 3, 4));
}
TEST(STLExtrasTest, DropEndTest) {
SmallVector<int, 5> vec{0, 1, 2, 3, 4};
for (int n = 0; n < 5; ++n) {
- int i = 0;
- for (auto &v : drop_end(vec, n)) {
- EXPECT_EQ(v, i);
- i += 1;
- }
- EXPECT_EQ(i, 5 - n);
+ EXPECT_THAT(drop_end(vec, n),
+ ElementsAreArray(ArrayRef(vec.data(), vec.size() - n)));
}
}
TEST(STLExtrasTest, DropEndDefaultTest) {
SmallVector<int, 5> vec{0, 1, 2, 3, 4};
- int i = 0;
- for (auto &v : drop_end(vec)) {
- EXPECT_EQ(v, i);
- i += 1;
- }
- EXPECT_EQ(i, 4);
+ EXPECT_THAT(drop_end(vec), ElementsAre(0, 1, 2, 3));
}
TEST(STLExtrasTest, MapRangeTest) {
diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp
index e2e778f..1a01f30 100644
--- a/llvm/unittests/ADT/SmallVectorTest.cpp
+++ b/llvm/unittests/ADT/SmallVectorTest.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Compiler.h"
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <list>
#include <stdarg.h>
@@ -599,6 +600,15 @@ TYPED_TEST(SmallVectorTest, AssignSmallVector) {
assertValuesInOrder(V, 2u, 7, 7);
}
+TYPED_TEST(SmallVectorTest, AssignArrayRef) {
+ SCOPED_TRACE("AssignArrayRef");
+ auto &V = this->theVector;
+ Constructable Other[] = {7, 8, 9};
+ V.push_back(Constructable(1));
+ V.assign(ArrayRef(Other));
+ assertValuesInOrder(V, 3u, 7, 8, 9);
+}
+
// Move-assign test
TYPED_TEST(SmallVectorTest, MoveAssignTest) {
SCOPED_TRACE("MoveAssignTest");
@@ -1147,6 +1157,17 @@ TEST(SmallVectorTest, InitializerList) {
EXPECT_TRUE(ArrayRef(V2).equals({4, 5, 3, 2}));
}
+namespace namespace_with_adl {
+struct MyVector {
+ std::vector<int> data;
+};
+
+std::vector<int>::const_iterator begin(const MyVector &V) {
+ return V.data.begin();
+}
+std::vector<int>::const_iterator end(const MyVector &V) { return V.data.end(); }
+} // namespace namespace_with_adl
+
TEST(SmallVectorTest, ToVector) {
{
std::vector<char> v = {'a', 'b', 'c'};
@@ -1164,6 +1185,15 @@ TEST(SmallVectorTest, ToVector) {
for (size_t I = 0; I < v.size(); ++I)
EXPECT_EQ(v[I], Vector[I]);
}
+ {
+ // Check that to_vector and to_vector_of work with types that require ADL
+ // for being/end iterators.
+ namespace_with_adl::MyVector V = {{1, 2, 3}};
+ auto IntVector = to_vector(V);
+ EXPECT_THAT(IntVector, testing::ElementsAre(1, 2, 3));
+ IntVector = to_vector<3>(V);
+ EXPECT_THAT(IntVector, testing::ElementsAre(1, 2, 3));
+ }
}
struct To {
@@ -1222,6 +1252,15 @@ TEST(SmallVectorTest, ToVectorOf) {
for (size_t I = 0; I < StdVector.size(); ++I)
EXPECT_EQ(StdVector[I], Vector[I]);
}
+ {
+ // Check that to_vector works with types that require ADL for being/end
+ // iterators.
+ namespace_with_adl::MyVector V = {{1, 2, 3}};
+ auto UnsignedVector = to_vector_of<unsigned>(V);
+ EXPECT_THAT(UnsignedVector, testing::ElementsAre(1u, 2u, 3u));
+ UnsignedVector = to_vector_of<unsigned, 3>(V);
+ EXPECT_THAT(UnsignedVector, testing::ElementsAre(1u, 2u, 3u));
+ }
}
template <class VectorT>
diff --git a/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp b/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp
index d1c0f64..113b052 100644
--- a/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp
+++ b/llvm/unittests/Analysis/MemoryProfileInfoTest.cpp
@@ -638,7 +638,7 @@ declare dso_local noalias noundef i8* @malloc(i64 noundef)
!0 = !{!1, !3, !5, !7, !9, !11}
!1 = !{!2, !"cold"}
!2 = !{i64 1, i64 2, i64 3}
-!3 = !{!4, !"cold"}
+!3 = !{!4, !"cold", !13}
!4 = !{i64 1, i64 2, i64 4}
!5 = !{!6, !"notcold"}
!6 = !{i64 1, i64 5, i64 6}
@@ -648,6 +648,7 @@ declare dso_local noalias noundef i8* @malloc(i64 noundef)
!10 = !{i64 1, i64 8, i64 9}
!11 = !{!12, !"hot"}
!12 = !{i64 1, i64 8, i64 10}
+!13 = !{i64 123, i64 456}
)IR");
Function *Func = M->getFunction("test");
@@ -683,10 +684,25 @@ declare dso_local noalias noundef i8* @malloc(i64 noundef)
auto *StackId = mdconst::dyn_extract<ConstantInt>(StackMD->getOperand(0));
EXPECT_EQ(StackId->getZExtValue(), 1u);
StackId = mdconst::dyn_extract<ConstantInt>(StackMD->getOperand(1));
- if (StackId->getZExtValue() == 2u)
+ if (StackId->getZExtValue() == 2u) {
EXPECT_EQ(getMIBAllocType(MIB), AllocationType::Cold);
- else if (StackId->getZExtValue() == 5u)
+ // We should propagate the single context size info from the second cold
+ // context above onto the new merged/trimmed context.
+ ASSERT_EQ(MIB->getNumOperands(), 3u);
+ MDNode *ContextSizePair = dyn_cast<MDNode>(MIB->getOperand(2));
+ assert(ContextSizePair->getNumOperands() == 2);
+ EXPECT_EQ(
+ mdconst::dyn_extract<ConstantInt>(ContextSizePair->getOperand(0))
+ ->getZExtValue(),
+ 123u);
+ EXPECT_EQ(
+ mdconst::dyn_extract<ConstantInt>(ContextSizePair->getOperand(1))
+ ->getZExtValue(),
+ 456u);
+ } else if (StackId->getZExtValue() == 5u) {
EXPECT_EQ(getMIBAllocType(MIB), AllocationType::NotCold);
+ ASSERT_EQ(MIB->getNumOperands(), 2u);
+ }
}
}
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index ce22670..898a829 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -6,7 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/AsmParser/AsmParserContext.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/Constants.h"
@@ -14,10 +16,14 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
+#define DEBUG_TYPE "unittest-asm-parser-tests"
+
using namespace llvm;
namespace {
@@ -479,4 +485,53 @@ TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
ASSERT_EQ(Mapping.MetadataNodes.size(), 0u);
}
+#define ASSERT_EQ_LOC(Loc1, Loc2) \
+ do { \
+ EXPECT_TRUE(Loc1.contains(Loc2) && Loc2.contains(Loc1)) \
+ << #Loc1 " location: " << Loc1.Start.Line << ":" << Loc1.Start.Col \
+ << " - " << Loc1.End.Line << ":" << Loc1.End.Col << "\n" \
+ << #Loc2 " location: " << Loc2.Start.Line << ":" << Loc2.Start.Col \
+ << " - " << Loc2.End.Line << ":" << Loc2.End.Col << "\n"; \
+ } while (false)
+
+TEST(AsmParserTest, ParserObjectLocations) {
+ StringRef Source = "define i32 @main() {\n"
+ "entry:\n"
+ " %a = add i32 1, 2\n"
+ " ret i32 %a\n"
+ "}\n";
+ LLVMContext Ctx;
+ SMDiagnostic Error;
+ SlotMapping Mapping;
+ AsmParserContext ParserContext;
+ auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping, &ParserContext);
+
+ auto *MainFn = Mod->getFunction("main");
+ ASSERT_TRUE(MainFn != nullptr);
+
+ auto MaybeMainLoc = ParserContext.getFunctionLocation(MainFn);
+ EXPECT_TRUE(MaybeMainLoc.has_value());
+ auto MainLoc = MaybeMainLoc.value();
+ auto ExpectedMainLoc = FileLocRange(FileLoc{0, 0}, FileLoc{4, 1});
+ ASSERT_EQ_LOC(MainLoc, ExpectedMainLoc);
+
+ auto &EntryBB = MainFn->getEntryBlock();
+ auto MaybeEntryBBLoc = ParserContext.getBlockLocation(&EntryBB);
+ ASSERT_TRUE(MaybeEntryBBLoc.has_value());
+ auto EntryBBLoc = MaybeEntryBBLoc.value();
+ auto ExpectedEntryBBLoc = FileLocRange(FileLoc{1, 0}, FileLoc{3, 14});
+ ASSERT_EQ_LOC(EntryBBLoc, ExpectedEntryBBLoc);
+
+ SmallVector<FileLocRange> InstructionLocations = {
+ FileLocRange(FileLoc{2, 4}, FileLoc{2, 21}),
+ FileLocRange(FileLoc{3, 4}, FileLoc{3, 14})};
+
+ for (const auto &[Inst, ExpectedLoc] : zip(EntryBB, InstructionLocations)) {
+ auto MaybeInstLoc = ParserContext.getInstructionLocation(&Inst);
+ ASSERT_TRUE(MaybeMainLoc.has_value());
+ auto InstLoc = MaybeInstLoc.value();
+ ASSERT_EQ_LOC(InstLoc, ExpectedLoc);
+ }
+}
+
} // end anonymous namespace
diff --git a/llvm/unittests/CAS/CASTestConfig.cpp b/llvm/unittests/CAS/CASTestConfig.cpp
index 91d0970..10e4b68 100644
--- a/llvm/unittests/CAS/CASTestConfig.cpp
+++ b/llvm/unittests/CAS/CASTestConfig.cpp
@@ -9,6 +9,7 @@
#include "CASTestConfig.h"
#include "llvm/CAS/ObjectStore.h"
#include "gtest/gtest.h"
+#include <mutex>
using namespace llvm;
using namespace llvm::cas;
diff --git a/llvm/unittests/CAS/OnDiskCommonUtils.h b/llvm/unittests/CAS/OnDiskCommonUtils.h
index 57c8c22..89f93e0 100644
--- a/llvm/unittests/CAS/OnDiskCommonUtils.h
+++ b/llvm/unittests/CAS/OnDiskCommonUtils.h
@@ -45,7 +45,7 @@ inline HashType digest(StringRef Data) {
}
inline ValueType valueFromString(StringRef S) {
- ValueType Val;
+ ValueType Val = {};
llvm::copy(S.substr(0, sizeof(Val)), Val.data());
return Val;
}
diff --git a/llvm/unittests/CAS/OnDiskGraphDBTest.cpp b/llvm/unittests/CAS/OnDiskGraphDBTest.cpp
index 58f5dcc6..3c2e963 100644
--- a/llvm/unittests/CAS/OnDiskGraphDBTest.cpp
+++ b/llvm/unittests/CAS/OnDiskGraphDBTest.cpp
@@ -283,7 +283,7 @@ TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInPolicyConflict) {
OnDiskGraphDB::FaultInPolicy::SingleNode);
}
-#if defined(EXPENSIVE_CHECKS)
+#if defined(EXPENSIVE_CHECKS) && !defined(_WIN32)
TEST_F(OnDiskCASTest, OnDiskGraphDBSpaceLimit) {
setMaxOnDiskCASMappingSize();
unittest::TempDir Temp("ondiskcas", /*Unique=*/true);
diff --git a/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp b/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp
index 89c03b8..41512d0 100644
--- a/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp
+++ b/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp
@@ -33,13 +33,13 @@ TEST_F(OnDiskCASTest, OnDiskKeyValueDBTest) {
}
ValueType ValW = valueFromString("world");
- ArrayRef<char> Val;
+ std::optional<ArrayRef<char>> Val;
ASSERT_THAT_ERROR(DB->put(digest("hello"), ValW).moveInto(Val), Succeeded());
- EXPECT_EQ(Val, ArrayRef(ValW));
+ EXPECT_EQ(*Val, ArrayRef(ValW));
ASSERT_THAT_ERROR(
DB->put(digest("hello"), valueFromString("other")).moveInto(Val),
Succeeded());
- EXPECT_EQ(Val, ArrayRef(ValW));
+ EXPECT_EQ(*Val, ArrayRef(ValW));
{
std::optional<ArrayRef<char>> Val;
@@ -65,7 +65,7 @@ TEST_F(OnDiskCASTest, OnDiskKeyValueDBTest) {
// Insert a lot of entries.
for (unsigned I = 0; I < 1024 * 100; ++I) {
std::string Index = Twine(I).str();
- ArrayRef<char> Val;
+ std::optional<ArrayRef<char>> Val;
ASSERT_THAT_ERROR(
DB->put(digest(Index), valueFromString(Index)).moveInto(Val),
Succeeded());
diff --git a/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp b/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp
index 6c08173..af2d56d 100644
--- a/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp
+++ b/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp
@@ -383,14 +383,14 @@ class AsmPrinterHandlerTest : public AsmPrinterFixtureBase {
public:
TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {}
- virtual ~TestHandler() {}
- virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
- virtual void beginModule(Module *M) override { Test.BeginCount++; }
- virtual void endModule() override { Test.EndCount++; }
- virtual void beginFunction(const MachineFunction *MF) override {}
- virtual void endFunction(const MachineFunction *MF) override {}
- virtual void beginInstruction(const MachineInstr *MI) override {}
- virtual void endInstruction() override {}
+ ~TestHandler() override {}
+ void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
+ void beginModule(Module *M) override { Test.BeginCount++; }
+ void endModule() override { Test.EndCount++; }
+ void beginFunction(const MachineFunction *MF) override {}
+ void endFunction(const MachineFunction *MF) override {}
+ void beginInstruction(const MachineInstr *MI) override {}
+ void endInstruction() override {}
};
protected:
diff --git a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
index ce2a38b..ff87e7b 100644
--- a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
+++ b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
@@ -69,7 +69,7 @@ public:
InstrRefLDVTest() : Ctx(), Mod(std::make_unique<Module>("beehives", Ctx)) {}
- void SetUp() {
+ void SetUp() override {
// Boilerplate that creates a MachineFunction and associated blocks.
Mod->setDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
diff --git a/llvm/unittests/CodeGen/MIR2VecTest.cpp b/llvm/unittests/CodeGen/MIR2VecTest.cpp
index 11222b4..d42749c 100644
--- a/llvm/unittests/CodeGen/MIR2VecTest.cpp
+++ b/llvm/unittests/CodeGen/MIR2VecTest.cpp
@@ -54,6 +54,9 @@ protected:
std::unique_ptr<Module> M;
std::unique_ptr<TargetMachine> TM;
const TargetInstrInfo *TII = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ std::unique_ptr<MachineModuleInfo> MMI;
+ MachineFunction *MF = nullptr;
static void SetUpTestCase() {
InitializeAllTargets();
@@ -82,31 +85,131 @@ protected:
return;
}
+ // Set the data layout to match the target machine
+ M->setDataLayout(TM->createDataLayout());
+
// Create a dummy function to get subtarget info
FunctionType *FT = FunctionType::get(Type::getVoidTy(*Ctx), false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, "test", M.get());
- // Get the target instruction info
+ // Create MMI and MF to get TRI and MRI
+ MMI = std::make_unique<MachineModuleInfo>(TM.get());
+ MF = &MMI->getOrCreateMachineFunction(*F);
+
+ // Get the target instruction info and register info
TII = TM->getSubtargetImpl(*F)->getInstrInfo();
- if (!TII) {
- GTEST_SKIP() << "Failed to get target instruction info; Skipping test";
+ TRI = TM->getSubtargetImpl(*F)->getRegisterInfo();
+ if (!TII || !TRI) {
+ GTEST_SKIP()
+ << "Failed to get target instruction/register info; Skipping test";
return;
}
}
- void TearDown() override { TII = nullptr; }
+ void TearDown() override {
+ TII = nullptr;
+ TRI = nullptr;
+ }
+
+ // Find an opcode by name
+ int findOpcodeByName(StringRef Name) {
+ for (unsigned Opcode = 1; Opcode < TII->getNumOpcodes(); ++Opcode) {
+ if (TII->getName(Opcode) == Name)
+ return Opcode;
+ }
+ return -1; // Not found
+ }
+
+ // Create a vocabulary with specific opcodes and embeddings
+ // This might cause errors in future when the validation in
+ // MIRVocabulary::generateStorage() enforces hard checks on the vocabulary
+ // entries.
+ Expected<MIRVocabulary> createTestVocab(
+ std::initializer_list<std::pair<const char *, float>> Opcodes,
+ std::initializer_list<std::pair<const char *, float>> CommonOperands,
+ std::initializer_list<std::pair<const char *, float>> PhyRegs,
+ std::initializer_list<std::pair<const char *, float>> VirtRegs,
+ unsigned Dimension = 2) {
+ assert(TII && TRI && MF && "Target info not initialized");
+ VocabMap OpcodeMap, CommonOperandMap, PhyRegMap, VirtRegMap;
+ for (const auto &[Name, Value] : Opcodes)
+ OpcodeMap[Name] = Embedding(Dimension, Value);
+
+ for (const auto &[Name, Value] : CommonOperands)
+ CommonOperandMap[Name] = Embedding(Dimension, Value);
+
+ for (const auto &[Name, Value] : PhyRegs)
+ PhyRegMap[Name] = Embedding(Dimension, Value);
+
+ for (const auto &[Name, Value] : VirtRegs)
+ VirtRegMap[Name] = Embedding(Dimension, Value);
+
+ // If any section is empty, create minimal maps for other vocabulary
+ // sections to satisfy validation
+ if (Opcodes.size() == 0)
+ OpcodeMap["NOOP"] = Embedding(Dimension, 0.0f);
+ if (CommonOperands.size() == 0)
+ CommonOperandMap["Immediate"] = Embedding(Dimension, 0.0f);
+ if (PhyRegs.size() == 0)
+ PhyRegMap["GR32"] = Embedding(Dimension, 0.0f);
+ if (VirtRegs.size() == 0)
+ VirtRegMap["GR32"] = Embedding(Dimension, 0.0f);
+
+ return MIRVocabulary::create(
+ std::move(OpcodeMap), std::move(CommonOperandMap), std::move(PhyRegMap),
+ std::move(VirtRegMap), *TII, *TRI, MF->getRegInfo());
+ }
};
-// Function to find an opcode by name
-static int findOpcodeByName(const TargetInstrInfo *TII, StringRef Name) {
- for (unsigned Opcode = 1; Opcode < TII->getNumOpcodes(); ++Opcode) {
- if (TII->getName(Opcode) == Name)
- return Opcode;
+// Parameterized test for empty vocab sections
+class MIR2VecVocabEmptySectionTestFixture
+ : public MIR2VecVocabTestFixture,
+ public ::testing::WithParamInterface<int> {
+protected:
+ void SetUp() override {
+ MIR2VecVocabTestFixture::SetUp();
+ // If base class setup was skipped (TII not initialized), skip derived setup
+ if (!TII)
+ GTEST_SKIP() << "Failed to get target instruction info in "
+ "the base class setup; Skipping test";
+ }
+};
+
+TEST_P(MIR2VecVocabEmptySectionTestFixture, EmptySectionFailsValidation) {
+ int EmptySection = GetParam();
+ VocabMap OpcodeMap, CommonOperandMap, PhyRegMap, VirtRegMap;
+
+ if (EmptySection != 0)
+ OpcodeMap["ADD"] = Embedding(2, 1.0f);
+ if (EmptySection != 1)
+ CommonOperandMap["Immediate"] = Embedding(2, 0.0f);
+ if (EmptySection != 2)
+ PhyRegMap["GR32"] = Embedding(2, 0.0f);
+ if (EmptySection != 3)
+ VirtRegMap["GR32"] = Embedding(2, 0.0f);
+
+ ASSERT_TRUE(TII != nullptr);
+ ASSERT_TRUE(TRI != nullptr);
+ ASSERT_TRUE(MF != nullptr);
+
+ auto VocabOrErr = MIRVocabulary::create(
+ std::move(OpcodeMap), std::move(CommonOperandMap), std::move(PhyRegMap),
+ std::move(VirtRegMap), *TII, *TRI, MF->getRegInfo());
+ EXPECT_FALSE(static_cast<bool>(VocabOrErr))
+ << "Factory method should fail when section " << EmptySection
+ << " is empty";
+
+ if (!VocabOrErr) {
+ auto Err = VocabOrErr.takeError();
+ std::string ErrorMsg = toString(std::move(Err));
+ EXPECT_FALSE(ErrorMsg.empty());
}
- return -1; // Not found
}
+INSTANTIATE_TEST_SUITE_P(EmptySection, MIR2VecVocabEmptySectionTestFixture,
+ ::testing::Values(0, 1, 2, 3));
+
TEST_F(MIR2VecVocabTestFixture, CanonicalOpcodeMappingTest) {
// Test that same base opcodes get same canonical indices
std::string BaseName1 = MIRVocabulary::extractBaseOpcodeName("ADD16ri");
@@ -118,10 +221,8 @@ TEST_F(MIR2VecVocabTestFixture, CanonicalOpcodeMappingTest) {
// Create a MIRVocabulary instance to test the mapping
// Use a minimal MIRVocabulary to trigger canonical mapping construction
- VocabMap VMap;
Embedding Val = Embedding(64, 1.0f);
- VMap["ADD"] = Val;
- auto TestVocabOrErr = MIRVocabulary::create(std::move(VMap), *TII);
+ auto TestVocabOrErr = createTestVocab({{"ADD", 1.0f}}, {}, {}, {}, 64);
ASSERT_TRUE(static_cast<bool>(TestVocabOrErr))
<< "Failed to create vocabulary: "
<< toString(TestVocabOrErr.takeError());
@@ -156,16 +257,16 @@ TEST_F(MIR2VecVocabTestFixture, CanonicalOpcodeMappingTest) {
6880u); // X86 has >6880 unique base opcodes
// Check that the embeddings for opcodes not in the vocab are zero vectors
- int Add32rrOpcode = findOpcodeByName(TII, "ADD32rr");
+ int Add32rrOpcode = findOpcodeByName("ADD32rr");
ASSERT_NE(Add32rrOpcode, -1) << "ADD32rr opcode not found";
EXPECT_TRUE(TestVocab[Add32rrOpcode].approximatelyEquals(Val));
- int Sub32rrOpcode = findOpcodeByName(TII, "SUB32rr");
+ int Sub32rrOpcode = findOpcodeByName("SUB32rr");
ASSERT_NE(Sub32rrOpcode, -1) << "SUB32rr opcode not found";
EXPECT_TRUE(
TestVocab[Sub32rrOpcode].approximatelyEquals(Embedding(64, 0.0f)));
- int Mov32rrOpcode = findOpcodeByName(TII, "MOV32rr");
+ int Mov32rrOpcode = findOpcodeByName("MOV32rr");
ASSERT_NE(Mov32rrOpcode, -1) << "MOV32rr opcode not found";
EXPECT_TRUE(
TestVocab[Mov32rrOpcode].approximatelyEquals(Embedding(64, 0.0f)));
@@ -178,9 +279,7 @@ TEST_F(MIR2VecVocabTestFixture, DeterministicMapping) {
// Create a MIRVocabulary instance to test deterministic mapping
// Use a minimal MIRVocabulary to trigger canonical mapping construction
- VocabMap VMap;
- VMap["ADD"] = Embedding(64, 1.0f);
- auto TestVocabOrErr = MIRVocabulary::create(std::move(VMap), *TII);
+ auto TestVocabOrErr = createTestVocab({{"ADD", 1.0f}}, {}, {}, {}, 64);
ASSERT_TRUE(static_cast<bool>(TestVocabOrErr))
<< "Failed to create vocabulary: "
<< toString(TestVocabOrErr.takeError());
@@ -189,8 +288,6 @@ TEST_F(MIR2VecVocabTestFixture, DeterministicMapping) {
unsigned Index1 = TestVocab.getCanonicalIndexForBaseName(BaseName);
unsigned Index2 = TestVocab.getCanonicalIndexForBaseName(BaseName);
unsigned Index3 = TestVocab.getCanonicalIndexForBaseName(BaseName);
-
- EXPECT_EQ(Index1, Index2);
EXPECT_EQ(Index2, Index3);
// Test across multiple runs
@@ -202,11 +299,8 @@ TEST_F(MIR2VecVocabTestFixture, DeterministicMapping) {
// Test MIRVocabulary construction
TEST_F(MIR2VecVocabTestFixture, VocabularyConstruction) {
- VocabMap VMap;
- VMap["ADD"] = Embedding(128, 1.0f); // Dimension 128, all values 1.0
- VMap["SUB"] = Embedding(128, 2.0f); // Dimension 128, all values 2.0
-
- auto VocabOrErr = MIRVocabulary::create(std::move(VMap), *TII);
+ auto VocabOrErr =
+ createTestVocab({{"ADD", 1.0f}, {"SUB", 2.0f}}, {}, {}, {}, 128);
ASSERT_TRUE(static_cast<bool>(VocabOrErr))
<< "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
auto &Vocab = *VocabOrErr;
@@ -227,20 +321,450 @@ TEST_F(MIR2VecVocabTestFixture, VocabularyConstruction) {
EXPECT_GT(Count, 0u);
}
-// Test factory method with empty vocabulary
-TEST_F(MIR2VecVocabTestFixture, EmptyVocabularyCreation) {
- VocabMap EmptyVMap;
+// Fixture for embedding related tests
+class MIR2VecEmbeddingTestFixture : public MIR2VecVocabTestFixture {
+protected:
+ void SetUp() override {
+ MIR2VecVocabTestFixture::SetUp();
+ // If base class setup was skipped (TII not initialized), skip derived setup
+ if (!TII)
+ GTEST_SKIP() << "Failed to get target instruction info in "
+ "the base class setup; Skipping test";
+ }
- auto VocabOrErr = MIRVocabulary::create(std::move(EmptyVMap), *TII);
- EXPECT_FALSE(static_cast<bool>(VocabOrErr))
- << "Factory method should fail with empty vocabulary";
+ void TearDown() override { MIR2VecVocabTestFixture::TearDown(); }
- // Consume the error
- if (!VocabOrErr) {
- auto Err = VocabOrErr.takeError();
- std::string ErrorMsg = toString(std::move(Err));
- EXPECT_FALSE(ErrorMsg.empty());
+ // Create a machine instruction
+ MachineInstr *createMachineInstr(MachineBasicBlock &MBB, unsigned Opcode) {
+ const MCInstrDesc &Desc = TII->get(Opcode);
+ // Create instruction - operands don't affect opcode-based embeddings
+ MachineInstr *MI = BuildMI(MBB, MBB.end(), DebugLoc(), Desc);
+ return MI;
+ }
+
+ MachineInstr *createMachineInstr(MachineBasicBlock &MBB,
+ const char *OpcodeName) {
+ int Opcode = findOpcodeByName(OpcodeName);
+ if (Opcode == -1)
+ return nullptr;
+ return createMachineInstr(MBB, Opcode);
+ }
+
+ void createMachineInstrs(MachineBasicBlock &MBB,
+ std::initializer_list<const char *> Opcodes) {
+ for (const char *OpcodeName : Opcodes) {
+ MachineInstr *MI = createMachineInstr(MBB, OpcodeName);
+ ASSERT_TRUE(MI != nullptr);
+ }
+ }
+};
+
+// Test factory method for creating embedder
+TEST_F(MIR2VecEmbeddingTestFixture, CreateSymbolicEmbedder) {
+ auto VocabOrErr =
+ MIRVocabulary::createDummyVocabForTest(*TII, *TRI, MF->getRegInfo(), 1);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &V = *VocabOrErr;
+ auto Emb = MIREmbedder::create(MIR2VecKind::Symbolic, *MF, V);
+ EXPECT_NE(Emb, nullptr);
+}
+
+TEST_F(MIR2VecEmbeddingTestFixture, CreateInvalidMode) {
+ auto VocabOrErr =
+ MIRVocabulary::createDummyVocabForTest(*TII, *TRI, MF->getRegInfo(), 1);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &V = *VocabOrErr;
+ auto Result = MIREmbedder::create(static_cast<MIR2VecKind>(-1), *MF, V);
+ EXPECT_FALSE(static_cast<bool>(Result));
+}
+
+// Test SymbolicMIREmbedder with simple target opcodes
+TEST_F(MIR2VecEmbeddingTestFixture, TestSymbolicEmbedder) {
+ // Create a test vocabulary with specific values
+ auto VocabOrErr = createTestVocab(
+ {
+ {"NOOP", 1.0f}, // [1.0, 1.0, 1.0, 1.0]
+ {"RET", 2.0f}, // [2.0, 2.0, 2.0, 2.0]
+ {"TRAP", 3.0f} // [3.0, 3.0, 3.0, 3.0]
+ },
+ {}, {}, {}, 4);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+ // Create a basic block using fixture's MF
+ MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB);
+
+ // Use real X86 opcodes that should exist and not be pseudo
+ auto NoopInst = createMachineInstr(*MBB, "NOOP");
+ ASSERT_TRUE(NoopInst != nullptr);
+
+ auto RetInst = createMachineInstr(*MBB, "RET64");
+ ASSERT_TRUE(RetInst != nullptr);
+
+ auto TrapInst = createMachineInstr(*MBB, "TRAP");
+ ASSERT_TRUE(TrapInst != nullptr);
+
+ // Verify these are not pseudo instructions
+ ASSERT_FALSE(NoopInst->isPseudo()) << "NOOP is marked as pseudo instruction";
+ ASSERT_FALSE(RetInst->isPseudo()) << "RET is marked as pseudo instruction";
+ ASSERT_FALSE(TrapInst->isPseudo()) << "TRAP is marked as pseudo instruction";
+
+ // Create embedder
+ auto Embedder = SymbolicMIREmbedder::create(*MF, Vocab);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // Test instruction embeddings
+ auto NoopEmb = Embedder->getMInstVector(*NoopInst);
+ auto RetEmb = Embedder->getMInstVector(*RetInst);
+ auto TrapEmb = Embedder->getMInstVector(*TrapInst);
+
+ // Verify embeddings match expected values (accounting for weight scaling)
+ float ExpectedWeight = mir2vec::OpcWeight; // Global weight from command line
+ EXPECT_TRUE(NoopEmb.approximatelyEquals(Embedding(4, 1.0f * ExpectedWeight)));
+ EXPECT_TRUE(RetEmb.approximatelyEquals(Embedding(4, 2.0f * ExpectedWeight)));
+ EXPECT_TRUE(TrapEmb.approximatelyEquals(Embedding(4, 3.0f * ExpectedWeight)));
+
+ // Test basic block embedding (should be sum of instruction embeddings)
+ auto MBBVector = Embedder->getMBBVector(*MBB);
+
+ // Expected BB vector: NOOP + RET + TRAP = [1+2+3, 1+2+3, 1+2+3, 1+2+3] *
+ // weight = [6, 6, 6, 6] * weight
+ Embedding ExpectedMBBVector(4, 6.0f * ExpectedWeight);
+ EXPECT_TRUE(MBBVector.approximatelyEquals(ExpectedMBBVector));
+
+ // Test function embedding (should equal MBB embedding since we have one MBB)
+ auto MFuncVector = Embedder->getMFunctionVector();
+ EXPECT_TRUE(MFuncVector.approximatelyEquals(ExpectedMBBVector));
+}
+
+// Test embedder with multiple basic blocks
+TEST_F(MIR2VecEmbeddingTestFixture, MultipleBasicBlocks) {
+ // Create a test vocabulary
+ auto VocabOrErr =
+ createTestVocab({{"NOOP", 1.0f}, {"TRAP", 2.0f}}, {}, {}, {});
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ // Create two basic blocks using fixture's MF
+ MachineBasicBlock *MBB1 = MF->CreateMachineBasicBlock();
+ MachineBasicBlock *MBB2 = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB1);
+ MF->push_back(MBB2);
+
+ createMachineInstrs(*MBB1, {"NOOP", "NOOP"});
+ createMachineInstr(*MBB2, "TRAP");
+
+ // Create embedder
+ auto Embedder = SymbolicMIREmbedder::create(*MF, Vocab);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // Test basic block embeddings
+ auto MBB1Vector = Embedder->getMBBVector(*MBB1);
+ auto MBB2Vector = Embedder->getMBBVector(*MBB2);
+
+ float ExpectedWeight = mir2vec::OpcWeight;
+ // BB1: NOOP + NOOP = 2 * ([1, 1] * weight)
+ Embedding ExpectedMBB1Vector(2, 2.0f * ExpectedWeight);
+ EXPECT_TRUE(MBB1Vector.approximatelyEquals(ExpectedMBB1Vector));
+
+ // BB2: TRAP = [2, 2] * weight
+ Embedding ExpectedMBB2Vector(2, 2.0f * ExpectedWeight);
+ EXPECT_TRUE(MBB2Vector.approximatelyEquals(ExpectedMBB2Vector));
+
+ // Function embedding: BB1 + BB2 = [2+2, 2+2] * weight = [4, 4] * weight
+ // Function embedding should be just the first BB embedding as the second BB
+ // is unreachable
+ auto MFuncVector = Embedder->getMFunctionVector();
+ EXPECT_TRUE(MFuncVector.approximatelyEquals(ExpectedMBB1Vector));
+
+ // Add a branch from BB1 to BB2 to make both reachable; now function embedding
+ // should be MBB1 + MBB2
+ MBB1->addSuccessor(MBB2);
+ auto NewMFuncVector = Embedder->getMFunctionVector(); // Recompute embeddings
+ Embedding ExpectedFuncVector = MBB1Vector + MBB2Vector;
+ EXPECT_TRUE(NewMFuncVector.approximatelyEquals(ExpectedFuncVector));
+}
+
+// Test embedder with empty basic block
+TEST_F(MIR2VecEmbeddingTestFixture, EmptyBasicBlock) {
+
+ // Create an empty basic block
+ MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB);
+
+ // Create embedder
+ auto VocabOrErr =
+ MIRVocabulary::createDummyVocabForTest(*TII, *TRI, MF->getRegInfo(), 2);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &V = *VocabOrErr;
+ auto Embedder = SymbolicMIREmbedder::create(*MF, V);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // Test that empty BB has zero embedding
+ auto MBBVector = Embedder->getMBBVector(*MBB);
+ Embedding ExpectedBBVector(2, 0.0f);
+ EXPECT_TRUE(MBBVector.approximatelyEquals(ExpectedBBVector));
+
+ // Function embedding should also be zero
+ auto MFuncVector = Embedder->getMFunctionVector();
+ EXPECT_TRUE(MFuncVector.approximatelyEquals(ExpectedBBVector));
+}
+
+// Test embedder with opcodes not in vocabulary
+TEST_F(MIR2VecEmbeddingTestFixture, UnknownOpcodes) {
+ // Create a test vocabulary with limited entries
+ // SUB is intentionally not included
+ auto VocabOrErr = createTestVocab({{"ADD", 1.0f}}, {}, {}, {});
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ // Create a basic block
+ MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB);
+
+ // Find opcodes
+ int AddOpcode = findOpcodeByName("ADD32rr");
+ int SubOpcode = findOpcodeByName("SUB32rr");
+
+ ASSERT_NE(AddOpcode, -1) << "ADD32rr opcode not found";
+ ASSERT_NE(SubOpcode, -1) << "SUB32rr opcode not found";
+
+ // Create instructions
+ MachineInstr *AddInstr = createMachineInstr(*MBB, AddOpcode);
+ MachineInstr *SubInstr = createMachineInstr(*MBB, SubOpcode);
+
+ // Create embedder
+ auto Embedder = SymbolicMIREmbedder::create(*MF, Vocab);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // Test instruction embeddings
+ auto AddVector = Embedder->getMInstVector(*AddInstr);
+ auto SubVector = Embedder->getMInstVector(*SubInstr);
+
+ float ExpectedWeight = mir2vec::OpcWeight;
+ // ADD should have the embedding from vocabulary
+ EXPECT_TRUE(
+ AddVector.approximatelyEquals(Embedding(2, 1.0f * ExpectedWeight)));
+
+ // SUB should have zero embedding (not in vocabulary)
+ EXPECT_TRUE(SubVector.approximatelyEquals(Embedding(2, 0.0f)));
+
+ // Basic block embedding should be ADD + SUB = [1.0, 1.0] * weight + [0.0,
+ // 0.0] = [1.0, 1.0] * weight
+ const auto &MBBVector = Embedder->getMBBVector(*MBB);
+ Embedding ExpectedBBVector(2, 1.0f * ExpectedWeight);
+ EXPECT_TRUE(MBBVector.approximatelyEquals(ExpectedBBVector));
+}
+
+// Test vocabulary string key generation
+TEST_F(MIR2VecEmbeddingTestFixture, VocabularyStringKeys) {
+ auto VocabOrErr =
+ createTestVocab({{"ADD", 1.0f}, {"SUB", 2.0f}}, {}, {}, {}, 2);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ // Test that we can get string keys for all positions
+ for (size_t Pos = 0; Pos < Vocab.getCanonicalSize(); ++Pos) {
+ std::string Key = Vocab.getStringKey(Pos);
+ EXPECT_FALSE(Key.empty()) << "Empty key at position " << Pos;
+ }
+
+ // Test specific known positions if we can identify them
+ unsigned AddIndex = Vocab.getCanonicalIndexForBaseName("ADD");
+ std::string AddKey = Vocab.getStringKey(AddIndex);
+ EXPECT_EQ(AddKey, "ADD");
+
+ unsigned SubIndex = Vocab.getCanonicalIndexForBaseName("SUB");
+ std::string SubKey = Vocab.getStringKey(SubIndex);
+ EXPECT_EQ(SubKey, "SUB");
+
+ unsigned ImmIndex = Vocab.getCanonicalIndexForOperandName("Immediate");
+ std::string ImmKey = Vocab.getStringKey(ImmIndex);
+ EXPECT_EQ(ImmKey, "Immediate");
+
+ unsigned PhyRegIndex = Vocab.getCanonicalIndexForRegisterClass("GR32", true);
+ std::string PhyRegKey = Vocab.getStringKey(PhyRegIndex);
+ EXPECT_EQ(PhyRegKey, "PhyReg_GR32");
+
+ unsigned VirtRegIndex =
+ Vocab.getCanonicalIndexForRegisterClass("GR32", false);
+ std::string VirtRegKey = Vocab.getStringKey(VirtRegIndex);
+ EXPECT_EQ(VirtRegKey, "VirtReg_GR32");
+}
+
+// Test vocabulary dimension consistency
+TEST_F(MIR2VecEmbeddingTestFixture, DimensionConsistency) {
+ auto VocabOrErr = createTestVocab({{"TEST", 1.0f}}, {}, {}, {}, 5);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ EXPECT_EQ(Vocab.getDimension(), 5u);
+
+ // All embeddings should have the same dimension
+ for (auto IT = Vocab.begin(); IT != Vocab.end(); ++IT)
+ EXPECT_EQ((*IT).size(), 5u);
+}
+
+// Test invalid register handling through machine instruction creation
+TEST_F(MIR2VecEmbeddingTestFixture, InvalidRegisterHandling) {
+ float MOVValue = 1.5f;
+ float ImmValue = 0.5f;
+ float PhyRegValue = 0.2f;
+ auto VocabOrErr = createTestVocab(
+ {{"MOV", MOVValue}}, {{"Immediate", ImmValue}},
+ {{"GR8_ABCD_H", PhyRegValue}, {"GR8_ABCD_L", PhyRegValue + 0.1f}}, {}, 3);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB);
+
+ // Create a MOV instruction with actual operands including potential $noreg
+ // This tests the actual scenario where invalid registers are encountered
+ auto MovOpcode = findOpcodeByName("MOV32mr");
+ ASSERT_NE(MovOpcode, -1) << "MOV32mr opcode not found";
+ const MCInstrDesc &Desc = TII->get(MovOpcode);
+
+ // Use available physical registers from the target
+ unsigned BaseReg =
+ TRI->getNumRegs() > 1 ? 1 : 0; // First available physical register
+ unsigned ValueReg = TRI->getNumRegs() > 2 ? 2 : BaseReg;
+
+ // MOV32mr typically has: base, scale, index, displacement, segment, value
+ // Use the MachineInstrBuilder API properly
+ auto MovInst = BuildMI(*MBB, MBB->end(), DebugLoc(), Desc)
+ .addReg(BaseReg) // base
+ .addImm(1) // scale
+ .addReg(0) // index ($noreg)
+ .addImm(-4) // displacement
+ .addReg(0) // segment ($noreg)
+ .addReg(ValueReg); // value
+
+ auto Embedder = SymbolicMIREmbedder::create(*MF, Vocab);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // This should not crash even if the instruction has $noreg operands
+ auto InstEmb = Embedder->getMInstVector(*MovInst);
+ EXPECT_EQ(InstEmb.size(), 3u);
+
+ // Test the expected embedding value
+ Embedding ExpectedOpcodeContribution(3, MOVValue * mir2vec::OpcWeight);
+ auto ExpectedOperandContribution =
+ Embedding(3, PhyRegValue * mir2vec::RegOperandWeight) // Base
+ + Embedding(3, ImmValue * mir2vec::CommonOperandWeight) // Scale
+ + Embedding(3, 0.0f) // noreg
+ + Embedding(3, ImmValue * mir2vec::CommonOperandWeight) // displacement
+ + Embedding(3, 0.0f) // noreg
+ + Embedding(3, (PhyRegValue + 0.1f) * mir2vec::RegOperandWeight); // Value
+ auto ExpectedEmb = ExpectedOpcodeContribution + ExpectedOperandContribution;
+ EXPECT_TRUE(InstEmb.approximatelyEquals(ExpectedEmb))
+ << "MOV instruction embedding should match expected embedding";
+}
+
+// Test handling of both physical and virtual registers in an instruction
+TEST_F(MIR2VecEmbeddingTestFixture, PhysicalAndVirtualRegisterHandling) {
+ float MOVValue = 2.0f;
+ float ImmValue = 0.7f;
+ float PhyRegValue = 0.3f;
+ float VirtRegValue = 0.9f;
+
+ // Find GR32 register class
+ const TargetRegisterClass *GR32RC = nullptr;
+ for (unsigned i = 0; i < TRI->getNumRegClasses(); ++i) {
+ const TargetRegisterClass *RC = TRI->getRegClass(i);
+ if (std::string(TRI->getRegClassName(RC)) == "GR32") {
+ GR32RC = RC;
+ break;
+ }
}
+ ASSERT_TRUE(GR32RC != nullptr && GR32RC->isAllocatable())
+ << "No allocatable GR32 register class found";
+
+ // Get first available physical register from GR32
+ unsigned PhyReg = *GR32RC->begin();
+ // Create a virtual register of class GR32
+ unsigned VirtReg = MF->getRegInfo().createVirtualRegister(GR32RC);
+
+ // Create vocabulary with register class based keys
+ auto VocabOrErr =
+ createTestVocab({{"MOV", MOVValue}}, {{"Immediate", ImmValue}},
+ {{"GR32_AD", PhyRegValue}}, // GR32_AD is the minimal key
+ {{"GR32", VirtRegValue}}, 4);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB);
+
+ // Create a MOV32rr instruction: MOV32rr dst, src
+ auto MovOpcode = findOpcodeByName("MOV32rr");
+ ASSERT_NE(MovOpcode, -1) << "MOV32rr opcode not found";
+ const MCInstrDesc &Desc = TII->get(MovOpcode);
+
+ // MOV32rr: dst (physical), src (virtual)
+ auto MovInst = BuildMI(*MBB, MBB->end(), DebugLoc(), Desc)
+ .addReg(PhyReg) // physical register destination
+ .addReg(VirtReg); // virtual register source
+
+ // Create embedder with virtual register support
+ auto Embedder = SymbolicMIREmbedder::create(*MF, Vocab);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // This should not crash and should produce a valid embedding
+ auto InstEmb = Embedder->getMInstVector(*MovInst);
+ EXPECT_EQ(InstEmb.size(), 4u);
+
+ // Test the expected embedding value
+ Embedding ExpectedOpcodeContribution(4, MOVValue * mir2vec::OpcWeight);
+ auto ExpectedOperandContribution =
+ Embedding(4, PhyRegValue * mir2vec::RegOperandWeight) // dst (physical)
+ + Embedding(4, VirtRegValue * mir2vec::RegOperandWeight); // src (virtual)
+ auto ExpectedEmb = ExpectedOpcodeContribution + ExpectedOperandContribution;
+ EXPECT_TRUE(InstEmb.approximatelyEquals(ExpectedEmb))
+ << "MOV32rr instruction embedding should match expected embedding";
}
+// Test precise embedding calculation with known operands
+TEST_F(MIR2VecEmbeddingTestFixture, EmbeddingCalculation) {
+ auto VocabOrErr = createTestVocab({{"NOOP", 2.0f}}, {}, {}, {}, 2);
+ ASSERT_TRUE(static_cast<bool>(VocabOrErr))
+ << "Failed to create vocabulary: " << toString(VocabOrErr.takeError());
+ auto &Vocab = *VocabOrErr;
+
+ MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
+ MF->push_back(MBB);
+
+ // Create a simple NOOP instruction (no operands)
+ auto NoopInst = createMachineInstr(*MBB, "NOOP");
+ ASSERT_TRUE(NoopInst != nullptr);
+
+ auto Embedder = SymbolicMIREmbedder::create(*MF, Vocab);
+ ASSERT_TRUE(Embedder != nullptr);
+
+ // Get the instruction embedding
+ auto InstEmb = Embedder->getMInstVector(*NoopInst);
+ EXPECT_EQ(InstEmb.size(), 2u);
+
+ // For NOOP with no operands, the embedding should be exactly the opcode
+ // embedding
+ float ExpectedWeight = mir2vec::OpcWeight;
+ Embedding ExpectedEmb(2, 2.0f * ExpectedWeight);
+
+ EXPECT_TRUE(InstEmb.approximatelyEquals(ExpectedEmb))
+ << "NOOP instruction embedding should match opcode embedding";
+
+ // Verify individual components
+ EXPECT_FLOAT_EQ(InstEmb[0], 2.0f * ExpectedWeight);
+ EXPECT_FLOAT_EQ(InstEmb[1], 2.0f * ExpectedWeight);
+}
} // namespace
diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
index 16b9979..aa56aaf 100644
--- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp
@@ -550,6 +550,31 @@ TEST_F(SelectionDAGPatternMatchTest, matchNode) {
EXPECT_FALSE(sd_match(Add, m_Node(ISD::ADD, m_ConstInt(), m_Value())));
}
+TEST_F(SelectionDAGPatternMatchTest, matchSelectLike) {
+ SDLoc DL;
+ auto Int32VT = EVT::getIntegerVT(Context, 32);
+ auto VInt32VT = EVT::getVectorVT(Context, Int32VT, 4);
+
+ SDValue Cond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 0, Int32VT);
+ SDValue TVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT);
+ SDValue FVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Int32VT);
+
+ SDValue VCond = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 0, VInt32VT);
+ SDValue VTVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, VInt32VT);
+ SDValue VFVal = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, VInt32VT);
+
+ SDValue Select = DAG->getNode(ISD::SELECT, DL, Int32VT, Cond, TVal, FVal);
+ SDValue VSelect =
+ DAG->getNode(ISD::VSELECT, DL, Int32VT, VCond, VTVal, VFVal);
+
+ using namespace SDPatternMatch;
+ EXPECT_TRUE(sd_match(Select, m_SelectLike(m_Specific(Cond), m_Specific(TVal),
+ m_Specific(FVal))));
+ EXPECT_TRUE(
+ sd_match(VSelect, m_SelectLike(m_Specific(VCond), m_Specific(VTVal),
+ m_Specific(VFVal))));
+}
+
namespace {
struct VPMatchContext : public SDPatternMatch::BasicMatchContext {
using SDPatternMatch::BasicMatchContext::BasicMatchContext;
diff --git a/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h b/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h
index dc077f9..f03c82f 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h
+++ b/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h
@@ -132,7 +132,7 @@ public:
: JITLinkContext(&JD), MJMM(std::move(MJMM)),
HandleFailed(std::move(HandleFailed)) {}
- ~MockJITLinkContext() {
+ ~MockJITLinkContext() override {
if (auto Err = MJMM->deallocate(std::move(FinalizedAllocs)))
notifyFailed(std::move(Err));
}
diff --git a/llvm/unittests/ExecutionEngine/Orc/EPCGenericMemoryAccessTest.cpp b/llvm/unittests/ExecutionEngine/Orc/EPCGenericMemoryAccessTest.cpp
index 2bcff33..a72dc5f 100644
--- a/llvm/unittests/ExecutionEngine/Orc/EPCGenericMemoryAccessTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/EPCGenericMemoryAccessTest.cpp
@@ -140,7 +140,7 @@ public:
MemAccess = std::make_unique<EPCGenericMemoryAccess>(*EPC, FAs);
}
- ~EPCGenericMemoryAccessTest() { cantFail(EPC->disconnect()); }
+ ~EPCGenericMemoryAccessTest() override { cantFail(EPC->disconnect()); }
protected:
std::shared_ptr<SelfExecutorProcessControl> EPC;
diff --git a/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp
index a57241b..018a678 100644
--- a/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp
@@ -18,7 +18,7 @@ static int finalTarget() { return 53; }
class JITLinkRedirectionManagerTest : public testing::Test {
public:
- ~JITLinkRedirectionManagerTest() {
+ ~JITLinkRedirectionManagerTest() override {
if (ES)
if (auto Err = ES->endSession())
ES->reportError(std::move(Err));
diff --git a/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
index 5ff3e26..5deebec9 100644
--- a/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
@@ -34,7 +34,7 @@ ArrayRef<char> BlockContent(BlockContentBytes);
class ObjectLinkingLayerTest : public testing::Test {
public:
- ~ObjectLinkingLayerTest() {
+ ~ObjectLinkingLayerTest() override {
if (auto Err = ES.endSession())
ES.reportError(std::move(Err));
}
@@ -161,7 +161,7 @@ TEST_F(ObjectLinkingLayerTest, HandleErrorDuringPostAllocationPass) {
// abandon the in-flight allocation and report an error.
class TestPlugin : public ObjectLinkingLayer::Plugin {
public:
- ~TestPlugin() { EXPECT_TRUE(ErrorReported); }
+ ~TestPlugin() override { EXPECT_TRUE(ErrorReported); }
void modifyPassConfig(MaterializationResponsibility &MR,
jitlink::LinkGraph &G,
@@ -215,7 +215,7 @@ TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
TestPlugin(size_t &ActivationCount, bool &PluginDestroyed)
: ActivationCount(ActivationCount), PluginDestroyed(PluginDestroyed) {}
- ~TestPlugin() { PluginDestroyed = true; }
+ ~TestPlugin() override { PluginDestroyed = true; }
void modifyPassConfig(MaterializationResponsibility &MR,
jitlink::LinkGraph &G,
@@ -336,7 +336,7 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
class CheckDefs : public ObjectLinkingLayer::Plugin {
public:
- ~CheckDefs() { EXPECT_TRUE(SawSymbolDef); }
+ ~CheckDefs() override { EXPECT_TRUE(SawSymbolDef); }
void modifyPassConfig(MaterializationResponsibility &MR,
jitlink::LinkGraph &G,
diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
index 469de2a..e22c35f 100644
--- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
+++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -47,7 +47,7 @@ namespace orc {
// (5) V -- A JITDylib associated with ES.
class CoreAPIsBasedStandardTest : public testing::Test {
public:
- ~CoreAPIsBasedStandardTest() {
+ ~CoreAPIsBasedStandardTest() override {
if (auto Err = ES.endSession())
ES.reportError(std::move(Err));
}
diff --git a/llvm/unittests/ExecutionEngine/Orc/ReOptimizeLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ReOptimizeLayerTest.cpp
index 686d85d..ac591c1 100644
--- a/llvm/unittests/ExecutionEngine/Orc/ReOptimizeLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/ReOptimizeLayerTest.cpp
@@ -26,7 +26,7 @@ using namespace llvm::jitlink;
class ReOptimizeLayerTest : public testing::Test {
public:
- ~ReOptimizeLayerTest() {
+ ~ReOptimizeLayerTest() override {
if (ES)
if (auto Err = ES->endSession())
ES->reportError(std::move(Err));
diff --git a/llvm/unittests/ExecutionEngine/Orc/ResourceTrackerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ResourceTrackerTest.cpp
index 0e5d1517..3591829b 100644
--- a/llvm/unittests/ExecutionEngine/Orc/ResourceTrackerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/ResourceTrackerTest.cpp
@@ -50,7 +50,7 @@ public:
SimpleResourceManager(SimpleResourceManager &&) = delete;
SimpleResourceManager &operator=(SimpleResourceManager &&) = delete;
- ~SimpleResourceManager() { ES.deregisterResourceManager(*this); }
+ ~SimpleResourceManager() override { ES.deregisterResourceManager(*this); }
/// Set the HandleRemove function object.
void setHandleRemove(HandleRemoveFunction HandleRemove) {
diff --git a/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp b/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp
index b988a78a..08b4e8f 100644
--- a/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp
@@ -54,7 +54,9 @@ protected:
return ContainerElementsMap();
ContainerElementsMap Result = SNs[0]->defs();
+#ifndef NDEBUG
const ContainerElementsMap &Deps = SNs[0]->deps();
+#endif // NDEBUG
for (size_t I = 1; I != SNs.size(); ++I) {
assert(!DepsMustMatch || SNs[I]->deps() == Deps);
diff --git a/llvm/unittests/IR/ModuleTest.cpp b/llvm/unittests/IR/ModuleTest.cpp
index 36c35673..30eda73 100644
--- a/llvm/unittests/IR/ModuleTest.cpp
+++ b/llvm/unittests/IR/ModuleTest.cpp
@@ -103,6 +103,36 @@ TEST(ModuleTest, setModuleFlagInt) {
EXPECT_EQ(Val2, A2->getZExtValue());
}
+TEST(ModuleTest, setModuleFlagTwoMod) {
+ LLVMContext Context;
+ Module MA("MA", Context);
+ Module MB("MB", Context);
+ StringRef Key = "Key";
+ uint32_t Val1 = 1;
+ uint32_t Val2 = 2;
+
+ // Set a flag to MA
+ EXPECT_EQ(nullptr, MA.getModuleFlag(Key));
+ MA.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1);
+ auto A1 = mdconst::extract_or_null<ConstantInt>(MA.getModuleFlag(Key));
+ EXPECT_EQ(Val1, A1->getZExtValue());
+
+ // Set a flag to MB
+ EXPECT_EQ(nullptr, MB.getModuleFlag(Key));
+ MB.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1);
+ auto B1 = mdconst::extract_or_null<ConstantInt>(MB.getModuleFlag(Key));
+ EXPECT_EQ(Val1, B1->getZExtValue());
+
+ // Change the flag of MA
+ MA.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val2);
+ auto A2 = mdconst::extract_or_null<ConstantInt>(MA.getModuleFlag(Key));
+ EXPECT_EQ(Val2, A2->getZExtValue());
+
+ // MB should keep the original flag value
+ auto B2 = mdconst::extract_or_null<ConstantInt>(MB.getModuleFlag(Key));
+ EXPECT_EQ(Val1, B2->getZExtValue());
+}
+
const char *IRString = R"IR(
!llvm.module.flags = !{!0}
diff --git a/llvm/unittests/Support/GlobPatternTest.cpp b/llvm/unittests/Support/GlobPatternTest.cpp
index 58fd767..872a21e 100644
--- a/llvm/unittests/Support/GlobPatternTest.cpp
+++ b/llvm/unittests/Support/GlobPatternTest.cpp
@@ -329,6 +329,72 @@ TEST_F(GlobPatternTest, PrefixSuffix) {
EXPECT_EQ("cd", Pat->suffix());
}
+TEST_F(GlobPatternTest, Substr) {
+ auto Pat = GlobPattern::create("");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("", Pat->longest_substr());
+
+ Pat = GlobPattern::create("abcd");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcd");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("", Pat->longest_substr());
+
+ Pat = GlobPattern::create("*abcd");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("", Pat->longest_substr());
+
+ Pat = GlobPattern::create("abcd*");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bc*d");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bc", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bc*def*g");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("def", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcd*ef*g");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcd", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcd*efg*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcd", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcd[ef]g*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcd", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bc[d]efg*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("efg", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bc[]]efg*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("efg", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcde\\fg*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcde", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcde\\[fg*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcde", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcde?fg*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcde", Pat->longest_substr());
+
+ Pat = GlobPattern::create("a*bcdef{g}*h");
+ ASSERT_TRUE((bool)Pat);
+ EXPECT_EQ("bcdef", Pat->longest_substr());
+}
+
TEST_F(GlobPatternTest, Pathological) {
std::string P, S(40, 'a');
StringRef Pieces[] = {"a*", "[ba]*", "{b*,a*}*"};
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 5d69a31..bfc1275 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -730,6 +730,11 @@ TEST(ParseArchString, MissingDepency) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
"");
}
+
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64i_xsfvfbfexp16e", true)
+ .takeError()),
+ "'xsfvfbfexp16e' requires 'zvfbfmin' or 'zvfbfa' extension to also "
+ "be specified");
}
TEST(ParseArchString, RejectsUnrecognizedProfileNames) {
@@ -1162,6 +1167,11 @@ R"(All available -march extensions for RISC-V
xsfmm64t 0.6
xsfmmbase 0.6
xsfvcp 1.0
+ xsfvfbfexp16e 0.5
+ xsfvfexp16e 0.5
+ xsfvfexp32e 0.5
+ xsfvfexpa 0.2
+ xsfvfexpa64e 0.2
xsfvfnrclipxfqf 1.0
xsfvfwmaccqqq 1.0
xsfvqmaccdod 1.0
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 53a64b6..ef6aeae 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -47,6 +47,7 @@ const char *ARMArch[] = {
"armv9-a", "armv9", "armv9a", "armv9.1-a", "armv9.1a",
"armv9.2-a", "armv9.2a", "armv9.3-a", "armv9.3a", "armv9.4-a",
"armv9.4a", "armv9.5-a", "armv9.5a", "armv9.6a", "armv9.6-a",
+ "armv9.7a", "armv9.7-a",
};
std::string FormatExtensionFlags(int64_t Flags) {
@@ -622,6 +623,8 @@ TEST(TargetParserTest, testARMArch) {
ARMBuildAttrs::CPUArch::v9_A));
EXPECT_TRUE(testARMArch("armv9.6-a", "generic", "v9.6a",
ARMBuildAttrs::CPUArch::v9_A));
+ EXPECT_TRUE(testARMArch("armv9.7-a", "generic", "v9.7a",
+ ARMBuildAttrs::CPUArch::v9_A));
EXPECT_TRUE(
testARMArch("armv8-r", "generic", "v8r", ARMBuildAttrs::CPUArch::v8_R));
EXPECT_TRUE(testARMArch("armv8-m.base", "generic", "v8m.base",
@@ -937,6 +940,7 @@ TEST(TargetParserTest, ARMparseArchProfile) {
case ARM::ArchKind::ARMV9_4A:
case ARM::ArchKind::ARMV9_5A:
case ARM::ArchKind::ARMV9_6A:
+ case ARM::ArchKind::ARMV9_7A:
EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i]));
break;
default:
@@ -1294,6 +1298,7 @@ TEST(TargetParserTest, testAArch64Arch) {
EXPECT_TRUE(testAArch64Arch("armv9.4-a"));
EXPECT_TRUE(testAArch64Arch("armv9.5-a"));
EXPECT_TRUE(testAArch64Arch("armv9.6-a"));
+ EXPECT_TRUE(testAArch64Arch("armv9.7-a"));
}
bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) {
@@ -1438,7 +1443,13 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
AArch64::AEK_SVEAES, AArch64::AEK_SME_MOP4,
AArch64::AEK_SME_TMOP, AArch64::AEK_SVEBITPERM,
AArch64::AEK_SSVE_BITPERM, AArch64::AEK_SVESHA3,
- AArch64::AEK_SVESM4,
+ AArch64::AEK_SVESM4, AArch64::AEK_CMH,
+ AArch64::AEK_LSCP, AArch64::AEK_TLBID,
+ AArch64::AEK_MPAMV2, AArch64::AEK_MTETC,
+ AArch64::AEK_GCIE, AArch64::AEK_SME2P3,
+ AArch64::AEK_SVE2P3, AArch64::AEK_SVE_B16MM,
+ AArch64::AEK_F16MM, AArch64::AEK_F16F32DOT,
+ AArch64::AEK_F16F32MM,
};
std::vector<StringRef> Features;
@@ -1550,6 +1561,18 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
EXPECT_TRUE(llvm::is_contained(Features, "+pops"));
EXPECT_TRUE(llvm::is_contained(Features, "+sme-mop4"));
EXPECT_TRUE(llvm::is_contained(Features, "+sme-tmop"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+cmh"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+lscp"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+tlbid"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+mpamv2"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+mtetc"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+gcie"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+sme2p3"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+sve2p3"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+sve-b16mm"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+f16mm"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+f16f32dot"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+f16f32mm"));
// Assuming we listed every extension above, this should produce the same
// result.
@@ -1576,6 +1599,7 @@ TEST(TargetParserTest, AArch64ArchFeatures) {
EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a");
EXPECT_EQ(AArch64::ARMV9_5A.ArchFeature, "+v9.5a");
EXPECT_EQ(AArch64::ARMV9_6A.ArchFeature, "+v9.6a");
+ EXPECT_EQ(AArch64::ARMV9_7A.ArchFeature, "+v9.7a");
EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r");
}
@@ -1605,7 +1629,8 @@ TEST(TargetParserTest, AArch64ArchPartialOrder) {
for (const auto *A :
{&AArch64::ARMV9_1A, &AArch64::ARMV9_2A, &AArch64::ARMV9_3A,
- &AArch64::ARMV9_4A, &AArch64::ARMV9_5A, &AArch64::ARMV9_6A})
+ &AArch64::ARMV9_4A, &AArch64::ARMV9_5A, &AArch64::ARMV9_6A,
+ &AArch64::ARMV9_7A})
EXPECT_TRUE(A->implies(AArch64::ARMV9A));
EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A));
@@ -1624,6 +1649,7 @@ TEST(TargetParserTest, AArch64ArchPartialOrder) {
EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A));
EXPECT_TRUE(AArch64::ARMV9_5A.implies(AArch64::ARMV9_4A));
EXPECT_TRUE(AArch64::ARMV9_6A.implies(AArch64::ARMV9_5A));
+ EXPECT_TRUE(AArch64::ARMV9_7A.implies(AArch64::ARMV9_6A));
EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A));
EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A));
@@ -1713,6 +1739,18 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
{"pops", "nopops", "+pops", "-pops"},
{"sme-mop4", "nosme-mop4", "+sme-mop4", "-sme-mop4"},
{"sme-tmop", "nosme-tmop", "+sme-tmop", "-sme-tmop"},
+ {"cmh", "nocmh", "+cmh", "-cmh"},
+ {"lscp", "nolscp", "+lscp", "-lscp"},
+ {"tlbid", "notlbid", "+tlbid", "-tlbid"},
+ {"mpamv2", "nompamv2", "+mpamv2", "-mpamv2"},
+ {"mtetc", "nomtetc", "+mtetc", "-mtetc"},
+ {"gcie", "nogcie", "+gcie", "-gcie"},
+ {"sme2p3", "nosme2p3", "+sme2p3", "-sme2p3"},
+ {"sve2p3", "nosve2p3", "+sve2p3", "-sve2p3"},
+ {"sve-b16mm", "nosve-b16mm", "+sve-b16mm", "-sve-b16mm"},
+ {"f16mm", "nof16mm", "+f16mm", "-f16mm"},
+ {"f16f32dot", "nof16f32dot", "+f16f32dot", "-f16f32dot"},
+ {"f16f32mm", "nof16f32mm", "+f16f32mm", "-f16f32mm"},
};
for (unsigned i = 0; i < std::size(ArchExt); i++) {
@@ -1927,7 +1965,8 @@ AArch64ExtensionDependenciesBaseArchTestParams
{AArch64::ARMV9_6A, {"nofp", "fprcvt"}, {"fp-armv8", "fprcvt"}, {}},
{AArch64::ARMV9_6A, {"fprcvt", "nofp"}, {}, {"fp-armv8", "fprcvt"}},
- // simd -> {aes, sha2, sha3, sm4, f8f16mm, f8f32mm, faminmax, lut, fp8}
+ // simd -> {aes, sha2, sha3, sm4, f8f16mm, f8f32mm, faminmax, lut, fp8,
+ // f16f32dot, f16f32mm}
{AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}},
{AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}},
{AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},
@@ -1946,6 +1985,10 @@ AArch64ExtensionDependenciesBaseArchTestParams
{AArch64::ARMV9_6A, {"nosimd", "lut"}, {"neon", "lut"}, {}},
{AArch64::ARMV9_6A, {"fp8", "nosimd"}, {}, {"neon", "fp8"}},
{AArch64::ARMV9_6A, {"nosimd", "fp8"}, {"neon", "fp8"}, {}},
+ {AArch64::ARMV9_7A, {"nosimd", "f16f32mm"}, {"neon", "f16f32mm"}, {}},
+ {AArch64::ARMV9_7A, {"f16f32mm", "nosimd"}, {}, {"neon", "f16f32mm"}},
+ {AArch64::ARMV9_7A, {"nosimd", "f16f32dot"}, {"neon", "f16f32dot"}, {}},
+ {AArch64::ARMV9_7A, {"f16f32dot", "nosimd"}, {}, {"neon", "f16f32dot"}},
// fp8 -> {fp8dot4, fp8dot2}
{AArch64::ARMV9_6A, {"nofp8", "fp8dot4"}, {"fp8", "fp8dot4"}, {}},
@@ -1961,17 +2004,35 @@ AArch64ExtensionDependenciesBaseArchTestParams
{AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},
{AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},
- // fp16 -> {fp16fml, sve}
+ // fp16 -> {fp16fml, sve, f16f32dot, f16f32mm, f16mm}
{AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},
{AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},
{AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},
{AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},
+ {AArch64::ARMV9_7A, {"nofp16", "f16mm"}, {"fullfp16", "f16mm"}, {}},
+ {AArch64::ARMV9_7A, {"f16mm", "nofp16"}, {}, {"fullfp16", "f16mm"}},
+ {AArch64::ARMV9_7A,
+ {"nofp16", "f16f32mm"},
+ {"fullfp16", "f16f32mm"},
+ {}},
+ {AArch64::ARMV9_7A,
+ {"f16f32mm", "nofp16"},
+ {},
+ {"fullfp16", "f16f32mm"}},
+ {AArch64::ARMV9_7A,
+ {"nofp16", "f16f32dot"},
+ {"fullfp16", "f16f32dot"},
+ {}},
+ {AArch64::ARMV9_7A,
+ {"f16f32dot", "nofp16"},
+ {},
+ {"fullfp16", "f16f32dot"}},
// bf16 -> {sme}
{AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}},
{AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}},
- // sve -> {sve2, f32mm, f64mm, sve-f16f32mm}
+ // sve -> {sve2, f32mm, f64mm, sve-f16f32mm, sve-b16mm}
{AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}},
{AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}},
{AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},
@@ -1986,6 +2047,8 @@ AArch64ExtensionDependenciesBaseArchTestParams
{"sve-f16f32mm", "nosve"},
{},
{"sve", "sve-f16f32mm"}},
+ {AArch64::ARMV9_7A, {"nosve", "sve-b16mm"}, {"sve", "sve-b16mm"}, {}},
+ {AArch64::ARMV9_7A, {"sve-b16mm", "nosve"}, {}, {"sve", "sve-b16mm"}},
// aes -> {sve-aes}
{AArch64::ARMV8A, {"noaes", "sve-aes"}, {"aes", "sve-aes"}, {}},
@@ -2031,6 +2094,10 @@ AArch64ExtensionDependenciesBaseArchTestParams
{AArch64::ARMV9_6A, {"nosve2p1", "sve2p2"}, {"sve2p1", "sve2p2"}, {}},
{AArch64::ARMV9_6A, {"sve2p2", "nosve2p1"}, {}, {"sve2p1", "sve2p2"}},
+ // sve2p2 -> {sve2p3}
+ {AArch64::ARMV9_7A, {"nosve2p2", "sve2p3"}, {"sve2p2", "sve2p3"}, {}},
+ {AArch64::ARMV9_7A, {"sve2p3", "nosve2p2"}, {}, {"sve2p2", "sve2p3"}},
+
// sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}
{AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}},
{AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}},
@@ -2084,6 +2151,10 @@ AArch64ExtensionDependenciesBaseArchTestParams
{AArch64::ARMV9_6A, {"nosme2p1", "sme2p2"}, {"sme2p2", "sme2p1"}, {}},
{AArch64::ARMV9_6A, {"sme2p2", "nosme2p1"}, {}, {"sme2p1", "sme2p2"}},
+ // sme2p2 -> {sme2p3}
+ {AArch64::ARMV9_7A, {"nosme2p2", "sme2p3"}, {"sme2p3", "sme2p2"}, {}},
+ {AArch64::ARMV9_7A, {"sme2p3", "nosme2p2"}, {}, {"sme2p2", "sme2p3"}},
+
// fp8 -> {sme-f8f16, sme-f8f32, f8f16mm, f8f32mm, fp8dot4, fp8dot2,
// ssve-fp8dot4, ssve-fp8dot2}
{AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
diff --git a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
index 3c9374b..4235c93 100644
--- a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
+++ b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
@@ -716,3 +716,32 @@ attributes #0 = { presplitcoroutine }
EXPECT_FALSE(llvm::isPresplitCoroSuspendExitEdge(
*ExitN.getSinglePredecessor(), ExitN));
}
+
+TEST(BasicBlockUtils, BasicBlockPrintable) {
+ std::string S;
+ std::string SCheck;
+ llvm::raw_string_ostream OS{S};
+ llvm::raw_string_ostream OSCheck{SCheck};
+
+ LLVMContext C;
+ std::unique_ptr<Module> M = parseIR(C, R"IR(
+define void @foo() {
+ br label %bb0
+bb0:
+ br label %.exit
+.exit:
+ ret void
+}
+)IR");
+
+ Function *F = M->getFunction("foo");
+ for (const BasicBlock &BB : *F) {
+ OS << printBasicBlock(&BB);
+ BB.printAsOperand(OSCheck);
+ EXPECT_EQ(OS.str(), OSCheck.str());
+ S.clear();
+ SCheck.clear();
+ }
+ OS << printBasicBlock(nullptr);
+ EXPECT_EQ(OS.str(), "<nullptr>");
+}
diff --git a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
index 2a0f500..e108c4d 100644
--- a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
@@ -33,7 +33,7 @@ TEST_F(VPDominatorTreeTest, DominanceNoRegionsTest) {
VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("VPBB2");
VPBasicBlock *VPBB3 = Plan.createVPBasicBlock("VPBB3");
VPBasicBlock *VPBB4 = Plan.createVPBasicBlock("VPBB4");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB1, VPBB4);
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB1, VPBB4);
VPBB2->setParent(R1);
VPBB3->setParent(R1);
@@ -99,7 +99,7 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("");
VPBasicBlock *R1BB3 = Plan.createVPBasicBlock("");
VPBasicBlock *R1BB4 = Plan.createVPBasicBlock("");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R1BB1, R1BB4, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R1BB1, R1BB4);
R1BB2->setParent(R1);
R1BB3->setParent(R1);
VPBlockUtils::connectBlocks(VPBB0, R1);
@@ -112,7 +112,7 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("");
VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R2BB2, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R1, R2);
@@ -171,12 +171,12 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
VPBasicBlock *R1BB1 = Plan.createVPBasicBlock("R1BB1");
VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("R1BB2");
VPBasicBlock *R1BB3 = Plan.createVPBasicBlock("R1BB3");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R1BB1, R1BB3, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R1BB1, R1BB3);
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
VPBasicBlock *R2BB3 = Plan.createVPBasicBlock("R2BB#");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R2BB3, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB3);
R2BB2->setParent(R2);
VPBlockUtils::connectBlocks(R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R2BB2, R2BB1);
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index db64c75..c1791dfa 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -269,7 +269,7 @@ TEST_F(VPBasicBlockTest, getPlan) {
// VPBasicBlock is the entry into the VPlan, followed by a region.
VPBasicBlock *R1BB1 = Plan.createVPBasicBlock("");
VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R1BB1, R1BB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R1BB1, R1BB2);
VPBlockUtils::connectBlocks(R1BB1, R1BB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
@@ -286,12 +286,12 @@ TEST_F(VPBasicBlockTest, getPlan) {
VPlan &Plan = getPlan();
VPBasicBlock *R1BB1 = Plan.createVPBasicBlock("");
VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R1BB1, R1BB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R1BB1, R1BB2);
VPBlockUtils::connectBlocks(R1BB1, R1BB2);
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("");
VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R2BB2, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R2BB1, R2BB2);
VPBasicBlock *VPBB1 = Plan.getEntry();
@@ -369,7 +369,7 @@ TEST_F(VPBasicBlockTest, TraversingIteratorTest) {
VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("");
VPBasicBlock *R1BB3 = Plan.createVPBasicBlock("");
VPBasicBlock *R1BB4 = Plan.createVPBasicBlock("");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R1BB1, R1BB4, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R1BB1, R1BB4);
R1BB2->setParent(R1);
R1BB3->setParent(R1);
VPBlockUtils::connectBlocks(VPBB0, R1);
@@ -382,7 +382,7 @@ TEST_F(VPBasicBlockTest, TraversingIteratorTest) {
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("");
VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R2BB2, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R1, R2);
@@ -467,12 +467,12 @@ TEST_F(VPBasicBlockTest, TraversingIteratorTest) {
VPBasicBlock *R1BB1 = Plan.createVPBasicBlock("R1BB1");
VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("R1BB2");
VPBasicBlock *R1BB3 = Plan.createVPBasicBlock("R1BB3");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R1BB1, R1BB3, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R1BB1, R1BB3);
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
VPBasicBlock *R2BB3 = Plan.createVPBasicBlock("R2BB3");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R2BB3, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB3);
R2BB2->setParent(R2);
VPBlockUtils::connectBlocks(R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R2BB2, R2BB1);
@@ -537,10 +537,10 @@ TEST_F(VPBasicBlockTest, TraversingIteratorTest) {
VPlan &Plan = getPlan();
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R2BB2, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB2);
VPBlockUtils::connectBlocks(R2BB1, R2BB2);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R2, R2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R2, R2);
R2->setParent(R1);
VPBasicBlock *VPBB1 = Plan.getEntry();
@@ -590,14 +590,14 @@ TEST_F(VPBasicBlockTest, TraversingIteratorTest) {
//
VPlan &Plan = getPlan();
VPBasicBlock *R3BB1 = Plan.createVPBasicBlock("R3BB1");
- VPRegionBlock *R3 = Plan.createVPRegionBlock(R3BB1, R3BB1, "R3");
+ VPRegionBlock *R3 = Plan.createLoopRegion("R3", R3BB1, R3BB1);
VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
- VPRegionBlock *R2 = Plan.createVPRegionBlock(R2BB1, R3, "R2");
+ VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R3);
R3->setParent(R2);
VPBlockUtils::connectBlocks(R2BB1, R3);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(R2, R2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", R2, R2);
R2->setParent(R1);
VPBasicBlock *VPBB1 = Plan.getEntry();
@@ -687,7 +687,7 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) {
VPlan &Plan = getPlan();
VPBasicBlock *VPBB1 = Plan.createVPBasicBlock("VPBB1");
VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("VPBB2");
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
auto *WidenPhi = new VPWidenPHIRecipe(nullptr);
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
index c2f045b..50ad4d5 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
@@ -32,7 +32,7 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) {
VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("");
VPBB2->appendRecipe(CanIV);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
@@ -71,7 +71,7 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) {
VPBB2->appendRecipe(DefI);
VPBB2->appendRecipe(BranchOnCond);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
@@ -117,7 +117,7 @@ TEST_F(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) {
VPBlockUtils::connectBlocks(VPBB2, VPBB3);
VPBlockUtils::connectBlocks(VPBB3, VPBB4);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB4, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB4);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBB3->setParent(R1);
@@ -160,7 +160,7 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) {
auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {});
VPBB3->appendRecipe(CanIV);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB3, VPBB3, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB3, VPBB3);
VPBlockUtils::connectBlocks(VPBB1, VPBB2);
VPBlockUtils::connectBlocks(VPBB2, R1);
VPBlockUtils::connectBlocks(VPBB4, Plan.getScalarHeader());
@@ -200,7 +200,7 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) {
VPBB2->appendRecipe(CanIV);
VPBB2->appendRecipe(BranchOnCond);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBlockUtils::connectBlocks(VPBB1, R1);
@@ -237,7 +237,7 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsInsideRegion) {
VPBlockUtils::connectBlocks(VPBB2, VPBB3);
VPBlockUtils::connectBlocks(VPBB2, VPBB3);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB3, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB3);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBB3->setParent(R1);
@@ -270,7 +270,7 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) {
VPBB1->appendRecipe(DefI);
VPBB2->appendRecipe(BranchOnCond);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
@@ -302,7 +302,7 @@ TEST_F(VPVerifierTest, NonHeaderPHIInHeader) {
VPBB2->appendRecipe(IRPhi);
VPBB2->appendRecipe(BranchOnCond);
- VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1");
+ VPRegionBlock *R1 = Plan.createLoopRegion("R1", VPBB2, VPBB2);
VPBlockUtils::connectBlocks(VPBB1, R1);
VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());