diff options
Diffstat (limited to 'llvm/unittests')
67 files changed, 1664 insertions, 654 deletions
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index ca9f9f1..4cb537d 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -3823,4 +3823,87 @@ TEST(APIntTest, Fshr) { -8193); } +TEST(APIntTest, clmul) { + EXPECT_EQ(APIntOps::clmul(APInt(4, 1), APInt(4, 2)).getZExtValue(), 2U); + EXPECT_EQ(APIntOps::clmul(APInt(4, 5), APInt(4, 6)).getZExtValue(), 14U); + EXPECT_EQ(APIntOps::clmul(APInt(4, -4, /*isSigned*/ true), + APInt(4, 2, /*isSigned*/ false)) + .getSExtValue(), + -8); + EXPECT_EQ(APIntOps::clmul(APInt(4, -4, /*isSigned*/ true), + APInt(4, -5, /*isSigned*/ true)) + .getSExtValue(), + 4); + EXPECT_EQ(APIntOps::clmul(APInt(8, 0), APInt(8, 255)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmul(APInt(8, 15), APInt(8, 15)).getZExtValue(), 85U); + EXPECT_EQ(APIntOps::clmul(APInt(8, 1), APInt(8, 2)).getZExtValue(), 2U); + EXPECT_EQ(APIntOps::clmul(APInt(64, 0, /*isSigned*/ true), + APInt(64, 9223372036854775807, /*isSigned*/ true)) + .getSExtValue(), + 0); + EXPECT_EQ(APIntOps::clmul(APInt(64, 1, /*isSigned*/ true), + APInt(64, 2, /*isSigned*/ true)) + .getSExtValue(), + 2); + EXPECT_EQ(APIntOps::clmul(APInt(16, -2, /*isSigned*/ true), + APInt(16, -1, /*isSigned*/ true)) + .getSExtValue(), + -21846); +} + +TEST(APIntTest, clmulr) { + EXPECT_EQ(APIntOps::clmulr(APInt(4, 1), APInt(4, 2)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulr(APInt(4, 5), APInt(4, 6)).getZExtValue(), 3U); + EXPECT_EQ(APIntOps::clmulr(APInt(4, -4, /*isSigned*/ true), + APInt(4, 2, /*isSigned*/ false)) + .getSExtValue(), + 3); + EXPECT_EQ(APIntOps::clmulr(APInt(4, -4, /*isSigned*/ true), + APInt(4, -5, /*isSigned*/ true)) + .getSExtValue(), + -2); + EXPECT_EQ(APIntOps::clmulr(APInt(8, 0), APInt(8, 255)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulr(APInt(8, 15), APInt(8, 15)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulr(APInt(8, 1), APInt(8, 2)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulr(APInt(64, 0, /*isSigned*/ true), + APInt(64, 9223372036854775807, /*isSigned*/ true)) + .getSExtValue(), + 0); + EXPECT_EQ(APIntOps::clmulr(APInt(64, 1, /*isSigned*/ true), + APInt(64, 2, /*isSigned*/ true)) + .getSExtValue(), + 0); + EXPECT_EQ(APIntOps::clmulr(APInt(16, -2, /*isSigned*/ true), + APInt(16, -1, /*isSigned*/ true)) + .getSExtValue(), + -21845); +} + +TEST(APIntTest, clmulh) { + EXPECT_EQ(APIntOps::clmulh(APInt(4, 1), APInt(4, 2)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulh(APInt(4, 5), APInt(4, 6)).getZExtValue(), 1U); + EXPECT_EQ(APIntOps::clmulh(APInt(4, -4, /*isSigned*/ true), + APInt(4, 2, /*isSigned*/ false)) + .getSExtValue(), + 1); + EXPECT_EQ(APIntOps::clmulh(APInt(4, -4, /*isSigned*/ true), + APInt(4, -5, /*isSigned*/ true)) + .getSExtValue(), + 7); + EXPECT_EQ(APIntOps::clmulh(APInt(8, 0), APInt(8, 255)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulh(APInt(8, 15), APInt(8, 15)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulh(APInt(8, 1), APInt(8, 2)).getZExtValue(), 0U); + EXPECT_EQ(APIntOps::clmulh(APInt(64, 0, /*isSigned*/ true), + APInt(64, 9223372036854775807, /*isSigned*/ true)) + .getSExtValue(), + 0); + EXPECT_EQ(APIntOps::clmulh(APInt(64, 1, /*isSigned*/ true), + APInt(64, 2, /*isSigned*/ true)) + .getSExtValue(), + 0); + EXPECT_EQ(APIntOps::clmulh(APInt(16, -2, /*isSigned*/ true), + APInt(16, -1, /*isSigned*/ true)) + .getSExtValue(), + 21845); +} } // end anonymous namespace diff --git a/llvm/unittests/ADT/BitVectorTest.cpp b/llvm/unittests/ADT/BitVectorTest.cpp index e13523b..d3200b7 100644 --- a/llvm/unittests/ADT/BitVectorTest.cpp +++ b/llvm/unittests/ADT/BitVectorTest.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" #include "gtest/gtest.h" +#include <initializer_list> using namespace llvm; @@ -835,19 +836,27 @@ TYPED_TEST(BitVectorTest, BinOps) { A.resize(65); EXPECT_FALSE(A.anyCommon(B)); EXPECT_FALSE(B.anyCommon(B)); + EXPECT_TRUE(A.subsetOf(B)); + EXPECT_TRUE(B.subsetOf(A)); B.resize(64); A.set(64); EXPECT_FALSE(A.anyCommon(B)); EXPECT_FALSE(B.anyCommon(A)); + EXPECT_FALSE(A.subsetOf(B)); + EXPECT_TRUE(B.subsetOf(A)); B.set(63); EXPECT_FALSE(A.anyCommon(B)); EXPECT_FALSE(B.anyCommon(A)); + EXPECT_FALSE(A.subsetOf(B)); + EXPECT_FALSE(B.subsetOf(A)); A.set(63); EXPECT_TRUE(A.anyCommon(B)); EXPECT_TRUE(B.anyCommon(A)); + EXPECT_FALSE(A.subsetOf(B)); + EXPECT_TRUE(B.subsetOf(A)); B.resize(70); B.set(64); @@ -855,6 +864,87 @@ TYPED_TEST(BitVectorTest, BinOps) { A.resize(64); EXPECT_FALSE(A.anyCommon(B)); EXPECT_FALSE(B.anyCommon(A)); + EXPECT_FALSE(A.subsetOf(B)); + EXPECT_FALSE(B.subsetOf(A)); + + B.set(63); + B.reset(64); + EXPECT_TRUE(A.anyCommon(B)); + EXPECT_TRUE(B.anyCommon(A)); + EXPECT_TRUE(A.subsetOf(B)); + EXPECT_TRUE(B.subsetOf(A)); +} + +template <typename VecType> +static inline VecType +createBitVectorFromBits(uint32_t Size, std::initializer_list<int> SetBits) { + VecType V; + V.resize(Size); + for (int BitIndex : SetBits) + V.set(BitIndex); + return V; +} + +TYPED_TEST(BitVectorTest, BinOpsLiteral) { + // More tests of binary operations with more focus on the semantics and + // less focus on mutability. + + auto AnyCommon = [](uint32_t SizeLHS, std::initializer_list<int> SetBitsLHS, + uint32_t SizeRHS, std::initializer_list<int> SetBitsRHS) { + auto LHS = createBitVectorFromBits<TypeParam>(SizeLHS, SetBitsLHS); + auto RHS = createBitVectorFromBits<TypeParam>(SizeRHS, SetBitsRHS); + return LHS.anyCommon(RHS); + }; + auto SubsetOf = [](uint32_t SizeLHS, std::initializer_list<int> SetBitsLHS, + uint32_t SizeRHS, std::initializer_list<int> SetBitsRHS) { + auto LHS = createBitVectorFromBits<TypeParam>(SizeLHS, SetBitsLHS); + auto RHS = createBitVectorFromBits<TypeParam>(SizeRHS, SetBitsRHS); + return LHS.subsetOf(RHS); + }; + + // clang-format off + + // Test small-sized vectors. + EXPECT_TRUE (AnyCommon(10, {1, 2, 3}, 10, {3, 4, 5})); + EXPECT_FALSE(AnyCommon(10, {1, 2, 3}, 10, {4, 5})); + + EXPECT_FALSE(SubsetOf(10, {1, 2, 3}, 10, {2, 3, 4})); + EXPECT_TRUE (SubsetOf(10, {2, 3}, 10, {2, 3, 4})); + EXPECT_FALSE(SubsetOf(10, {1, 2, 3}, 10, {2, 3})); + EXPECT_TRUE (SubsetOf(10, {1, 2, 3}, 10, {1, 2, 3})); + + // Test representations of empty sets of various sizes. + EXPECT_FALSE(AnyCommon(10, {}, 10, {})); + EXPECT_FALSE(AnyCommon(10, {}, 123, {})); + EXPECT_FALSE(AnyCommon(123, {}, 10, {})); + EXPECT_FALSE(AnyCommon(123, {}, 123, {})); + EXPECT_TRUE(SubsetOf(10, {}, 10, {})); + EXPECT_TRUE(SubsetOf(10, {}, 123, {})); + EXPECT_TRUE(SubsetOf(123, {}, 10, {})); + EXPECT_TRUE(SubsetOf(123, {}, 123, {})); + + // Test handling of the remainder words. + EXPECT_FALSE(AnyCommon(10, {1, 2}, 123, {5, 70})); + EXPECT_TRUE (AnyCommon(10, {1, 2}, 123, {1, 70})); + EXPECT_FALSE(AnyCommon(123, {5, 70}, 10, {1, 2})); + EXPECT_TRUE (AnyCommon(123, {1, 70}, 10, {1, 2})); + + EXPECT_FALSE(AnyCommon(10, {1, 2}, 123, {5})); + EXPECT_TRUE (AnyCommon(10, {1, 2}, 123, {1})); + EXPECT_FALSE(AnyCommon(123, {5}, 10, {1, 2})); + EXPECT_TRUE (AnyCommon(123, {1}, 10, {1, 2})); + + EXPECT_FALSE(SubsetOf(10, {1, 2}, 123, {2, 70})); + EXPECT_TRUE (SubsetOf(10, {1, 2}, 123, {1, 2, 70})); + EXPECT_FALSE(SubsetOf(123, {2, 70}, 10, {1, 2})); + EXPECT_FALSE(SubsetOf(123, {1, 2, 70}, 10, {1, 2})); + + EXPECT_FALSE(SubsetOf(10, {1, 2}, 123, {2})); + EXPECT_TRUE (SubsetOf(10, {1, 2}, 123, {1, 2})); + EXPECT_TRUE (SubsetOf(123, {2}, 10, {1, 2})); + EXPECT_TRUE (SubsetOf(123, {1, 2}, 10, {1, 2})); + + // clang-format on } using RangeList = std::vector<std::pair<int, int>>; diff --git a/llvm/unittests/ADT/CombinationGeneratorTest.cpp b/llvm/unittests/ADT/CombinationGeneratorTest.cpp index 219e18b..cf187e6 100644 --- a/llvm/unittests/ADT/CombinationGeneratorTest.cpp +++ b/llvm/unittests/ADT/CombinationGeneratorTest.cpp @@ -13,7 +13,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include <cstddef> -#include <iterator> #include <vector> using namespace llvm; diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp index 273ee09..553d159 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp @@ -200,6 +200,14 @@ TYPED_TEST(DenseMapTest, AtTest) { EXPECT_EQ(this->getValue(0), this->Map.at(this->getKey(0))); EXPECT_EQ(this->getValue(1), this->Map.at(this->getKey(1))); EXPECT_EQ(this->getValue(2), this->Map.at(this->getKey(2))); + + this->Map.at(this->getKey(0)) = this->getValue(1); + EXPECT_EQ(this->getValue(1), this->Map.at(this->getKey(0))); + + const auto &ConstMap = this->Map; + EXPECT_EQ(this->getValue(1), ConstMap.at(this->getKey(0))); + EXPECT_EQ(this->getValue(1), ConstMap.at(this->getKey(1))); + EXPECT_EQ(this->getValue(2), ConstMap.at(this->getKey(2))); } // Test clear() method diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp index 9809a92..fdabdca 100644 --- a/llvm/unittests/ADT/FunctionExtrasTest.cpp +++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp @@ -11,7 +11,6 @@ #include "gtest/gtest.h" #include <memory> -#include <type_traits> using namespace llvm; diff --git a/llvm/unittests/ADT/IntervalMapTest.cpp b/llvm/unittests/ADT/IntervalMapTest.cpp index 38f397f..06848e2 100644 --- a/llvm/unittests/ADT/IntervalMapTest.cpp +++ b/llvm/unittests/ADT/IntervalMapTest.cpp @@ -8,7 +8,6 @@ #include "llvm/ADT/IntervalMap.h" #include "gtest/gtest.h" -#include <type_traits> using namespace llvm; diff --git a/llvm/unittests/ADT/MapVectorTest.cpp b/llvm/unittests/ADT/MapVectorTest.cpp index 639e1a1..b11d460 100644 --- a/llvm/unittests/ADT/MapVectorTest.cpp +++ b/llvm/unittests/ADT/MapVectorTest.cpp @@ -292,6 +292,39 @@ TEST(MapVectorTest, GetArrayRef) { EXPECT_TRUE(MV.getArrayRef().equals({std::pair(100, 99), std::pair(99, 98)})); } +TEST(MapVectorTest, AtTest) { + MapVector<int, int> MV; + MV[0] = 10; + MV[1] = 11; + EXPECT_EQ(MV.at(0), 10); + EXPECT_EQ(MV.at(1), 11); + + MV.at(1) = 12; + EXPECT_EQ(MV.at(1), 12); + + const auto &ConstMV = MV; + EXPECT_EQ(ConstMV.at(0), 10); + EXPECT_EQ(ConstMV.at(1), 12); +} + +TEST(MapVectorTest, KeysValuesIterator) { + MapVector<int, int> MV; + + MV.insert(std::make_pair(1, 11)); + MV.insert(std::make_pair(2, 12)); + MV.insert(std::make_pair(3, 13)); + MV.insert(std::make_pair(4, 14)); + MV.insert(std::make_pair(5, 15)); + MV.insert(std::make_pair(6, 16)); + + EXPECT_THAT(MV.keys(), testing::ElementsAre(1, 2, 3, 4, 5, 6)); + EXPECT_THAT(MV.values(), testing::ElementsAre(11, 12, 13, 14, 15, 16)); + + const MapVector<int, int> &ConstMV = MV; + EXPECT_THAT(ConstMV.keys(), testing::ElementsAre(1, 2, 3, 4, 5, 6)); + EXPECT_THAT(ConstMV.values(), testing::ElementsAre(11, 12, 13, 14, 15, 16)); +} + template <class IntType> struct MapVectorMappedTypeTest : ::testing::Test { using int_type = IntType; }; diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 8556777..e356f6b 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -1693,6 +1693,30 @@ TEST(STLExtrasTest, ProductOf) { EXPECT_EQ(product_of(V3), 2.0f); } +TEST(STLExtrasTest, ReverseConditionally) { + std::vector<char> foo = {'a', 'b', 'c'}; + + // Test backwards. + std::vector<char> ReverseResults; + for (char Value : llvm::reverse_conditionally(foo, /*ShouldReverse=*/true)) { + ReverseResults.emplace_back(Value); + } + EXPECT_THAT(ReverseResults, ElementsAre('c', 'b', 'a')); + + // Test forwards. + std::vector<char> ForwardResults; + for (char Value : llvm::reverse_conditionally(foo, /*ShouldReverse=*/false)) { + ForwardResults.emplace_back(Value); + } + EXPECT_THAT(ForwardResults, ElementsAre('a', 'b', 'c')); + + // Test modifying collection. + for (char &Value : llvm::reverse_conditionally(foo, /*ShouldReverse=*/true)) { + ++Value; + } + EXPECT_THAT(foo, ElementsAre('b', 'c', 'd')); +} + struct Foo; struct Bar {}; diff --git a/llvm/unittests/ADT/SetVectorTest.cpp b/llvm/unittests/ADT/SetVectorTest.cpp index ff3c876..6230472 100644 --- a/llvm/unittests/ADT/SetVectorTest.cpp +++ b/llvm/unittests/ADT/SetVectorTest.cpp @@ -52,7 +52,7 @@ TEST(SetVector, ContainsTest) { } TEST(SetVector, ConstPtrKeyTest) { - SetVector<int *, SmallVector<int *, 8>, SmallPtrSet<const int *, 8>> S, T; + SetVector<int *> S, T; int i, j, k, m, n; S.insert(&i); diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp index 787a324..3029f10 100644 --- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp +++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp @@ -64,7 +64,7 @@ TEST_F(TargetLibraryInfoTest, InvalidProto) { auto *StructTy = StructType::getTypeByName(Context, "foo"); auto *InvalidFTy = FunctionType::get(StructTy, /*isVarArg=*/false); - for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) { + for (unsigned FI = LibFunc::Begin_LibFunc; FI != LibFunc::End_LibFunc; ++FI) { LibFunc LF = (LibFunc)FI; auto *F = cast<Function>( M->getOrInsertFunction(TLI.getName(LF), InvalidFTy).getCallee()); @@ -694,7 +694,7 @@ TEST_F(TargetLibraryInfoTest, ValidProto) { "declare i8* @__kmpc_alloc_shared(i64)\n" "declare void @__kmpc_free_shared(i8*, i64)\n"); - for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) { + for (unsigned FI = LibFunc::Begin_LibFunc; FI != LibFunc::End_LibFunc; ++FI) { LibFunc LF = (LibFunc)FI; // Make sure everything is available; we're not testing target defaults. TLII.setAvailable(LF); diff --git a/llvm/unittests/CAS/CASTestConfig.h b/llvm/unittests/CAS/CASTestConfig.h index b1c0e59..e3139c9 100644 --- a/llvm/unittests/CAS/CASTestConfig.h +++ b/llvm/unittests/CAS/CASTestConfig.h @@ -15,6 +15,11 @@ #include "gtest/gtest.h" #include <memory> +#ifdef _WIN32 +#include "llvm/Support/VersionTuple.h" +#include "llvm/Support/Windows/WindowsSupport.h" +#endif + namespace llvm::unittest::cas { class MockEnv { void anchor(); @@ -68,6 +73,11 @@ protected: } void SetUp() override { +#ifdef _WIN32 + // Temporarily disable CAS tests on pre windows 11 OS. + if (llvm::GetWindowsOSVersion() < llvm::VersionTuple(10, 0, 0, 22000)) + GTEST_SKIP() << "CAS tests skipped on older windows version"; +#endif NextCASIndex = 0; setMaxOnDiskCASMappingSize(); } diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt index 4d07462..80d1013 100644 --- a/llvm/unittests/CodeGen/CMakeLists.txt +++ b/llvm/unittests/CodeGen/CMakeLists.txt @@ -49,7 +49,6 @@ add_llvm_unittest(CodeGenTests TypeTraitsTest.cpp TargetOptionsTest.cpp TestAsmPrinter.cpp - MLRegAllocDevelopmentFeatures.cpp X86MCInstLowerTest.cpp ) diff --git a/llvm/unittests/CodeGen/GlobalISel/InstructionSelectTest.cpp b/llvm/unittests/CodeGen/GlobalISel/InstructionSelectTest.cpp index 7fbccf7..2237983 100644 --- a/llvm/unittests/CodeGen/GlobalISel/InstructionSelectTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/InstructionSelectTest.cpp @@ -59,10 +59,8 @@ TEST_F(AArch64GISelMITest, TestInstructionSelectErase) { GTEST_SKIP(); legacy::PassManager PM; - std::unique_ptr<TargetPassConfig> TPC(TM->createPassConfig(PM)); EraseMockInstructionSelector ISel; - ISel.TPC = TPC.get(); for (auto &MI : *EntryMBB) { ISel.MIs.push_back(&MI); } diff --git a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp index 235a53d..5211a6c 100644 --- a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp +++ b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp @@ -955,7 +955,7 @@ TEST_F(InstrRefLDVTest, MLocSingleBlock) { // Add a new register to be tracked, and insert it into the transfer function // as a copy. The output of $rax should be the live-in value of $rsp. Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); TransferFunc[0].insert({RspLoc, ValueIDNum(0, 1, RspLoc)}); TransferFunc[0].insert({RaxLoc, ValueIDNum(0, 0, RspLoc)}); initValueArray(MInLocs, 1, 2); @@ -980,7 +980,7 @@ TEST_F(InstrRefLDVTest, MLocDiamondBlocks) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(4, 2); @@ -1194,7 +1194,7 @@ TEST_F(InstrRefLDVTest, MLocSimpleLoop) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(3, 2); @@ -1292,7 +1292,7 @@ TEST_F(InstrRefLDVTest, MLocNestedLoop) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(5, 2); @@ -1493,7 +1493,7 @@ TEST_F(InstrRefLDVTest, MLocNoDominatingLoop) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(5, 2); @@ -1648,7 +1648,7 @@ TEST_F(InstrRefLDVTest, MLocBadlyNestedLoops) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(5, 2); @@ -1780,7 +1780,7 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(4, 2); @@ -1976,7 +1976,7 @@ TEST_F(InstrRefLDVTest, pickVPHILocLoops) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); auto [MInLocs, MOutLocs] = allocValueTables(3, 2); @@ -2104,9 +2104,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocBadlyNestedLoops) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); Register RBX = getRegByName("RBX"); - LocIdx RbxLoc = MTracker->lookupOrTrackRegister(RBX); + LocIdx RbxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RBX)); auto [MInLocs, MOutLocs] = allocValueTables(5, 3); @@ -2256,7 +2256,7 @@ TEST_F(InstrRefLDVTest, vlocJoinDiamond) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - MTracker->lookupOrTrackRegister(RAX); + MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); DbgOpID LiveInRspID = DbgOpID(false, 0); DbgOpID LiveInRaxID = DbgOpID(false, 1); @@ -2440,7 +2440,7 @@ TEST_F(InstrRefLDVTest, vlocJoinLoops) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - MTracker->lookupOrTrackRegister(RAX); + MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); DbgOpID LiveInRspID = DbgOpID(false, 0); DbgOpID LiveInRaxID = DbgOpID(false, 1); @@ -2538,9 +2538,9 @@ TEST_F(InstrRefLDVTest, vlocJoinBadlyNestedLoops) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - MTracker->lookupOrTrackRegister(RAX); + MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); Register RBX = getRegByName("RBX"); - MTracker->lookupOrTrackRegister(RBX); + MTracker->lookupOrTrackRegister(MTracker->getLocID(RBX)); DbgOpID LiveInRspID = DbgOpID(false, 0); DbgOpID LiveInRaxID = DbgOpID(false, 1); @@ -2678,7 +2678,7 @@ TEST_F(InstrRefLDVTest, VLocDiamondBlocks) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); unsigned EntryBlk = 0, RetBlk = 3; @@ -2896,7 +2896,7 @@ TEST_F(InstrRefLDVTest, VLocSimpleLoop) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); unsigned EntryBlk = 0, LoopBlk = 1; @@ -3175,7 +3175,7 @@ TEST_F(InstrRefLDVTest, VLocNestedLoop) { ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); Register RAX = getRegByName("RAX"); - LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); + LocIdx RaxLoc = MTracker->lookupOrTrackRegister(MTracker->getLocID(RAX)); unsigned EntryBlk = 0, Loop1Blk = 1, Loop2Blk = 2; diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc index 783267a..c5e1c74 100644 --- a/llvm/unittests/CodeGen/MFCommon.inc +++ b/llvm/unittests/CodeGen/MFCommon.inc @@ -2,7 +2,8 @@ // depending on a real target. class BogusTargetLowering : public TargetLowering { public: - BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {} + BogusTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI) + : TargetLowering(TM, STI) {} }; class BogusFrameLowering : public TargetFrameLowering { @@ -45,7 +46,7 @@ public: static RegClassWeight Bogus{1, 16}; return Bogus; } - unsigned getRegUnitWeight(unsigned RegUnit) const override { return 1; } + unsigned getRegUnitWeight(MCRegUnit RegUnit) const override { return 1; } unsigned getNumRegPressureSets() const override { return 0; } const char *getRegPressureSetName(unsigned Idx) const override { return "bogus"; @@ -59,7 +60,7 @@ public: static const int Bogus[] = {0, -1}; return &Bogus[0]; } - const int *getRegUnitPressureSets(unsigned RegUnit) const override { + const int *getRegUnitPressureSets(MCRegUnit RegUnit) const override { static const int Bogus[] = {0, -1}; return &Bogus[0]; } @@ -87,7 +88,7 @@ public: BogusSubtarget(TargetMachine &TM) : TargetSubtargetInfo(Triple(""), "", "", "", {}, {}, {}, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr), - FL(), TL(TM) {} + FL(), TL(TM, *this) {} ~BogusSubtarget() override = default; const TargetFrameLowering *getFrameLowering() const override { return &FL; } diff --git a/llvm/unittests/CodeGen/MLRegAllocDevelopmentFeatures.cpp b/llvm/unittests/CodeGen/MLRegAllocDevelopmentFeatures.cpp deleted file mode 100644 index 00c2c3a..0000000 --- a/llvm/unittests/CodeGen/MLRegAllocDevelopmentFeatures.cpp +++ /dev/null @@ -1,293 +0,0 @@ -//===- MLRegAllocDevelopmentFeatures.cpp - test dev MLRegAlloc features ---===// -// -// 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 "../../lib/CodeGen/MLRegAllocEvictAdvisor.h" -#include "llvm/Analysis/NoInferenceModelRunner.h" -#include "llvm/CodeGen/CodeGenTargetMachineImpl.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/SlotIndexes.h" -#include "llvm/CodeGen/TargetFrameLowering.h" -#include "llvm/CodeGen/TargetInstrInfo.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/CodeGen.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/TargetParser/Triple.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include <string> -#include <vector> - -using namespace llvm; -using testing::ContainerEq; -using testing::Test; - -namespace { - -#include "MFCommon.inc" - -struct LRPosInfoIndexes { - size_t StartIndex; - size_t EndIndex; - size_t PhysReg; -}; - -class RegAllocDevelopmentFeaturesTest : public ::Test { -protected: - SmallVector<LRStartEndInfo> - setupOverlapProblem(const SmallVectorImpl<LRPosInfoIndexes> &Segments, - simple_ilist<IndexListEntry> &IndexList) { - SmallVector<LRStartEndInfo> PositionsToReturn; - PositionsToReturn.reserve(Segments.size()); - for (auto CurrentPosIndexInfo : Segments) { - LRStartEndInfo CurrentPosInfo = {}; - CurrentPosInfo.Pos = CurrentPosIndexInfo.PhysReg; - PositionsToReturn.push_back(CurrentPosInfo); - } - size_t CurrentSegmentIndex = 0; - size_t CurrentIndex = 0; - while (CurrentSegmentIndex < Segments.size()) { - auto *CurrentLEMem = static_cast<IndexListEntry *>( - Allocator.Allocate(sizeof(IndexListEntry), alignof(IndexListEntry))); - auto *CurrentListEntry = - new (CurrentLEMem) IndexListEntry(nullptr, CurrentIndex); - IndexList.push_back(*CurrentListEntry); - for (size_t CurrentPosInfoIndex = 0; - CurrentPosInfoIndex < Segments.size(); ++CurrentPosInfoIndex) { - if ((CurrentIndex / SlotIndex::InstrDist) == - Segments[CurrentPosInfoIndex].StartIndex) { - PositionsToReturn[CurrentPosInfoIndex].Begin = - SlotIndex(CurrentListEntry, 0); - } else if ((CurrentIndex / SlotIndex::InstrDist) == - Segments[CurrentPosInfoIndex].EndIndex) { - PositionsToReturn[CurrentPosInfoIndex].End = - SlotIndex(CurrentListEntry, 0); - ++CurrentSegmentIndex; - } - } - CurrentIndex += SlotIndex::InstrDist; - } - return PositionsToReturn; - } - - NoInferenceModelRunner setupModelRunner() { - const std::vector<TensorSpec> Inputs{ - TensorSpec::createSpec<int64_t>("instructions", InstructionsShape), - TensorSpec::createSpec<int64_t>("instructions_mapping", - InstructionsMappingShape), - TensorSpec::createSpec<float>("mbb_frequencies", MBBFrequencyShape), - TensorSpec::createSpec<int64_t>("mbb_mapping", InstructionsShape)}; - LLVMContext Ctx; - return NoInferenceModelRunner(Ctx, Inputs); - } - - std::vector<int64_t> - getExpectedMappingMatrix(SmallVectorImpl<LRPosInfoIndexes> &OverlapSetup) { - std::vector<int64_t> ExpectedMappingMatrix( - NumberOfInterferences * ModelMaxSupportedInstructionCount, 0); - for (auto NewSegment : OverlapSetup) { - for (size_t CurrentIndex = NewSegment.StartIndex; - CurrentIndex <= NewSegment.EndIndex; ++CurrentIndex) { - ExpectedMappingMatrix[NewSegment.PhysReg * - ModelMaxSupportedInstructionCount + - CurrentIndex] = 1; - } - } - return ExpectedMappingMatrix; - } - - void runOverlapTest(SmallVectorImpl<LRPosInfoIndexes> &OverlapSetup) { - simple_ilist<IndexListEntry> IndexList; - auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList); - NoInferenceModelRunner ModelRunner = setupModelRunner(); - size_t MaxIndex = 0; - for (size_t CurrentOverlap = 0; CurrentOverlap < OverlapSetup.size(); - ++CurrentOverlap) { - if (OverlapSetup[CurrentOverlap].EndIndex > - OverlapSetup[MaxIndex].EndIndex) { - MaxIndex = CurrentOverlap; - } - } - SlotIndex LastIndex = OverlapProblem[MaxIndex].End; - extractInstructionFeatures( - OverlapProblem, &ModelRunner, - [](SlotIndex InputSlot) -> int { return 0; }, - [](SlotIndex InputSlot) -> float { return 0.0f; }, - [](SlotIndex InputSlot) -> MachineBasicBlock * { return nullptr; }, 0, - 1, 2, 3, LastIndex); - std::vector<int64_t> MappingMatrix( - ModelRunner.getTensor<int64_t>(1), - ModelRunner.getTensor<int64_t>(1) + - NumberOfInterferences * ModelMaxSupportedInstructionCount); - ASSERT_THAT(MappingMatrix, - ContainerEq(getExpectedMappingMatrix(OverlapSetup))); - IndexList.clear(); - } - - BumpPtrAllocator Allocator; -}; - -// meta tests to ensure that test setup works correctly - -TEST_F(RegAllocDevelopmentFeaturesTest, - MetaOverlapInstructionDistancesAreCorrect) { - SmallVector<LRPosInfoIndexes, 2> OverlapSetup; - OverlapSetup.push_back({0, 5, 0}); - OverlapSetup.push_back({5, 10, 0}); - simple_ilist<IndexListEntry> IndexList; - auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList); - ASSERT_EQ(OverlapProblem[0].End.distance(OverlapProblem[1].End), - 5 * SlotIndex::InstrDist); - ASSERT_EQ(OverlapProblem[0].End.distance(OverlapProblem[1].Begin), 0); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, MetaSlotIndicesAreValid) { - SmallVector<LRPosInfoIndexes, 1> OverlapSetup; - OverlapSetup.push_back({0, 10, 0}); - simple_ilist<IndexListEntry> IndexList; - auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList); - ASSERT_TRUE(OverlapProblem[0].Begin.isValid()); - ASSERT_TRUE(OverlapProblem[0].End.isValid()); -} - -// Testing of feature extraction for per-instruction features - -TEST_F(RegAllocDevelopmentFeaturesTest, InstructionOpcodesAreCorrect) { - SmallVector<LRPosInfoIndexes, 1> OverlapSetup; - OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 0}); - simple_ilist<IndexListEntry> IndexList; - auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList); - NoInferenceModelRunner ModelRunner = setupModelRunner(); - SlotIndex LastIndex = OverlapProblem[0].End; - SlotIndex FirstIndex = OverlapProblem[0].Begin; - extractInstructionFeatures( - OverlapProblem, &ModelRunner, - [FirstIndex](SlotIndex InputSlot) -> int { - return FirstIndex.distance(InputSlot) / SlotIndex::InstrDist; - }, - [](SlotIndex InputSlot) -> float { return 0.0f; }, - [](SlotIndex InputSlot) -> MachineBasicBlock * { return nullptr; }, 0, 1, - 2, 3, LastIndex); - for (size_t CurrentInstructionIndex = 0; - CurrentInstructionIndex < ModelMaxSupportedInstructionCount; - ++CurrentInstructionIndex) { - ASSERT_EQ( - (size_t)ModelRunner.getTensor<int64_t>(0)[CurrentInstructionIndex], - CurrentInstructionIndex); - } -} - -TEST_F(RegAllocDevelopmentFeaturesTest, FullOverlap) { - SmallVector<LRPosInfoIndexes, 2> OverlapSetup; - OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 0}); - OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 1}); - runOverlapTest(OverlapSetup); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, PartialOverlap) { - SmallVector<LRPosInfoIndexes, 2> OverlapSetup; - OverlapSetup.push_back({0, 20, 0}); - OverlapSetup.push_back({15, 30, 1}); - runOverlapTest(OverlapSetup); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, PartialOverlapOpposite) { - SmallVector<LRPosInfoIndexes, 2> OverlapSetup; - OverlapSetup.push_back({15, 30, 1}); - OverlapSetup.push_back({0, 20, 0}); - runOverlapTest(OverlapSetup); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, InternalOverlap) { - SmallVector<LRPosInfoIndexes, 2> OverlapSetup; - OverlapSetup.push_back({0, 30, 0}); - OverlapSetup.push_back({10, 20, 1}); - runOverlapTest(OverlapSetup); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, TripleInternalOverlap) { - SmallVector<LRPosInfoIndexes, 3> OverlapSetup; - OverlapSetup.push_back({0, 30, 0}); - OverlapSetup.push_back({10, 25, 1}); - OverlapSetup.push_back({15, 20, 2}); - runOverlapTest(OverlapSetup); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, InternalMultiOverlap) { - SmallVector<LRPosInfoIndexes, 3> OverlapSetup; - OverlapSetup.push_back({0, 45, 0}); - OverlapSetup.push_back({30, 40, 1}); - OverlapSetup.push_back({35, 60, 2}); - runOverlapTest(OverlapSetup); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, SingleMBBTest) { - NoInferenceModelRunner ModelRunner = setupModelRunner(); - SlotIndex CurrentIndex; - // set index to 1 so we can ensure that the mapping actually get set - std::map<MachineBasicBlock *, size_t> VisitedMBBs = {{nullptr, 1}}; - extractMBBFrequency( - CurrentIndex, 0, VisitedMBBs, - [](SlotIndex InputSlot) -> float { return 1.0f; }, nullptr, &ModelRunner, - 2, 3); - ASSERT_FLOAT_EQ(ModelRunner.getTensor<float>(2)[1], 1.0f); - ASSERT_EQ(ModelRunner.getTensor<int64_t>(3)[0], 1); -} - -TEST_F(RegAllocDevelopmentFeaturesTest, MBBFullTruncated) { - SmallVector<LRPosInfoIndexes, 1> OverlapSetup; - OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 0}); - simple_ilist<IndexListEntry> IndexList; - auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList); - NoInferenceModelRunner ModelRunner = setupModelRunner(); - SlotIndex LastIndex = OverlapProblem[0].End; - SlotIndex FirstIndex = OverlapProblem[0].Begin; - - LLVMContext Ctx; - Module Mod("Module", Ctx); - auto MF = createMachineFunction(Ctx, Mod); - std::array<MachineBasicBlock *, ModelMaxSupportedInstructionCount> - MBBsForTest; - for (size_t I = 0; I < ModelMaxSupportedInstructionCount; ++I) { - MBBsForTest[I] = MF->CreateMachineBasicBlock(); - } - - extractInstructionFeatures( - OverlapProblem, &ModelRunner, - [](SlotIndex InputSlot) -> int { return 0; }, - [FirstIndex](SlotIndex InputSlot) -> float { - return static_cast<float>(FirstIndex.distance(InputSlot) / - SlotIndex::InstrDist); - }, - [FirstIndex, MBBsForTest](SlotIndex InputSlot) -> MachineBasicBlock * { - return MBBsForTest[FirstIndex.distance(InputSlot) / - SlotIndex::InstrDist]; - }, - 0, 1, 2, 3, LastIndex); - for (size_t MBBIndex = 0; MBBIndex < ModelMaxSupportedMBBCount; ++MBBIndex) { - ASSERT_FLOAT_EQ(ModelRunner.getTensor<float>(2)[MBBIndex], - static_cast<float>(MBBIndex)); - ASSERT_EQ(ModelRunner.getTensor<int64_t>(3)[MBBIndex], - static_cast<int64_t>(MBBIndex)); - } - // the rest of the mapping values should be zero (truncated to 100 MBBs) - for (size_t MBBIndex = ModelMaxSupportedMBBCount; - MBBIndex < ModelMaxSupportedInstructionCount; ++MBBIndex) { - ASSERT_EQ(ModelRunner.getTensor<int64_t>(3)[MBBIndex], - static_cast<int64_t>(0)); - } -} - -} // end namespace diff --git a/llvm/unittests/CodeGen/MachineOperandTest.cpp b/llvm/unittests/CodeGen/MachineOperandTest.cpp index 0373c7a..c0b2b18 100644 --- a/llvm/unittests/CodeGen/MachineOperandTest.cpp +++ b/llvm/unittests/CodeGen/MachineOperandTest.cpp @@ -288,6 +288,23 @@ TEST(MachineOperandTest, PrintGlobalAddress) { } } +TEST(MachineOperandTest, PrintLaneMask) { + // Create a MachineOperand with a lanemask and print it. + LaneBitmask LaneMask = LaneBitmask(12); + MachineOperand MO = MachineOperand::CreateLaneMask(LaneMask); + + // Checking some preconditions on the newly created + // MachineOperand. + ASSERT_TRUE(MO.isLaneMask()); + ASSERT_EQ(MO.getLaneMask(), LaneMask); + + std::string str; + // Print a MachineOperand that is lanemask as in HEX representation. + raw_string_ostream OS(str); + MO.print(OS, /*TRI=*/nullptr); + ASSERT_EQ(str, "lanemask(0x000000000000000C)"); +} + TEST(MachineOperandTest, PrintRegisterLiveOut) { // Create a MachineOperand with a register live out list and print it. uint32_t Mask = 0; diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp index ceaee52..4fcd3fc 100644 --- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp @@ -354,6 +354,46 @@ TEST_F(SelectionDAGPatternMatchTest, matchBinaryOp) { sd_match(InsertELT, m_InsertElt(m_Value(), m_Value(), m_SpecificInt(1)))); } +TEST_F(SelectionDAGPatternMatchTest, matchSpecificFpOp) { + SDLoc DL; + APFloat Value(1.5f); + auto Float32VT = EVT::getFloatingPointVT(32); + SDValue Op0 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Float32VT); + SDValue Op1 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 2, Float32VT); + SDValue Op2 = DAG->getConstantFP(Value, DL, Float32VT); + SDValue FAdd0 = DAG->getNode(ISD::FADD, DL, Float32VT, Op0, Op1); + SDValue FAdd1 = DAG->getNode(ISD::FADD, DL, Float32VT, Op1, Op2); + + using namespace SDPatternMatch; + + EXPECT_FALSE(sd_match(Op1, m_SpecificFP(Value))); + EXPECT_TRUE(sd_match(Op2, m_SpecificFP(Value))); + + EXPECT_FALSE(sd_match( + FAdd0, m_BinOp(ISD::FADD, m_Specific(Op0), m_SpecificFP(Value)))); + EXPECT_TRUE(sd_match( + FAdd1, m_BinOp(ISD::FADD, m_Specific(Op1), m_SpecificFP(Value)))); + EXPECT_TRUE(sd_match( + FAdd1, m_c_BinOp(ISD::FADD, m_SpecificFP(Value), m_Specific(Op1)))); + + auto VFloat32VT = EVT::getVectorVT(Context, Float32VT, 2); + SDValue VOp0 = DAG->getSplat(VFloat32VT, DL, Op0); + SDValue VOp1 = DAG->getSplat(VFloat32VT, DL, Op1); + SDValue VOp2 = DAG->getSplat(VFloat32VT, DL, Op2); + + EXPECT_FALSE(sd_match(VOp0, m_SpecificFP(Value))); + EXPECT_TRUE(sd_match(VOp2, m_SpecificFP(Value))); + + SDValue VFAdd0 = DAG->getNode(ISD::FADD, DL, VFloat32VT, VOp0, VOp1); + SDValue VFAdd1 = DAG->getNode(ISD::FADD, DL, VFloat32VT, VOp1, VOp2); + EXPECT_FALSE(sd_match( + VFAdd0, m_BinOp(ISD::FADD, m_Specific(VOp0), m_SpecificFP(Value)))); + EXPECT_TRUE(sd_match( + VFAdd1, m_BinOp(ISD::FADD, m_Specific(VOp1), m_SpecificFP(Value)))); + EXPECT_TRUE(sd_match( + VFAdd1, m_c_BinOp(ISD::FADD, m_SpecificFP(Value), m_Specific(VOp1)))); +} + TEST_F(SelectionDAGPatternMatchTest, matchGenericTernaryOp) { SDLoc DL; auto Float32VT = EVT::getFloatingPointVT(32); @@ -551,6 +591,8 @@ TEST_F(SelectionDAGPatternMatchTest, matchConstants) { SDValue PoisonVInt32VT = DAG->getPOISON(VInt32VT); EXPECT_TRUE(sd_match(PoisonInt32VT, m_Poison())); EXPECT_TRUE(sd_match(PoisonVInt32VT, m_Poison())); + EXPECT_TRUE(sd_match(PoisonInt32VT, m_Undef())); + EXPECT_TRUE(sd_match(PoisonVInt32VT, m_Undef())); } TEST_F(SelectionDAGPatternMatchTest, patternCombinators) { @@ -790,6 +832,38 @@ TEST_F(SelectionDAGPatternMatchTest, matchReassociatableOp) { EXPECT_FALSE(sd_match(ADDS0123, m_ReassociatableAdd(m_Value(), m_Value(), m_Value(), m_Value()))); + // (Op0 + Op1) + Op0 binds correctly, allowing commutation on leaf nodes + SDValue ADD010 = DAG->getNode(ISD::ADD, DL, Int32VT, ADD01, Op0); + SDValue A, B; + EXPECT_TRUE(sd_match( + ADD010, m_ReassociatableAdd(m_Value(A), m_Value(B), m_Deferred(A)))); + EXPECT_EQ(Op0, A); + EXPECT_EQ(Op1, B); + + A.setNode(nullptr); + B.setNode(nullptr); + EXPECT_TRUE(sd_match( + ADD010, m_ReassociatableAdd(m_Value(A), m_Value(B), m_Deferred(B)))); + EXPECT_EQ(Op0, B); + EXPECT_EQ(Op1, A); + + A.setNode(nullptr); + B.setNode(nullptr); + EXPECT_TRUE(sd_match( + ADD010, m_ReassociatableAdd(m_Value(A), m_Deferred(A), m_Value(B)))); + EXPECT_EQ(Op0, A); + EXPECT_EQ(Op1, B); + + A.setNode(nullptr); + B.setNode(nullptr); + EXPECT_FALSE(sd_match( + ADD010, m_ReassociatableAdd(m_Value(A), m_Deferred(A), m_Deferred(A)))); + + A.setNode(nullptr); + B.setNode(nullptr); + EXPECT_FALSE(sd_match( + ADD010, m_ReassociatableAdd(m_Value(A), m_Deferred(B), m_Value(B)))); + // (Op0 * Op1) * (Op2 * Op3) SDValue MUL01 = DAG->getNode(ISD::MUL, DL, Int32VT, Op0, Op1); SDValue MUL23 = DAG->getNode(ISD::MUL, DL, Int32VT, Op2, Op3); diff --git a/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp b/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp index cffaf7c9..20ae253 100644 --- a/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp +++ b/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp @@ -40,6 +40,18 @@ TEST(NativeSessionTest, TestCreateFromExe) { ASSERT_THAT_ERROR(std::move(E), Succeeded()); } +TEST(NativeSessionTest, TestInvalidPdbMagicError) { + SmallString<128> InputsDir = unittest::getInputFileDirectory(TestMainArgv0); + llvm::sys::path::append(InputsDir, "SimpleTest.cpp"); + std::string CppPath{InputsDir}; + std::unique_ptr<IPDBSession> S; + + Error E = NativeSession::createFromPdbPath(CppPath, S); + const char *FormatErr = "The record is in an unexpected format. " + "The input file did not contain the pdb file magic."; + ASSERT_THAT_ERROR(std::move(E), FailedWithMessage(FormatErr)); +} + TEST(NativeSessionTest, TestSetLoadAddress) { std::unique_ptr<IPDBSession> S; Error E = pdb::loadDataForEXE(PDB_ReaderType::Native, getExePath(), S); diff --git a/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp index bc43515..f84ef04 100644 --- a/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp +++ b/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp @@ -147,6 +147,7 @@ protected: didCallAllocateCodeSection = false; didAllocateCompactUnwindSection = false; didCallYield = false; + Context = LLVMContextCreate(); Module = nullptr; Function = nullptr; Engine = nullptr; @@ -158,21 +159,24 @@ protected: LLVMDisposeExecutionEngine(Engine); else if (Module) LLVMDisposeModule(Module); + LLVMContextDispose(Context); } void buildSimpleFunction() { - Module = LLVMModuleCreateWithName("simple_module"); + Module = LLVMModuleCreateWithNameInContext("simple_module", Context); LLVMSetTarget(Module, HostTripleName.c_str()); + LLVMTypeRef Int32Ty = LLVMInt32TypeInContext(Context); Function = LLVMAddFunction(Module, "simple_function", - LLVMFunctionType(LLVMInt32Type(), nullptr,0, 0)); + LLVMFunctionType(Int32Ty, nullptr, 0, 0)); LLVMSetFunctionCallConv(Function, LLVMCCallConv); - LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry"); - LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMBasicBlockRef entry = + LLVMAppendBasicBlockInContext(Context, Function, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(Context); LLVMPositionBuilderAtEnd(builder, entry); - LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); + LLVMBuildRet(builder, LLVMConstInt(Int32Ty, 42, 0)); LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); LLVMDisposeMessage(Error); @@ -181,29 +185,31 @@ protected: } void buildFunctionThatUsesStackmap() { - Module = LLVMModuleCreateWithName("simple_module"); + Module = LLVMModuleCreateWithNameInContext("simple_module", Context); LLVMSetTarget(Module, HostTripleName.c_str()); - LLVMTypeRef stackmapParamTypes[] = { LLVMInt64Type(), LLVMInt32Type() }; - LLVMTypeRef stackmapTy = - LLVMFunctionType(LLVMVoidType(), stackmapParamTypes, 2, 1); + LLVMTypeRef Int64Ty = LLVMInt64TypeInContext(Context); + LLVMTypeRef Int32Ty = LLVMInt32TypeInContext(Context); + LLVMTypeRef VoidTy = LLVMVoidTypeInContext(Context); + LLVMTypeRef stackmapParamTypes[] = {Int64Ty, Int32Ty}; + LLVMTypeRef stackmapTy = LLVMFunctionType(VoidTy, stackmapParamTypes, 2, 1); LLVMValueRef stackmap = LLVMAddFunction( Module, "llvm.experimental.stackmap", stackmapTy); LLVMSetLinkage(stackmap, LLVMExternalLinkage); Function = LLVMAddFunction(Module, "simple_function", - LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0)); + LLVMFunctionType(Int32Ty, nullptr, 0, 0)); - LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry"); - LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMBasicBlockRef entry = + LLVMAppendBasicBlockInContext(Context, Function, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilderInContext(Context); LLVMPositionBuilderAtEnd(builder, entry); - LLVMValueRef stackmapArgs[] = { - LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 5, 0), - LLVMConstInt(LLVMInt32Type(), 42, 0) - }; + LLVMValueRef stackmapArgs[] = {LLVMConstInt(Int64Ty, 0, 0), + LLVMConstInt(Int32Ty, 5, 0), + LLVMConstInt(Int32Ty, 42, 0)}; LLVMBuildCall2(builder, stackmapTy, stackmap, stackmapArgs, 3, ""); - LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); + LLVMBuildRet(builder, LLVMConstInt(Int32Ty, 42, 0)); LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); LLVMDisposeMessage(Error); @@ -212,51 +218,56 @@ protected: } void buildModuleWithCodeAndData() { - Module = LLVMModuleCreateWithName("simple_module"); + Module = LLVMModuleCreateWithNameInContext("simple_module", Context); LLVMSetTarget(Module, HostTripleName.c_str()); + LLVMTypeRef Int32Ty = LLVMInt32TypeInContext(Context); + LLVMTypeRef VoidTy = LLVMVoidTypeInContext(Context); + // build a global int32 variable initialized to 42. - LLVMValueRef GlobalVar = LLVMAddGlobal(Module, LLVMInt32Type(), "intVal"); - LLVMSetInitializer(GlobalVar, LLVMConstInt(LLVMInt32Type(), 42, 0)); + LLVMValueRef GlobalVar = LLVMAddGlobal(Module, Int32Ty, "intVal"); + LLVMSetInitializer(GlobalVar, LLVMConstInt(Int32Ty, 42, 0)); { - Function = LLVMAddFunction(Module, "getGlobal", - LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0)); - LLVMSetFunctionCallConv(Function, LLVMCCallConv); + Function = LLVMAddFunction(Module, "getGlobal", + LLVMFunctionType(Int32Ty, nullptr, 0, 0)); + LLVMSetFunctionCallConv(Function, LLVMCCallConv); - LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "entry"); - LLVMBuilderRef Builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(Builder, Entry); + LLVMBasicBlockRef Entry = + LLVMAppendBasicBlockInContext(Context, Function, "entry"); + LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Context); + LLVMPositionBuilderAtEnd(Builder, Entry); - LLVMValueRef IntVal = - LLVMBuildLoad2(Builder, LLVMInt32Type(), GlobalVar, "intVal"); - LLVMBuildRet(Builder, IntVal); + LLVMValueRef IntVal = + LLVMBuildLoad2(Builder, Int32Ty, GlobalVar, "intVal"); + LLVMBuildRet(Builder, IntVal); - LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); - LLVMDisposeMessage(Error); + LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); + LLVMDisposeMessage(Error); - LLVMDisposeBuilder(Builder); + LLVMDisposeBuilder(Builder); } { - LLVMTypeRef ParamTypes[] = { LLVMInt32Type() }; - Function2 = LLVMAddFunction( - Module, "setGlobal", LLVMFunctionType(LLVMVoidType(), ParamTypes, 1, 0)); - LLVMSetFunctionCallConv(Function2, LLVMCCallConv); + LLVMTypeRef ParamTypes[] = {Int32Ty}; + Function2 = LLVMAddFunction(Module, "setGlobal", + LLVMFunctionType(VoidTy, ParamTypes, 1, 0)); + LLVMSetFunctionCallConv(Function2, LLVMCCallConv); - LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function2, "entry"); - LLVMBuilderRef Builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(Builder, Entry); + LLVMBasicBlockRef Entry = + LLVMAppendBasicBlockInContext(Context, Function2, "entry"); + LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Context); + LLVMPositionBuilderAtEnd(Builder, Entry); - LLVMValueRef Arg = LLVMGetParam(Function2, 0); - LLVMBuildStore(Builder, Arg, GlobalVar); - LLVMBuildRetVoid(Builder); + LLVMValueRef Arg = LLVMGetParam(Function2, 0); + LLVMBuildStore(Builder, Arg, GlobalVar); + LLVMBuildRetVoid(Builder); - LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); - LLVMDisposeMessage(Error); + LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); + LLVMDisposeMessage(Error); - LLVMDisposeBuilder(Builder); + LLVMDisposeBuilder(Builder); } } @@ -309,6 +320,7 @@ protected: LLVMDisposePassBuilderOptions(Options); } + LLVMContextRef Context; LLVMModuleRef Module; LLVMValueRef Function; LLVMValueRef Function2; @@ -335,10 +347,11 @@ TEST_F(MCJITCAPITest, simple_function) { TEST_F(MCJITCAPITest, gva) { SKIP_UNSUPPORTED_PLATFORM; - Module = LLVMModuleCreateWithName("simple_module"); + Module = LLVMModuleCreateWithNameInContext("simple_module", Context); LLVMSetTarget(Module, HostTripleName.c_str()); - LLVMValueRef GlobalVar = LLVMAddGlobal(Module, LLVMInt32Type(), "simple_value"); - LLVMSetInitializer(GlobalVar, LLVMConstInt(LLVMInt32Type(), 42, 0)); + LLVMTypeRef Int32Ty = LLVMInt32TypeInContext(Context); + LLVMValueRef GlobalVar = LLVMAddGlobal(Module, Int32Ty, "simple_value"); + LLVMSetInitializer(GlobalVar, LLVMConstInt(Int32Ty, 42, 0)); buildMCJITOptions(); buildMCJITEngine(); @@ -451,8 +464,7 @@ TEST_F(MCJITCAPITest, yield) { buildSimpleFunction(); buildMCJITOptions(); buildMCJITEngine(); - LLVMContextRef C = LLVMGetGlobalContext(); - LLVMContextSetYieldCallback(C, yield, nullptr); + LLVMContextSetYieldCallback(Context, yield, nullptr); buildAndRunPasses(); auto *functionPointer = reinterpret_cast<int (*)()>( @@ -469,14 +481,16 @@ static int localTestFunc() { TEST_F(MCJITCAPITest, addGlobalMapping) { SKIP_UNSUPPORTED_PLATFORM; - Module = LLVMModuleCreateWithName("testModule"); + Module = LLVMModuleCreateWithNameInContext("testModule", Context); LLVMSetTarget(Module, HostTripleName.c_str()); - LLVMTypeRef FunctionType = LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0); + LLVMTypeRef Int32Ty = LLVMInt32TypeInContext(Context); + LLVMTypeRef FunctionType = LLVMFunctionType(Int32Ty, nullptr, 0, 0); LLVMValueRef MappedFn = LLVMAddFunction(Module, "mapped_fn", FunctionType); Function = LLVMAddFunction(Module, "test_fn", FunctionType); - LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, ""); - LLVMBuilderRef Builder = LLVMCreateBuilder(); + LLVMBasicBlockRef Entry = + LLVMAppendBasicBlockInContext(Context, Function, ""); + LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Context); LLVMPositionBuilderAtEnd(Builder, Entry); LLVMValueRef RetVal = LLVMBuildCall2(Builder, FunctionType, MappedFn, nullptr, 0, ""); diff --git a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt index 7b563d7..ea45a03 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt +++ b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt @@ -18,6 +18,8 @@ set(LLVM_LINK_COMPONENTS ) add_llvm_unittest(OrcJITTests + CallableTraitsHelperTest.cpp + CallSPSViaEPCTest.cpp CoreAPIsTest.cpp ExecutorAddressTest.cpp ExecutionSessionWrapperFunctionCallsTest.cpp diff --git a/llvm/unittests/ExecutionEngine/Orc/CallSPSViaEPCTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CallSPSViaEPCTest.cpp new file mode 100644 index 0000000..7e3d468 --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/CallSPSViaEPCTest.cpp @@ -0,0 +1,173 @@ +//===----------- CallSPSViaEPC.cpp - Test CallSPSViaEPC.h APIs ------------===// +// +// 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 "llvm/ExecutionEngine/Orc/CallSPSViaEPC.h" +#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h" + +#include "llvm/Testing/Support/Error.h" + +#include <future> + +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::orc; +using namespace llvm::orc::shared; + +static CWrapperFunctionResult voidWrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction<void()>::handle(ArgData, ArgSize, []() {}).release(); +} + +static CWrapperFunctionResult mainWrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction<int32_t(SPSSequence<SPSString>)>::handle( + ArgData, ArgSize, + [](std::vector<std::string> Args) -> int32_t { + return Args.size(); + }) + .release(); +} + +TEST(CallSPSViaEPCTest, CallVoidViaCallerAsync) { + auto EPC = cantFail(SelfExecutorProcessControl::Create()); + SPSEPCCaller<void()> C(*EPC); + + Error Err = Error::success(); + { + ErrorAsOutParameter _(Err); + C([&](Error E) { Err = std::move(E); }, + ExecutorSymbolDef::fromPtr(voidWrapper)); + } + EXPECT_THAT_ERROR(std::move(Err), Succeeded()); +} + +TEST(CallSPSViaEPCTest, CallVoidViaCallerSync) { + auto EPC = cantFail(SelfExecutorProcessControl::Create()); + SPSEPCCaller<void()> C(*EPC); + + Error Err = + C(std::promise<MSVCPError>(), ExecutorSymbolDef::fromPtr(voidWrapper)); + EXPECT_THAT_ERROR(std::move(Err), Succeeded()); +} + +TEST(CallSPSViaEPCTest, CallMainViaCallerAsync) { + auto EPC = cantFail(SelfExecutorProcessControl::Create()); + SPSEPCCaller<int32_t(SPSSequence<SPSString>)> C(*EPC); + std::vector<std::string> Args; + + std::optional<Expected<int32_t>> R1; + C([&](Expected<int32_t> R) { R1 = std::move(R); }, + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(*R1, Succeeded()); + EXPECT_EQ(**R1, 0); + + Args.push_back("foo"); + std::optional<Expected<int32_t>> R2; + C([&](Expected<int32_t> R) { R2 = std::move(R); }, + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(*R2, Succeeded()); + EXPECT_EQ(**R2, 1); + + Args.push_back("foo"); + std::optional<Expected<int32_t>> R3; + C([&](Expected<int32_t> R) { R3 = std::move(R); }, + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(*R3, Succeeded()); + EXPECT_EQ(**R3, 2); + + Args.clear(); + std::optional<Expected<int32_t>> R4; + C([&](Expected<int32_t> R) { R4 = std::move(R); }, + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(*R4, Succeeded()); + EXPECT_EQ(**R4, 0); +} + +TEST(CallSPSViaEPCTest, CallMainViaGenericCallAsync) { + auto EPC = cantFail(SelfExecutorProcessControl::Create()); + SPSEPCCall<int32_t(SPSSequence<SPSString>)> C( + *EPC, ExecutorSymbolDef::fromPtr(mainWrapper)); + std::vector<std::string> Args; + + std::optional<Expected<int32_t>> R1; + C([&](Expected<int32_t> R) { R1 = std::move(R); }, Args); + ASSERT_THAT_EXPECTED(*R1, Succeeded()); + EXPECT_EQ(**R1, 0); + + Args.push_back("foo"); + std::optional<Expected<int32_t>> R2; + C([&](Expected<int32_t> R) { R2 = std::move(R); }, Args); + ASSERT_THAT_EXPECTED(*R2, Succeeded()); + EXPECT_EQ(**R2, 1); + + Args.push_back("foo"); + std::optional<Expected<int32_t>> R3; + C([&](Expected<int32_t> R) { R3 = std::move(R); }, Args); + ASSERT_THAT_EXPECTED(*R3, Succeeded()); + EXPECT_EQ(**R3, 2); + + Args.clear(); + std::optional<Expected<int32_t>> R4; + C([&](Expected<int32_t> R) { R4 = std::move(R); }, Args); + ASSERT_THAT_EXPECTED(*R4, Succeeded()); + EXPECT_EQ(**R4, 0); +} + +TEST(CallSPSViaEPCTest, CallMainViaCallerSync) { + auto EPC = cantFail(SelfExecutorProcessControl::Create()); + SPSEPCCaller<int32_t(SPSSequence<SPSString>)> C(*EPC); + std::vector<std::string> Args; + + Expected<int32_t> R1 = C(std::promise<MSVCPExpected<int32_t>>(), + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(R1, Succeeded()); + EXPECT_EQ(*R1, 0); + + Args.push_back("foo"); + Expected<int32_t> R2 = C(std::promise<MSVCPExpected<int32_t>>(), + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(R2, Succeeded()); + EXPECT_EQ(*R2, 1); + + Args.push_back("foo"); + Expected<int32_t> R3 = C(std::promise<MSVCPExpected<int32_t>>(), + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(R3, Succeeded()); + EXPECT_EQ(*R3, 2); + + Args.clear(); + Expected<int32_t> R4 = C(std::promise<MSVCPExpected<int32_t>>(), + ExecutorSymbolDef::fromPtr(mainWrapper), Args); + ASSERT_THAT_EXPECTED(R4, Succeeded()); + EXPECT_EQ(*R4, 0); +} + +TEST(CallSPSViaEPCTest, CallMainViaGenericCallSync) { + auto EPC = cantFail(SelfExecutorProcessControl::Create()); + SPSEPCCall<int32_t(SPSSequence<SPSString>)> C( + *EPC, ExecutorSymbolDef::fromPtr(mainWrapper)); + std::vector<std::string> Args; + + Expected<int32_t> R1 = C(std::promise<MSVCPExpected<int32_t>>(), Args); + ASSERT_THAT_EXPECTED(R1, Succeeded()); + EXPECT_EQ(*R1, 0); + + Args.push_back("foo"); + Expected<int32_t> R2 = C(std::promise<MSVCPExpected<int32_t>>(), Args); + ASSERT_THAT_EXPECTED(R2, Succeeded()); + EXPECT_EQ(*R2, 1); + + Args.push_back("foo"); + Expected<int32_t> R3 = C(std::promise<MSVCPExpected<int32_t>>(), Args); + ASSERT_THAT_EXPECTED(R3, Succeeded()); + EXPECT_EQ(*R3, 2); + + Args.clear(); + Expected<int32_t> R4 = C(std::promise<MSVCPExpected<int32_t>>(), Args); + ASSERT_THAT_EXPECTED(R4, Succeeded()); + EXPECT_EQ(*R4, 0); +} diff --git a/llvm/unittests/ExecutionEngine/Orc/CallableTraitsHelperTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CallableTraitsHelperTest.cpp new file mode 100644 index 0000000..bfb3d8e --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/CallableTraitsHelperTest.cpp @@ -0,0 +1,70 @@ +//===- CallableTraitsHelperTest.cpp ---------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Tests for llvm::orc::CallableTraitsHelper APIs. +// +// NOTE: All tests in this file are testing compile-time functionality, so the +// tests at runtime all end up being noops. That's fine -- those are +// cheap. +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/CallableTraitsHelper.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::orc; + +static void freeVoidVoid() {} + +TEST(CallableTraitsHelperTest, FreeVoidVoid) { + (void)freeVoidVoid; + typedef CallableArgInfo<decltype(freeVoidVoid)> CAI; + static_assert(std::is_void_v<CAI::ReturnType>); + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<>>); +} + +static int freeBinaryOp(int, float) { return 0; } + +TEST(CallableTraitsHelperTest, FreeBinaryOp) { + (void)freeBinaryOp; + typedef CallableArgInfo<decltype(freeBinaryOp)> CAI; + static_assert(std::is_same_v<CAI::ReturnType, int>); + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int, float>>); +} + +TEST(CallableTraitsHelperTest, VoidVoidObj) { + auto VoidVoid = []() {}; + typedef CallableArgInfo<decltype(VoidVoid)> CAI; + static_assert(std::is_void_v<CAI::ReturnType>); + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<>>); +} + +TEST(CallableTraitsHelperTest, BinaryOpObj) { + auto BinaryOp = [](int X, float Y) -> int { return X + Y; }; + typedef CallableArgInfo<decltype(BinaryOp)> CAI; + static_assert(std::is_same_v<CAI::ReturnType, int>); + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int, float>>); +} + +TEST(CallableTraitsHelperTest, PreservesLValueRef) { + auto RefOp = [](int &) {}; + typedef CallableArgInfo<decltype(RefOp)> CAI; + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int &>>); +} + +TEST(CallableTraitsHelperTest, PreservesLValueRefConstness) { + auto RefOp = [](const int &) {}; + typedef CallableArgInfo<decltype(RefOp)> CAI; + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<const int &>>); +} + +TEST(CallableTraitsHelperTest, PreservesRValueRef) { + auto RefOp = [](int &&) {}; + typedef CallableArgInfo<decltype(RefOp)> CAI; + static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int &&>>); +} diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp index d3fcb94..0ddbb33 100644 --- a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp @@ -547,7 +547,6 @@ TEST_F(OrcCAPITestBase, DISABLED_EnableDebugSupport) { #else static LLVM_ATTRIBUTE_USED void linkComponents() { errs() << "Linking in runtime functions\n" - << (void *)&llvm_orc_registerJITLoaderGDBWrapper << '\n' << (void *)&llvm_orc_registerJITLoaderGDBAllocAction << '\n'; } TEST_F(OrcCAPITestBase, EnableDebugSupport) { diff --git a/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp b/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp index 08b4e8f..1d550b1 100644 --- a/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/WaitingOnGraphTest.cpp @@ -399,6 +399,31 @@ TEST_F(WaitingOnGraphTest, Emit_TrivialSequence) { EXPECT_EQ(ER1.Failed.size(), 0U); } +TEST_F(WaitingOnGraphTest, Emit_SingleContainerSimpleCycle) { + // Test an emit of two nodes with a dependence cycle within a single + // container: + // N0: (0, 0) -> (0, 1) + // N1: (0, 1) -> (0, 0) + // We expect intra-simplify cycle elimination to clear both dependence sets, + // and coalescing to join them into one supernode covering both defs. + SuperNodeBuilder B; + ContainerElementsMap Defs0({{0, {0}}}); + ContainerElementsMap Deps0({{0, {1}}}); + B.add(Defs0, Deps0); + + auto ER0 = emit(TestGraph::simplify(B.takeSuperNodes())); + EXPECT_EQ(ER0.Ready.size(), 0U); + EXPECT_EQ(ER0.Failed.size(), 0U); + + ContainerElementsMap Defs1({{0, {1}}}); + ContainerElementsMap Deps1({{0, {0}}}); + B.add(Defs1, Deps1); + auto ER1 = emit(TestGraph::simplify(B.takeSuperNodes())); + + EXPECT_EQ(collapseDefs(ER1.Ready), merge(Defs0, Defs1)); + EXPECT_EQ(ER1.Failed.size(), 0U); +} + TEST_F(WaitingOnGraphTest, Emit_TrivialReverseSequence) { // Perform a sequence of two emits where the first emit depends on the // second. Check that both nodes become ready after the second emit. @@ -507,6 +532,52 @@ TEST_F(WaitingOnGraphTest, Emit_ZigZag) { EXPECT_TRUE(PendingSNs.empty()); } +TEST_F(WaitingOnGraphTest, Emit_ReEmit) { + // Test for the bug in https://github.com/llvm/llvm-project/issues/169135, + // which was caused by stale entries in the ElemsToPendingSNs map. + // + // To trigger the bug we need to: + // 1. Create a SuperNode with an unmet dependence, causing it to be added to + // ElemsToPendingSNs. + // 2. Cause that SuperNode to become ready (bug left stale entries in map) + // 3. Remove the node from the Ready map (this is equivalent to removal of a + // symbol in an ORC session, and allows new SuperNodes to depend on the + // stale entry). + // 4. Add a new node that references the previously emitted/removed SuperNode + // This triggers access of the stale entry, and should error out in + // sanitizer builds. + + SuperNodeBuilder B; + + // 1. Create SuperNode with unmet dependence. + ContainerElementsMap Defs0({{0, {0}}}); + ContainerElementsMap Deps0({{0, {1}}}); + B.add(Defs0, Deps0); + emit(TestGraph::simplify(B.takeSuperNodes())); + + EXPECT_TRUE(Ready.empty()); + + // 2. Cause previous SuperNode to become ready. + ContainerElementsMap Defs1({{0, {1}}}); + B.add(Defs1, ContainerElementsMap()); + emit(TestGraph::simplify(B.takeSuperNodes())); + + // Check that both nodes have become ready. + EXPECT_EQ(Ready, merge(Defs0, Defs1)); + + // 3. Erase Ready nodes to simulate removal from the graph. + Ready.clear(); + + // 4. Emit a new dependence on the original def. + ContainerElementsMap Defs2({{0, {2}}}); + ContainerElementsMap Deps2({{0, {0}}}); + B.add(Defs2, Deps2); + auto ER = emit(TestGraph::simplify(B.takeSuperNodes())); + + // We expect the new dependence to remain pending. + EXPECT_TRUE(ER.Ready.empty()); +} + TEST_F(WaitingOnGraphTest, Fail_Empty) { // Check that failing an empty set is a no-op. auto FR = G.fail(ContainerElementsMap()); diff --git a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp index e0c6b39..23c3c4d 100644 --- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp +++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp @@ -277,16 +277,42 @@ struct StringifyClause { std::string Str; }; +std::string stringify(const omp::Clause &C) { // + return StringifyClause(C).Str; +} + std::string stringify(const omp::DirectiveWithClauses &DWC) { std::stringstream Stream; Stream << getOpenMPDirectiveName(DWC.id, llvm::omp::FallbackVersion).str(); for (const omp::Clause &C : DWC.clauses) - Stream << ' ' << StringifyClause(C).Str; + Stream << ' ' << stringify(C); return Stream.str(); } +std::string stringify(tomp::ErrorCode E) { + switch (E) { + case tomp::ErrorCode::NoLeafAllowing: + return "no leaf that allows this clause"; + case tomp::ErrorCode::NoLeafPrivatizing: + return "no leaf with a privatizing clause"; + case tomp::ErrorCode::InvalidDirNameMod: + return "invalid directive name modifier"; + case tomp::ErrorCode::RedModNotApplied: + return "the reduction modifier cannot be applied"; + } + return "unrecognized error code " + std::to_string(llvm::to_underlying(E)); +} + +std::string stringify(std::pair<const omp::Clause *, tomp::ErrorCode> &ER) { + std::stringstream Stream; + + Stream << "error while applying '" << stringify(*ER.first) + << "': " << stringify(ER.second); + return Stream.str(); +} + // --- Tests ---------------------------------------------------------- namespace red { @@ -1109,4 +1135,81 @@ TEST_F(OpenMPDecompositionTest, Misc1) { std::string Dir0 = stringify(Dec.output[0]); ASSERT_EQ(Dir0, "simd linear(, , (x)) lastprivate(, (x))"); } + +// --- Failure/error reporting tests + +TEST_F(OpenMPDecompositionTest, Error1) { + // "parallel for at(compilation)" is invalid because the "at" clause + // does not apply to either "parallel" or "for". + + omp::List<omp::Clause> Clauses{ + {OMPC_at, omp::clause::At{omp::clause::At::ActionTime::Compilation}}, + }; + + omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_for, + Clauses); + ASSERT_EQ(Dec.errors.size(), 1u); + std::string Err0 = stringify(Dec.errors[0]); + ASSERT_EQ(Err0, + "error while applying 'at(0)': no leaf that allows this clause"); +} + +TEST_F(OpenMPDecompositionTest, Error2) { + // "parallel loop allocate(x) private(x)" is invalid because "allocate" + // can only be applied to "parallel", while "private" is applied to "loop". + // This violates the requirement that the leaf with an "allocate" also has + // a privatizing clause. + + omp::Object x{"x"}; + + omp::List<omp::Clause> Clauses{ + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, + {OMPC_private, omp::clause::Private{{x}}}, + }; + + omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_loop, + Clauses); + ASSERT_EQ(Dec.errors.size(), 1u); + std::string Err0 = stringify(Dec.errors[0]); + ASSERT_EQ(Err0, "error while applying 'allocate(, , (x))': no leaf with a " + "privatizing clause"); +} + +TEST_F(OpenMPDecompositionTest, Error3) { + // "parallel for if(target: e)" is invalid because the "target" directive- + // name-modifier does not refer to a constituent directive. + + omp::ExprTy e; + + omp::List<omp::Clause> Clauses{ + {OMPC_if, omp::clause::If{{llvm::omp::Directive::OMPD_target, e}}}, + }; + + omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_for, + Clauses); + ASSERT_EQ(Dec.errors.size(), 1u); + std::string Err0 = stringify(Dec.errors[0]); + ASSERT_EQ(Err0, "error while applying 'if(target, expr)': invalid directive " + "name modifier"); +} + +TEST_F(OpenMPDecompositionTest, Error4) { + // "masked taskloop reduction(+, task: x)" is invalid because the "task" + // modifier can only be applied to "parallel" or a worksharing directive. + + omp::Object x{"x"}; + auto Add = red::makeOp(omp::clause::DefinedOperator::IntrinsicOperator::Add); + auto TaskMod = omp::clause::Reduction::ReductionModifier::Task; + + omp::List<omp::Clause> Clauses{ + {OMPC_reduction, omp::clause::Reduction{{TaskMod, {Add}, {x}}}}, + }; + + omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_masked_taskloop, + Clauses); + ASSERT_EQ(Dec.errors.size(), 1u); + std::string Err0 = stringify(Dec.errors[0]); + ASSERT_EQ(Err0, "error while applying 'reduction(2, (3), (x))': the " + "reduction modifier cannot be applied"); +} } // namespace diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp index 0b3ae64..dcc621a 100644 --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -428,8 +428,8 @@ TEST_F(OpenMPIRBuilderTest, CreateCancel) { OMPBuilder.createCancel(Loc, nullptr, OMPD_parallel)); Builder.restoreIP(NewIP); EXPECT_FALSE(M->global_empty()); - EXPECT_EQ(M->size(), 4U); - EXPECT_EQ(F->size(), 4U); + EXPECT_EQ(M->size(), 3U); + EXPECT_EQ(F->size(), 5U); EXPECT_EQ(BB->size(), 4U); CallInst *GTID = dyn_cast<CallInst>(&BB->front()); @@ -449,23 +449,16 @@ TEST_F(OpenMPIRBuilderTest, CreateCancel) { Instruction *CancelBBTI = Cancel->getParent()->getTerminator(); EXPECT_EQ(CancelBBTI->getNumSuccessors(), 2U); EXPECT_EQ(CancelBBTI->getSuccessor(0), NewIP.getBlock()); - EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 3U); - CallInst *GTID1 = dyn_cast<CallInst>(&CancelBBTI->getSuccessor(1)->front()); - EXPECT_NE(GTID1, nullptr); - EXPECT_EQ(GTID1->arg_size(), 1U); - EXPECT_EQ(GTID1->getCalledFunction()->getName(), "__kmpc_global_thread_num"); - EXPECT_FALSE(GTID1->getCalledFunction()->doesNotAccessMemory()); - EXPECT_FALSE(GTID1->getCalledFunction()->doesNotFreeMemory()); - CallInst *Barrier = dyn_cast<CallInst>(GTID1->getNextNode()); - EXPECT_NE(Barrier, nullptr); - EXPECT_EQ(Barrier->arg_size(), 2U); - EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier"); - EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory()); - EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory()); - EXPECT_TRUE(Barrier->use_empty()); + EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 1U); EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(), 1U); - EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0), CBB); + // cancel branch instruction (1) -> .cncl -> .fini -> CBB + EXPECT_EQ(CancelBBTI->getSuccessor(1) + ->getTerminator() + ->getSuccessor(0) + ->getTerminator() + ->getSuccessor(0), + CBB); EXPECT_EQ(cast<CallInst>(Cancel)->getArgOperand(1), GTID); @@ -498,7 +491,7 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) { Builder.restoreIP(NewIP); EXPECT_FALSE(M->global_empty()); EXPECT_EQ(M->size(), 4U); - EXPECT_EQ(F->size(), 7U); + EXPECT_EQ(F->size(), 10U); EXPECT_EQ(BB->size(), 1U); ASSERT_TRUE(isa<BranchInst>(BB->getTerminator())); ASSERT_EQ(BB->getTerminator()->getNumSuccessors(), 2U); @@ -524,23 +517,15 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) { EXPECT_EQ(CancelBBTI->getSuccessor(0)->size(), 1U); EXPECT_EQ(CancelBBTI->getSuccessor(0)->getUniqueSuccessor(), NewIP.getBlock()); - EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 3U); - CallInst *GTID1 = dyn_cast<CallInst>(&CancelBBTI->getSuccessor(1)->front()); - EXPECT_NE(GTID1, nullptr); - EXPECT_EQ(GTID1->arg_size(), 1U); - EXPECT_EQ(GTID1->getCalledFunction()->getName(), "__kmpc_global_thread_num"); - EXPECT_FALSE(GTID1->getCalledFunction()->doesNotAccessMemory()); - EXPECT_FALSE(GTID1->getCalledFunction()->doesNotFreeMemory()); - CallInst *Barrier = dyn_cast<CallInst>(GTID1->getNextNode()); - EXPECT_NE(Barrier, nullptr); - EXPECT_EQ(Barrier->arg_size(), 2U); - EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier"); - EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory()); - EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory()); - EXPECT_TRUE(Barrier->use_empty()); + EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 1U); EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(), 1U); - EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0), CBB); + EXPECT_EQ(CancelBBTI->getSuccessor(1) + ->getTerminator() + ->getSuccessor(0) + ->getTerminator() + ->getSuccessor(0), + CBB); EXPECT_EQ(cast<CallInst>(Cancel)->getArgOperand(1), GTID); @@ -572,7 +557,7 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) { Builder.restoreIP(NewIP); EXPECT_FALSE(M->global_empty()); EXPECT_EQ(M->size(), 3U); - EXPECT_EQ(F->size(), 4U); + EXPECT_EQ(F->size(), 5U); EXPECT_EQ(BB->size(), 4U); CallInst *GTID = dyn_cast<CallInst>(&BB->front()); @@ -595,7 +580,11 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) { EXPECT_EQ(BarrierBBTI->getSuccessor(1)->size(), 1U); EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(), 1U); - EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0), + EXPECT_EQ(BarrierBBTI->getSuccessor(1) + ->getTerminator() + ->getSuccessor(0) + ->getTerminator() + ->getSuccessor(0), CBB); EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID); @@ -747,15 +736,15 @@ TEST_F(OpenMPIRBuilderTest, ParallelSimpleGPU) { EXPECT_TRUE(OutlinedFn->hasOneUse()); User *Usr = OutlinedFn->user_back(); ASSERT_TRUE(isa<CallInst>(Usr)); - CallInst *Parallel51CI = dyn_cast<CallInst>(Usr); - ASSERT_NE(Parallel51CI, nullptr); + CallInst *Parallel60CI = dyn_cast<CallInst>(Usr); + ASSERT_NE(Parallel60CI, nullptr); - EXPECT_EQ(Parallel51CI->getCalledFunction()->getName(), "__kmpc_parallel_51"); - EXPECT_EQ(Parallel51CI->arg_size(), 9U); - EXPECT_EQ(Parallel51CI->getArgOperand(5), OutlinedFn); + EXPECT_EQ(Parallel60CI->getCalledFunction()->getName(), "__kmpc_parallel_60"); + EXPECT_EQ(Parallel60CI->arg_size(), 10U); + EXPECT_EQ(Parallel60CI->getArgOperand(5), OutlinedFn); EXPECT_TRUE( - isa<GlobalVariable>(Parallel51CI->getArgOperand(0)->stripPointerCasts())); - EXPECT_EQ(Parallel51CI, Usr); + isa<GlobalVariable>(Parallel60CI->getArgOperand(0)->stripPointerCasts())); + EXPECT_EQ(Parallel60CI, Usr); M->setDataLayout(oldDLStr); } @@ -1291,8 +1280,8 @@ TEST_F(OpenMPIRBuilderTest, ParallelCancelBarrier) { EXPECT_EQ(NumBodiesGenerated, 1U); EXPECT_EQ(NumPrivatizedVars, 0U); - EXPECT_EQ(NumFinalizationPoints, 2U); - EXPECT_TRUE(FakeDestructor->hasNUses(2)); + EXPECT_EQ(NumFinalizationPoints, 1U); + EXPECT_TRUE(FakeDestructor->hasNUses(1)); Builder.restoreIP(AfterIP); Builder.CreateRetVoid(); @@ -2916,7 +2905,8 @@ TEST_F(OpenMPIRBuilderTest, MasterDirective) { BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator()); EXPECT_TRUE(EntryBr->isConditional()); EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB); - BasicBlock *ExitBB = ThenBB->getUniqueSuccessor(); + BasicBlock *FinalizeBB = ThenBB->getUniqueSuccessor(); + BasicBlock *ExitBB = FinalizeBB->getUniqueSuccessor(); EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB); CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition()); @@ -2928,7 +2918,7 @@ TEST_F(OpenMPIRBuilderTest, MasterDirective) { EXPECT_TRUE(isa<GlobalVariable>(MasterEntryCI->getArgOperand(0))); CallInst *MasterEndCI = nullptr; - for (auto &FI : *ThenBB) { + for (auto &FI : *FinalizeBB) { Instruction *cur = &FI; if (isa<CallInst>(cur)) { MasterEndCI = cast<CallInst>(cur); @@ -2998,7 +2988,8 @@ TEST_F(OpenMPIRBuilderTest, MaskedDirective) { BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator()); EXPECT_TRUE(EntryBr->isConditional()); EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB); - BasicBlock *ExitBB = ThenBB->getUniqueSuccessor(); + BasicBlock *FinalizeBB = ThenBB->getUniqueSuccessor(); + BasicBlock *ExitBB = FinalizeBB->getUniqueSuccessor(); EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB); CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition()); @@ -3010,7 +3001,7 @@ TEST_F(OpenMPIRBuilderTest, MaskedDirective) { EXPECT_TRUE(isa<GlobalVariable>(MaskedEntryCI->getArgOperand(0))); CallInst *MaskedEndCI = nullptr; - for (auto &FI : *ThenBB) { + for (auto &FI : *FinalizeBB) { Instruction *cur = &FI; if (isa<CallInst>(cur)) { MaskedEndCI = cast<CallInst>(cur); @@ -3062,6 +3053,9 @@ TEST_F(OpenMPIRBuilderTest, CriticalDirective) { FINICB_WRAPPER(FiniCB), "testCRT", nullptr)); Builder.restoreIP(AfterIP); + BasicBlock *FinalizeBB = EntryBB->getUniqueSuccessor(); + EXPECT_NE(FinalizeBB, nullptr); + CallInst *CriticalEntryCI = nullptr; for (auto &EI : *EntryBB) { Instruction *cur = &EI; @@ -3078,7 +3072,7 @@ TEST_F(OpenMPIRBuilderTest, CriticalDirective) { EXPECT_TRUE(isa<GlobalVariable>(CriticalEntryCI->getArgOperand(0))); CallInst *CriticalEndCI = nullptr; - for (auto &FI : *EntryBB) { + for (auto &FI : *FinalizeBB) { Instruction *cur = &FI; if (isa<CallInst>(cur)) { CriticalEndCI = cast<CallInst>(cur); @@ -3312,6 +3306,9 @@ TEST_F(OpenMPIRBuilderTest, OrderedDirectiveThreads) { FINICB_WRAPPER(FiniCB), true)); Builder.restoreIP(AfterIP); + BasicBlock *FinalizeBB = EntryBB->getUniqueSuccessor(); + EXPECT_NE(FinalizeBB, nullptr); + Builder.CreateRetVoid(); OMPBuilder.finalize(); EXPECT_FALSE(verifyModule(*M, &errs())); @@ -3334,7 +3331,7 @@ TEST_F(OpenMPIRBuilderTest, OrderedDirectiveThreads) { EXPECT_TRUE(isa<GlobalVariable>(OrderedEntryCI->getArgOperand(0))); CallInst *OrderedEndCI = nullptr; - for (auto &FI : *EntryBB) { + for (auto &FI : *FinalizeBB) { Instruction *Cur = &FI; if (isa<CallInst>(Cur)) { OrderedEndCI = cast<CallInst>(Cur); @@ -3508,7 +3505,8 @@ TEST_F(OpenMPIRBuilderTest, SingleDirective) { BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator()); EXPECT_TRUE(EntryBr->isConditional()); EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB); - BasicBlock *ExitBB = ThenBB->getUniqueSuccessor(); + BasicBlock *FinalizeBB = ThenBB->getUniqueSuccessor(); + BasicBlock *ExitBB = FinalizeBB->getUniqueSuccessor(); EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB); CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition()); @@ -3520,7 +3518,7 @@ TEST_F(OpenMPIRBuilderTest, SingleDirective) { EXPECT_TRUE(isa<GlobalVariable>(SingleEntryCI->getArgOperand(0))); CallInst *SingleEndCI = nullptr; - for (auto &FI : *ThenBB) { + for (auto &FI : *FinalizeBB) { Instruction *cur = &FI; if (isa<CallInst>(cur)) { SingleEndCI = cast<CallInst>(cur); @@ -3601,7 +3599,8 @@ TEST_F(OpenMPIRBuilderTest, SingleDirectiveNowait) { BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator()); EXPECT_TRUE(EntryBr->isConditional()); EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB); - BasicBlock *ExitBB = ThenBB->getUniqueSuccessor(); + BasicBlock *FinalizeBB = ThenBB->getUniqueSuccessor(); + BasicBlock *ExitBB = FinalizeBB->getUniqueSuccessor(); EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB); CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition()); @@ -3613,7 +3612,7 @@ TEST_F(OpenMPIRBuilderTest, SingleDirectiveNowait) { EXPECT_TRUE(isa<GlobalVariable>(SingleEntryCI->getArgOperand(0))); CallInst *SingleEndCI = nullptr; - for (auto &FI : *ThenBB) { + for (auto &FI : *FinalizeBB) { Instruction *cur = &FI; if (isa<CallInst>(cur)) { SingleEndCI = cast<CallInst>(cur); @@ -3724,7 +3723,8 @@ TEST_F(OpenMPIRBuilderTest, SingleDirectiveCopyPrivate) { BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator()); EXPECT_TRUE(EntryBr->isConditional()); EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB); - BasicBlock *ExitBB = ThenBB->getUniqueSuccessor(); + BasicBlock *FinalizeBB = ThenBB->getUniqueSuccessor(); + BasicBlock *ExitBB = FinalizeBB->getUniqueSuccessor(); EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB); CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition()); @@ -3743,25 +3743,28 @@ TEST_F(OpenMPIRBuilderTest, SingleDirectiveCopyPrivate) { EXPECT_EQ(PrivLI->getPointerOperand(), PrivAI); // icmp EXPECT_TRUE(ThenBBI.next<ICmpInst>()); + + // check FinalizeBB + BBInstIter FinalizeBBI(FinalizeBB); // store 1, DidIt - auto *DidItSI = ThenBBI.next<StoreInst>(); + auto *DidItSI = FinalizeBBI.next<StoreInst>(); EXPECT_NE(DidItSI, nullptr); EXPECT_EQ(DidItSI->getValueOperand(), ConstantInt::get(Type::getInt32Ty(Ctx), 1)); Value *DidIt = DidItSI->getPointerOperand(); // call __kmpc_end_single - auto *SingleEndCI = ThenBBI.next<CallInst>(); + auto *SingleEndCI = FinalizeBBI.next<CallInst>(); EXPECT_NE(SingleEndCI, nullptr); EXPECT_EQ(SingleEndCI->getCalledFunction()->getName(), "__kmpc_end_single"); EXPECT_EQ(SingleEndCI->arg_size(), 2U); EXPECT_TRUE(isa<GlobalVariable>(SingleEndCI->getArgOperand(0))); EXPECT_EQ(SingleEndCI->getArgOperand(1), SingleEntryCI->getArgOperand(1)); // br ExitBB - auto *ExitBBBI = ThenBBI.next<BranchInst>(); + auto *ExitBBBI = FinalizeBBI.next<BranchInst>(); EXPECT_NE(ExitBBBI, nullptr); EXPECT_TRUE(ExitBBBI->isUnconditional()); EXPECT_EQ(ExitBBBI->getOperand(0), ExitBB); - EXPECT_FALSE(ThenBBI.hasNext()); + EXPECT_FALSE(FinalizeBBI.hasNext()); // check ExitBB BBInstIter ExitBBI(ExitBB); @@ -5298,10 +5301,12 @@ TEST_F(OpenMPIRBuilderTest, CreateReductions) { OpenMPIRBuilder::ReductionInfo ReductionInfos[] = { {SumType, SumReduced, SumPrivatized, /*EvaluationKind=*/OpenMPIRBuilder::EvalKind::Scalar, sumReduction, - /*ReductionGenClang=*/nullptr, sumAtomicReduction}, + /*ReductionGenClang=*/nullptr, sumAtomicReduction, + /*DataPtrPtrGen=*/nullptr}, {XorType, XorReduced, XorPrivatized, /*EvaluationKind=*/OpenMPIRBuilder::EvalKind::Scalar, xorReduction, - /*ReductionGenClang=*/nullptr, xorAtomicReduction}}; + /*ReductionGenClang=*/nullptr, xorAtomicReduction, + /*DataPtrPtrGen=*/nullptr}}; OMPBuilder.Config.setIsGPU(false); bool ReduceVariableByRef[] = {false, false}; @@ -5533,10 +5538,11 @@ TEST_F(OpenMPIRBuilderTest, ScanReduction) { EXPECT_EQ(ScanLoop->getAfter(), Builder.GetInsertBlock()); EXPECT_EQ(NumBodiesGenerated, 2U); - SmallVector<OpenMPIRBuilder::ReductionInfo> ReductionInfos = { + SmallVector<OpenMPIRBuilder::ReductionInfo, 2> ReductionInfos = { {Builder.getFloatTy(), OrigVar, ScanVar, /*EvaluationKind=*/OpenMPIRBuilder::EvalKind::Scalar, sumReduction, - /*ReductionGenClang=*/nullptr, sumAtomicReduction}}; + /*ReductionGenClang=*/nullptr, sumAtomicReduction, + /*DataPtrPtrGen=*/nullptr}}; OpenMPIRBuilder::LocationDescription RedLoc({InputLoop->getAfterIP(), DL}); llvm::BasicBlock *Cont = splitBB(Builder, false, "omp.scan.loop.cont"); ASSERT_EXPECTED_INIT( @@ -5708,7 +5714,8 @@ TEST_F(OpenMPIRBuilderTest, CreateTwoReductions) { FirstBodyIP, FirstBodyAllocaIP, {{SumType, SumReduced, SumPrivatized, /*EvaluationKind=*/OpenMPIRBuilder::EvalKind::Scalar, sumReduction, - /*ReductionGenClang=*/nullptr, sumAtomicReduction}}, + /*ReductionGenClang=*/nullptr, sumAtomicReduction, + /*DataPtrPtrGen=*/nullptr}}, ReduceVariableByRef), Succeeded()); ASSERT_THAT_EXPECTED( @@ -5716,7 +5723,8 @@ TEST_F(OpenMPIRBuilderTest, CreateTwoReductions) { SecondBodyIP, SecondBodyAllocaIP, {{XorType, XorReduced, XorPrivatized, /*EvaluationKind=*/OpenMPIRBuilder::EvalKind::Scalar, xorReduction, - /*ReductionGenClang=*/nullptr, xorAtomicReduction}}, + /*ReductionGenClang=*/nullptr, xorAtomicReduction, + /*DataPtrPtrGen=*/nullptr}}, ReduceVariableByRef), Succeeded()); diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index 53d581c..13712a7 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -449,6 +449,9 @@ TEST_F(ConstantRangeTest, Trunc) { // trunc([7, 1), 3->2) = [3, 1) ConstantRange SevenOne(APInt(3, 7), APInt(3, 1)); EXPECT_EQ(SevenOne.truncate(2), ConstantRange(APInt(2, 3), APInt(2, 1))); + + ConstantRange Nop = Full.truncate(Full.getBitWidth()); + EXPECT_EQ(Full, Nop); } TEST_F(ConstantRangeTest, TruncNuw) { @@ -527,6 +530,9 @@ TEST_F(ConstantRangeTest, ZExt) { // zext([5, 0), 3->7) = [5, 8) ConstantRange FiveZero(APInt(3, 5), APInt(3, 0)); EXPECT_EQ(FiveZero.zeroExtend(7), ConstantRange(APInt(7, 5), APInt(7, 8))); + + ConstantRange Nop = Full.zeroExtend(Full.getBitWidth()); + EXPECT_EQ(Full, Nop); } TEST_F(ConstantRangeTest, SExt) { @@ -550,6 +556,9 @@ TEST_F(ConstantRangeTest, SExt) { EXPECT_EQ(ConstantRange(APInt(16, 0x0200), APInt(16, 0x8000)).signExtend(19), ConstantRange(APInt(19, 0x0200), APInt(19, 0x8000))); + + ConstantRange Nop = Full.signExtend(Full.getBitWidth()); + EXPECT_EQ(Full, Nop); } TEST_F(ConstantRangeTest, IntersectWith) { diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp index 6376165..07dd121 100644 --- a/llvm/unittests/IR/ConstantsTest.cpp +++ b/llvm/unittests/IR/ConstantsTest.cpp @@ -835,5 +835,36 @@ TEST(ConstantsTest, BlockAddressCAPITest) { EXPECT_EQ(&BB, OutBB); } +TEST(ConstantsTest, Float128Test) { + LLVMContextRef C = LLVMContextCreate(); + LLVMTypeRef Ty128 = LLVMFP128TypeInContext(C); + LLVMTypeRef TyPPC128 = LLVMPPCFP128TypeInContext(C); + LLVMTypeRef TyFloat = LLVMFloatTypeInContext(C); + LLVMTypeRef TyDouble = LLVMDoubleTypeInContext(C); + LLVMTypeRef TyHalf = LLVMHalfTypeInContext(C); + LLVMBuilderRef Builder = LLVMCreateBuilderInContext(C); + uint64_t n[2] = {0x4000000000000000, 0x0}; //+2 + uint64_t m[2] = {0xC000000000000000, 0x0}; //-2 + LLVMValueRef val1 = LLVMConstFPFromBits(Ty128, n); + EXPECT_TRUE(val1 != nullptr); + LLVMValueRef val2 = LLVMConstFPFromBits(Ty128, m); + EXPECT_TRUE(val2 != nullptr); + LLVMValueRef val3 = LLVMBuildFAdd(Builder, val1, val2, "test"); + EXPECT_TRUE(val3 != nullptr); + LLVMValueRef val4 = LLVMConstFPFromBits(TyPPC128, n); + EXPECT_TRUE(val4 != nullptr); + uint64_t p[1] = {0x0000000040000000}; //+2 + LLVMValueRef val5 = LLVMConstFPFromBits(TyFloat, p); + EXPECT_EQ(APFloat(2.0f), unwrap<ConstantFP>(val5)->getValue()); + uint64_t q[1] = {0x4000000000000000}; //+2 + LLVMValueRef val6 = LLVMConstFPFromBits(TyDouble, q); + EXPECT_EQ(APFloat(2.0), unwrap<ConstantFP>(val6)->getValue()); + uint64_t r[1] = {0x0000000000003c00}; //+1 + LLVMValueRef val7 = LLVMConstFPFromBits(TyHalf, r); + EXPECT_TRUE(val7 != nullptr); + LLVMDisposeBuilder(Builder); + LLVMContextDispose(C); +} + } // end anonymous namespace } // end namespace llvm diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp index cfd99ed..87d922d 100644 --- a/llvm/unittests/IR/IntrinsicsTest.cpp +++ b/llvm/unittests/IR/IntrinsicsTest.cpp @@ -30,14 +30,12 @@ using namespace llvm; namespace { - class IntrinsicsTest : public ::testing::Test { +protected: LLVMContext Context; std::unique_ptr<Module> M; BasicBlock *BB = nullptr; - void TearDown() override { M.reset(); } - void SetUp() override { M = std::make_unique<Module>("Test", Context); auto F = M->getOrInsertFunction( @@ -46,6 +44,8 @@ class IntrinsicsTest : public ::testing::Test { EXPECT_NE(BB, nullptr); } + void TearDown() override { M.reset(); } + public: Instruction *makeIntrinsic(Intrinsic::ID ID) const { IRBuilder<> Builder(BB); @@ -197,4 +197,212 @@ TEST(IntrinsicAttributes, TestGetFnAttributesBug) { AttributeSet AS = getFnAttributes(Context, experimental_guard); EXPECT_FALSE(AS.hasAttributes()); } + +// Tests non-overloaded intrinsic declaration. +TEST_F(IntrinsicsTest, NonOverloadedIntrinsic) { + Type *RetTy = Type::getVoidTy(Context); + SmallVector<Type *, 1> ArgTys; + ArgTys.push_back(Type::getInt1Ty(Context)); + + Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::assume, + RetTy, ArgTys); + + ASSERT_NE(F, nullptr); + EXPECT_EQ(F->getIntrinsicID(), Intrinsic::assume); + EXPECT_EQ(F->getReturnType(), RetTy); + EXPECT_EQ(F->arg_size(), 1u); + EXPECT_FALSE(F->isVarArg()); + EXPECT_EQ(F->getName(), "llvm.assume"); +} + +// Tests overloaded intrinsic with automatic type resolution for scalar types. +TEST_F(IntrinsicsTest, OverloadedIntrinsicScalar) { + Type *RetTy = Type::getInt32Ty(Context); + SmallVector<Type *, 2> ArgTys; + ArgTys.push_back(Type::getInt32Ty(Context)); + ArgTys.push_back(Type::getInt32Ty(Context)); + + Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax, + RetTy, ArgTys); + + ASSERT_NE(F, nullptr); + EXPECT_EQ(F->getIntrinsicID(), Intrinsic::umax); + EXPECT_EQ(F->getReturnType(), RetTy); + EXPECT_EQ(F->arg_size(), 2u); + EXPECT_FALSE(F->isVarArg()); + EXPECT_EQ(F->getName(), "llvm.umax.i32"); +} + +// Tests overloaded intrinsic with automatic type resolution for vector types. +TEST_F(IntrinsicsTest, OverloadedIntrinsicVector) { + Type *RetTy = FixedVectorType::get(Type::getInt32Ty(Context), 4); + SmallVector<Type *, 2> ArgTys; + ArgTys.push_back(RetTy); + ArgTys.push_back(RetTy); + + Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax, + RetTy, ArgTys); + + ASSERT_NE(F, nullptr); + EXPECT_EQ(F->getIntrinsicID(), Intrinsic::umax); + EXPECT_EQ(F->getReturnType(), RetTy); + EXPECT_EQ(F->arg_size(), 2u); + EXPECT_FALSE(F->isVarArg()); + EXPECT_EQ(F->getName(), "llvm.umax.v4i32"); +} + +// Tests overloaded intrinsic with automatic type resolution for addrspace. +TEST_F(IntrinsicsTest, OverloadedIntrinsicAddressSpace) { + Type *RetTy = Type::getVoidTy(Context); + SmallVector<Type *, 4> ArgTys; + ArgTys.push_back(PointerType::get(Context, 1)); // ptr addrspace(1) + ArgTys.push_back(Type::getInt32Ty(Context)); // rw + ArgTys.push_back(Type::getInt32Ty(Context)); // locality + ArgTys.push_back(Type::getInt32Ty(Context)); // cache type + + Function *F = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::prefetch, + RetTy, ArgTys); + + ASSERT_NE(F, nullptr); + EXPECT_EQ(F->getIntrinsicID(), Intrinsic::prefetch); + EXPECT_EQ(F->getReturnType(), RetTy); + EXPECT_EQ(F->arg_size(), 4u); + EXPECT_FALSE(F->isVarArg()); + EXPECT_EQ(F->getName(), "llvm.prefetch.p1"); +} + +// Tests vararg intrinsic declaration. +TEST_F(IntrinsicsTest, VarArgIntrinsicStatepoint) { + Type *RetTy = Type::getTokenTy(Context); + SmallVector<Type *, 5> ArgTys; + ArgTys.push_back(Type::getInt64Ty(Context)); // ID + ArgTys.push_back(Type::getInt32Ty(Context)); // NumPatchBytes + ArgTys.push_back(PointerType::get(Context, 0)); // Target + ArgTys.push_back(Type::getInt32Ty(Context)); // NumCallArgs + ArgTys.push_back(Type::getInt32Ty(Context)); // Flags + + Function *F = Intrinsic::getOrInsertDeclaration( + M.get(), Intrinsic::experimental_gc_statepoint, RetTy, ArgTys); + + ASSERT_NE(F, nullptr); + EXPECT_EQ(F->getIntrinsicID(), Intrinsic::experimental_gc_statepoint); + EXPECT_EQ(F->getReturnType(), RetTy); + EXPECT_EQ(F->arg_size(), 5u); + EXPECT_TRUE(F->isVarArg()) << "experimental_gc_statepoint must be vararg"; + EXPECT_EQ(F->getName(), "llvm.experimental.gc.statepoint.p0"); +} + +// Tests that different overloads create different declarations. +TEST_F(IntrinsicsTest, DifferentOverloads) { + // i32 version + Type *RetTy32 = Type::getInt32Ty(Context); + SmallVector<Type *, 2> ArgTys32; + ArgTys32.push_back(Type::getInt32Ty(Context)); + ArgTys32.push_back(Type::getInt32Ty(Context)); + + Function *Func32 = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax, + RetTy32, ArgTys32); + + // i64 version + Type *RetTy64 = Type::getInt64Ty(Context); + SmallVector<Type *, 2> ArgTys64; + ArgTys64.push_back(Type::getInt64Ty(Context)); + ArgTys64.push_back(Type::getInt64Ty(Context)); + + Function *Func64 = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::umax, + RetTy64, ArgTys64); + + EXPECT_NE(Func32, Func64) + << "Different overloads should be different functions"; + EXPECT_EQ(Func32->getName(), "llvm.umax.i32"); + EXPECT_EQ(Func64->getName(), "llvm.umax.i64"); +} + +// Tests IRBuilder::CreateIntrinsic with overloaded scalar type. +TEST_F(IntrinsicsTest, IRBuilderCreateIntrinsicScalar) { + IRBuilder<> Builder(BB); + + Type *RetTy = Type::getInt32Ty(Context); + SmallVector<Value *, 2> Args; + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 10)); + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 20)); + + CallInst *CI = Builder.CreateIntrinsic(RetTy, Intrinsic::umax, Args); + + ASSERT_NE(CI, nullptr); + EXPECT_EQ(CI->getIntrinsicID(), Intrinsic::umax); + EXPECT_EQ(CI->getType(), RetTy); + EXPECT_EQ(CI->arg_size(), 2u); + EXPECT_FALSE(CI->getCalledFunction()->isVarArg()); +} + +// Tests IRBuilder::CreateIntrinsic with overloaded vector type. +TEST_F(IntrinsicsTest, IRBuilderCreateIntrinsicVector) { + IRBuilder<> Builder(BB); + + Type *RetTy = FixedVectorType::get(Type::getInt32Ty(Context), 4); + SmallVector<Value *, 2> Args; + Args.push_back(Constant::getNullValue(RetTy)); + Args.push_back(Constant::getNullValue(RetTy)); + + CallInst *CI = Builder.CreateIntrinsic(RetTy, Intrinsic::umax, Args); + + ASSERT_NE(CI, nullptr); + EXPECT_EQ(CI->getIntrinsicID(), Intrinsic::umax); + EXPECT_EQ(CI->getType(), RetTy); + EXPECT_EQ(CI->arg_size(), 2u); + EXPECT_FALSE(CI->getCalledFunction()->isVarArg()); +} + +// Tests IRBuilder::CreateIntrinsic with overloaded address space. +TEST_F(IntrinsicsTest, IRBuilderCreateIntrinsicAddressSpace) { + IRBuilder<> Builder(BB); + + Type *RetTy = Type::getVoidTy(Context); + SmallVector<Value *, 4> Args; + Args.push_back(Constant::getNullValue( + PointerType::get(Context, 1))); // ptr addrspace(1) null + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0)); // rw + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 3)); // locality + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 1)); // cache type + + CallInst *CI = Builder.CreateIntrinsic(RetTy, Intrinsic::prefetch, Args); + + ASSERT_NE(CI, nullptr); + EXPECT_EQ(CI->getIntrinsicID(), Intrinsic::prefetch); + EXPECT_EQ(CI->getType(), RetTy); + EXPECT_EQ(CI->arg_size(), 4u); + EXPECT_FALSE(CI->getCalledFunction()->isVarArg()); + EXPECT_EQ(CI->getCalledFunction()->getName(), "llvm.prefetch.p1"); +} + +// Tests IRBuilder::CreateIntrinsic with vararg intrinsic. +TEST_F(IntrinsicsTest, IRBuilderCreateIntrinsicVarArg) { + IRBuilder<> Builder(BB); + + // Create a dummy function to call through statepoint + FunctionType *DummyFnTy = FunctionType::get(Type::getVoidTy(Context), false); + Function *DummyFn = Function::Create(DummyFnTy, GlobalValue::ExternalLinkage, + "dummy", M.get()); + + Type *RetTy = Type::getTokenTy(Context); + SmallVector<Value *, 5> Args; + Args.push_back(ConstantInt::get(Type::getInt64Ty(Context), 0)); // ID + Args.push_back( + ConstantInt::get(Type::getInt32Ty(Context), 0)); // NumPatchBytes + Args.push_back(DummyFn); // Target + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0)); // NumCallArgs + Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0)); // Flags + + CallInst *CI = Builder.CreateIntrinsic( + RetTy, Intrinsic::experimental_gc_statepoint, Args); + + ASSERT_NE(CI, nullptr); + EXPECT_EQ(CI->getIntrinsicID(), Intrinsic::experimental_gc_statepoint); + EXPECT_EQ(CI->getType(), RetTy); + EXPECT_EQ(CI->arg_size(), 5u); + EXPECT_TRUE(CI->getCalledFunction()->isVarArg()) + << "experimental_gc_statepoint must be vararg"; +} + } // end namespace diff --git a/llvm/unittests/IR/ModuleTest.cpp b/llvm/unittests/IR/ModuleTest.cpp index 30eda73..1e4565b 100644 --- a/llvm/unittests/IR/ModuleTest.cpp +++ b/llvm/unittests/IR/ModuleTest.cpp @@ -433,4 +433,82 @@ define void @Foo2() { ASSERT_EQ(M2Str, M1Print); } +TEST(ModuleTest, FunctionDefinitions) { + // Test getFunctionDefs() method which returns only functions with bodies + LLVMContext Context; + SMDiagnostic Err; + std::unique_ptr<Module> M = parseAssemblyString(R"( +declare void @Decl1() +declare void @Decl2() + +define void @Def1() { + ret void +} + +define void @Def2() { + ret void +} + +declare void @Decl3() + +define void @Def3() { + ret void +} +)", + Err, Context); + ASSERT_TRUE(M); + + // Count total functions (should be 6: 3 declarations + 3 definitions) + size_t TotalFunctions = 0; + for (Function &F : *M) { + (void)F; + ++TotalFunctions; + } + EXPECT_EQ(TotalFunctions, 6u); + + // Count function definitions only (should be 3) + size_t DefinitionCount = 0; + for (Function &F : M->getFunctionDefs()) { + EXPECT_FALSE(F.isDeclaration()); + ++DefinitionCount; + } + EXPECT_EQ(DefinitionCount, 3u); + + // Verify the names of the definitions + auto DefRange = M->getFunctionDefs(); + auto It = DefRange.begin(); + EXPECT_EQ(It->getName(), "Def1"); + ++It; + EXPECT_EQ(It->getName(), "Def2"); + ++It; + EXPECT_EQ(It->getName(), "Def3"); + ++It; + EXPECT_EQ(It, DefRange.end()); +} + +TEST(ModuleTest, FunctionDefinitionsEmpty) { + // Test getFunctionDefs() with no definitions (only declarations) + LLVMContext Context; + SMDiagnostic Err; + std::unique_ptr<Module> M = parseAssemblyString(R"( +declare void @Decl1() +declare void @Decl2() +declare void @Decl3() +)", + Err, Context); + ASSERT_TRUE(M); + + // Should have functions + EXPECT_FALSE(M->empty()); + EXPECT_EQ(M->size(), 3u); + + // But no definitions + size_t DefinitionCount = 0; + for (Function &F : M->getFunctionDefs()) { + (void)F; + ++DefinitionCount; + } + EXPECT_EQ(DefinitionCount, 0u); +} + } // end namespace diff --git a/llvm/unittests/IR/VPIntrinsicTest.cpp b/llvm/unittests/IR/VPIntrinsicTest.cpp index 0dd352a..5dd9791 100644 --- a/llvm/unittests/IR/VPIntrinsicTest.cpp +++ b/llvm/unittests/IR/VPIntrinsicTest.cpp @@ -111,8 +111,6 @@ protected: "addrspace(1)*, i32, <8 x i1>, i32) "; Str << " declare <8 x i32> @llvm.vp.gather.v8i32.v8p0i32(<8 x i32*>, <8 x " "i1>, i32) "; - Str << " declare <8 x i32> @llvm.experimental.vp.splat.v8i32(i32, <8 x " - "i1>, i32) "; for (const char *ReductionOpcode : ReductionIntOpcodes) Str << " declare i32 @llvm.vp.reduce." << ReductionOpcode diff --git a/llvm/unittests/Object/ELFTest.cpp b/llvm/unittests/Object/ELFTest.cpp index 7c68ab5..61ec78f 100644 --- a/llvm/unittests/Object/ELFTest.cpp +++ b/llvm/unittests/Object/ELFTest.cpp @@ -255,6 +255,20 @@ TEST(ELFTest, getELFRelocationTypeNameForLoongArch) { getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_CALL36)); } +TEST(ELFTest, getRISCVVendorRelocationTypeName) { + EXPECT_EQ("R_RISCV_QC_ABS20_U", + getRISCVVendorRelocationTypeName(R_RISCV_CUSTOM192, "QUALCOMM")); + EXPECT_EQ("R_RISCV_QC_E_BRANCH", + getRISCVVendorRelocationTypeName(R_RISCV_CUSTOM193, "QUALCOMM")); + EXPECT_EQ("R_RISCV_QC_E_32", + getRISCVVendorRelocationTypeName(R_RISCV_CUSTOM194, "QUALCOMM")); + EXPECT_EQ("R_RISCV_QC_E_CALL_PLT", + getRISCVVendorRelocationTypeName(R_RISCV_CUSTOM195, "QUALCOMM")); + + EXPECT_EQ("R_RISCV_NDS_BRANCH_10", + getRISCVVendorRelocationTypeName(R_RISCV_CUSTOM241, "ANDES")); +} + TEST(ELFTest, getELFRelativeRelocationType) { EXPECT_EQ(ELF::R_VE_RELATIVE, getELFRelativeRelocationType(EM_VE)); EXPECT_EQ(ELF::R_LARCH_RELATIVE, getELFRelativeRelocationType(EM_LOONGARCH)); diff --git a/llvm/unittests/Object/ELFTypesTest.cpp b/llvm/unittests/Object/ELFTypesTest.cpp index 9e99b4a..1c00c9f3 100644 --- a/llvm/unittests/Object/ELFTypesTest.cpp +++ b/llvm/unittests/Object/ELFTypesTest.cpp @@ -32,7 +32,7 @@ template <class ELFT> struct NoteTestData { Nhdr->n_type = Type; auto NameOffset = Data.begin() + sizeof(*Nhdr); - std::copy(Name.begin(), Name.end(), NameOffset); + llvm::copy(Name, NameOffset); auto DescOffset = Data.begin() + alignTo(sizeof(*Nhdr) + Nhdr->n_namesz, Align); diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp index 33928ac..168502f 100644 --- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp +++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp @@ -1385,7 +1385,7 @@ define ptr @foo() { // Check get(), getKey(), getDiscriminator(), getAddrDiscriminator(). auto *NewPtrAuth = sandboxir::ConstantPtrAuth::get( &F, PtrAuth->getKey(), PtrAuth->getDiscriminator(), - PtrAuth->getAddrDiscriminator()); + PtrAuth->getAddrDiscriminator(), PtrAuth->getDeactivationSymbol()); EXPECT_EQ(NewPtrAuth, PtrAuth); // Check hasAddressDiscriminator(). EXPECT_EQ(PtrAuth->hasAddressDiscriminator(), diff --git a/llvm/unittests/Support/HashBuilderTest.cpp b/llvm/unittests/Support/HashBuilderTest.cpp index 0aacfcd..70cb92b 100644 --- a/llvm/unittests/Support/HashBuilderTest.cpp +++ b/llvm/unittests/Support/HashBuilderTest.cpp @@ -15,7 +15,6 @@ #include <list> #include <string> -#include <type_traits> #include <utility> #include <vector> diff --git a/llvm/unittests/Support/JobserverTest.cpp b/llvm/unittests/Support/JobserverTest.cpp index d274458..df62346 100644 --- a/llvm/unittests/Support/JobserverTest.cpp +++ b/llvm/unittests/Support/JobserverTest.cpp @@ -15,6 +15,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Parallel.h" +#include "llvm/Support/Program.h" #include "llvm/Support/ThreadPool.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" @@ -40,6 +41,9 @@ using namespace llvm; +// Provided by the unit test main to locate the current test binary. +extern const char *TestMainArgv0; + namespace { // RAII helper to set an environment variable for the duration of a test. @@ -218,6 +222,9 @@ TEST_F(JobserverClientTest, UnixClientFifo) { } #if LLVM_ENABLE_THREADS +// Unique anchor whose address helps locate the current test binary. +static int JobserverTestAnchor = 0; + // Test fixture for tests that use the jobserver strategy. It creates a // temporary FIFO, sets MAKEFLAGS, and provides a helper to pre-load the FIFO // with job tokens, simulating `make -jN`. @@ -382,51 +389,93 @@ TEST_F(JobserverStrategyTest, ThreadPoolConcurrencyIsLimited) { EXPECT_EQ(CompletedTasks, NumTasks); } -TEST_F(JobserverStrategyTest, ParallelForIsLimited) { +// Parent-side driver that spawns a fresh process to run the child test which +// validates that parallelFor respects the jobserver limit when it is the first +// user of the default executor in that process. +TEST_F(JobserverStrategyTest, ParallelForIsLimited_Subprocess) { + // Mark child execution. + setenv("LLVM_JOBSERVER_TEST_CHILD", "1", 1); + + // Find the current test binary and build args to run only the child test. + std::string Executable = + sys::fs::getMainExecutable(TestMainArgv0, &JobserverTestAnchor); + ASSERT_FALSE(Executable.empty()) << "Failed to get main executable path"; + SmallVector<StringRef, 4> Args{Executable, + "--gtest_filter=JobserverStrategyTest." + "ParallelForIsLimited_SubprocessChild"}; + + std::string Error; + bool ExecFailed = false; + int RC = sys::ExecuteAndWait(Executable, Args, std::nullopt, {}, 0, 0, &Error, + &ExecFailed); + unsetenv("LLVM_JOBSERVER_TEST_CHILD"); + ASSERT_FALSE(ExecFailed) << Error; + ASSERT_EQ(RC, 0) << "Executable failed with exit code " << RC; +} + +// Child-side test: create FIFO and make-proxy in this process, set the +// jobserver strategy, and then run parallelFor. +TEST_F(JobserverStrategyTest, ParallelForIsLimited_SubprocessChild) { + if (!getenv("LLVM_JOBSERVER_TEST_CHILD")) + GTEST_SKIP() << "Not running in child mode"; + // This test verifies that llvm::parallelFor respects the jobserver limit. const int NumExplicitJobs = 3; const int ConcurrencyLimit = NumExplicitJobs + 1; // +1 implicit const int NumTasks = 20; - LLVM_DEBUG(dbgs() << "Calling startMakeProxy with " << NumExplicitJobs - << " jobs.\n"); startMakeProxy(NumExplicitJobs); - LLVM_DEBUG(dbgs() << "MakeProxy is running.\n"); - // Set the global strategy. parallelFor will use this. + // Set the global strategy before any default executor is created. parallel::strategy = jobserver_concurrency(); std::atomic<int> ActiveTasks{0}; std::atomic<int> MaxActiveTasks{0}; - parallelFor(0, NumTasks, [&](int i) { + parallelFor(0, NumTasks, [&]([[maybe_unused]] int i) { int CurrentActive = ++ActiveTasks; - LLVM_DEBUG(dbgs() << "Task " << i << ": Active tasks: " << CurrentActive - << "\n"); int OldMax = MaxActiveTasks.load(); while (CurrentActive > OldMax) MaxActiveTasks.compare_exchange_weak(OldMax, CurrentActive); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); --ActiveTasks; }); - LLVM_DEBUG(dbgs() << "ParallelFor finished. Max active tasks was " - << MaxActiveTasks << ".\n"); EXPECT_LE(MaxActiveTasks, ConcurrencyLimit); } -TEST_F(JobserverStrategyTest, ParallelSortIsLimited) { - // This test serves as an integration test to ensure parallelSort completes - // correctly when running under the jobserver strategy. It doesn't directly - // measure concurrency but verifies correctness. +// Parent-side driver for parallelSort child test. +TEST_F(JobserverStrategyTest, ParallelSortIsLimited_Subprocess) { + setenv("LLVM_JOBSERVER_TEST_CHILD", "1", 1); + + std::string Executable = + sys::fs::getMainExecutable(TestMainArgv0, &JobserverTestAnchor); + ASSERT_FALSE(Executable.empty()) << "Failed to get main executable path"; + SmallVector<StringRef, 4> Args{Executable, + "--gtest_filter=JobserverStrategyTest." + "ParallelSortIsLimited_SubprocessChild"}; + + std::string Error; + bool ExecFailed = false; + int RC = sys::ExecuteAndWait(Executable, Args, std::nullopt, {}, 0, 0, &Error, + &ExecFailed); + unsetenv("LLVM_JOBSERVER_TEST_CHILD"); + ASSERT_FALSE(ExecFailed) << Error; + ASSERT_EQ(RC, 0) << "Executable failed with exit code " << RC; +} + +// Child-side test: ensure parallelSort runs and completes correctly under the +// jobserver strategy when it owns default executor initialization. +TEST_F(JobserverStrategyTest, ParallelSortIsLimited_SubprocessChild) { + if (!getenv("LLVM_JOBSERVER_TEST_CHILD")) + GTEST_SKIP() << "Not running in child mode"; + const int NumExplicitJobs = 3; startMakeProxy(NumExplicitJobs); parallel::strategy = jobserver_concurrency(); std::vector<int> V(1024); - // Fill with random data std::mt19937 randEngine; std::uniform_int_distribution<int> dist; for (int &i : V) diff --git a/llvm/unittests/Support/LockFileManagerTest.cpp b/llvm/unittests/Support/LockFileManagerTest.cpp index 627b2da..bd61b6c 100644 --- a/llvm/unittests/Support/LockFileManagerTest.cpp +++ b/llvm/unittests/Support/LockFileManagerTest.cpp @@ -12,7 +12,6 @@ #include "llvm/Testing/Support/Error.h" #include "llvm/Testing/Support/SupportHelpers.h" #include "gtest/gtest.h" -#include <memory> using namespace llvm; using llvm::unittest::TempDir; diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp index 9c13908..128501b 100644 --- a/llvm/unittests/Support/ModRefTest.cpp +++ b/llvm/unittests/Support/ModRefTest.cpp @@ -21,7 +21,7 @@ TEST(ModRefTest, PrintMemoryEffects) { raw_string_ostream OS(S);
OS << MemoryEffects::none();
EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
- "NoModRef, Other: NoModRef");
+ "NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: NoModRef");
}
} // namespace
diff --git a/llvm/unittests/Support/NativeFormatTests.cpp b/llvm/unittests/Support/NativeFormatTests.cpp index ac04c5a..974709e 100644 --- a/llvm/unittests/Support/NativeFormatTests.cpp +++ b/llvm/unittests/Support/NativeFormatTests.cpp @@ -10,8 +10,6 @@ #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" -#include <type_traits> - using namespace llvm; namespace { diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp index eb649de..51f65bf 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -1428,7 +1428,7 @@ TEST_F(FileSystemTest, FileMapping) { fs::mapped_file_region mfr(fs::convertFDToNativeFile(FileDescriptor), fs::mapped_file_region::readwrite, Size, 0, EC); ASSERT_NO_ERROR(EC); - std::copy(Val.begin(), Val.end(), mfr.data()); + llvm::copy(Val, mfr.data()); // Explicitly add a 0. mfr.data()[Val.size()] = 0; @@ -1494,7 +1494,7 @@ TEST_F(FileSystemTest, FileMappingSync) { // Write content through mapped memory. ASSERT_NO_ERROR(EC); - std::copy(Content.begin(), Content.end(), MFR.data()); + llvm::copy(Content, MFR.data()); // Synchronize to file system. ASSERT_FALSE((bool)MFR.sync()); diff --git a/llvm/unittests/Support/SignalsTest.cpp b/llvm/unittests/Support/SignalsTest.cpp index 2964785..f871753 100644 --- a/llvm/unittests/Support/SignalsTest.cpp +++ b/llvm/unittests/Support/SignalsTest.cpp @@ -32,6 +32,11 @@ using testing::Not; #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && \ (defined(__linux__) || defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || defined(__NetBSD__)) +// Test relies on the binary this test is linked into having a GNU build ID +// note, which is not universally enabled by default (even when using Clang). +// Disable until we can reliably detect whether this is the case and skip it if +// not. See https://github.com/llvm/llvm-project/issues/168891. +#if 0 TEST(SignalsTest, PrintsSymbolizerMarkup) { auto Exit = make_scope_exit([]() { unsetenv("LLVM_ENABLE_SYMBOLIZER_MARKUP"); }); @@ -51,6 +56,7 @@ TEST(SignalsTest, PrintsSymbolizerMarkup) { // Backtrace line EXPECT_THAT(Res, MatchesRegex(".*" TAG_BEGIN "bt:0:" P_REGEX ".*")); } +#endif TEST(SignalsTest, SymbolizerMarkupDisabled) { auto Exit = make_scope_exit([]() { unsetenv("LLVM_DISABLE_SYMBOLIZATION"); }); diff --git a/llvm/unittests/Support/ThreadPool.cpp b/llvm/unittests/Support/ThreadPool.cpp index b5268c8..7f72747 100644 --- a/llvm/unittests/Support/ThreadPool.cpp +++ b/llvm/unittests/Support/ThreadPool.cpp @@ -8,6 +8,7 @@ #include "llvm/Support/ThreadPool.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS @@ -197,6 +198,42 @@ TYPED_TEST(ThreadPoolTest, AsyncMoveOnly) { ASSERT_EQ(42, f.get()); } +TYPED_TEST(ThreadPoolTest, AsyncRAIICaptures) { + CHECK_UNSUPPORTED(); + DefaultThreadPool Pool(hardware_concurrency(2)); + + // We use a task group and a non-atomic value to stress test that the chaining + // of tasks via a captured RAII object in fact chains and synchronizes within + // a group. + ThreadPoolTaskGroup Group(Pool); + int value = 0; + + // Create an RAII object that when destroyed schedules more work. This makes + // it easy to check that the RAII is resolved at the same point as a task runs + // on the thread pool. + auto schedule_next = llvm::make_scope_exit([&Group, &value] { + // We sleep before scheduling the final task to make it much more likely + // that an incorrect implementation actually exbitits a bug. Without the + // sleep, we may get "lucky" and have the second task finish before the + // assertion below fails even with an incorrect implementaiton. The + // sleep is making _failures_ more reliable, it is not needed for + // correctness and this test should only flakily _pass_, never flakily + // fail. + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + Group.async([&value] { value = 42; }); + }); + + // Now schedule the initial task, moving the RAII object to schedule the final + // task into its captures. + Group.async([schedule_next = std::move(schedule_next)]() { + // Nothing to do here, the captured RAII object does the work. + }); + + // Both tasks should complete here, synchronizing with the read of value. + Group.wait(); + ASSERT_EQ(42, value); +} + TYPED_TEST(ThreadPoolTest, GetFuture) { CHECK_UNSUPPORTED(); DefaultThreadPool Pool(hardware_concurrency(2)); diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp index 809960d..14e1efa 100644 --- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp +++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp @@ -25,6 +25,8 @@ namespace llvm { class AArch64SelectionDAGTest : public testing::Test { protected: + const TargetSubtargetInfo *STI; + static void SetUpTestCase() { LLVMInitializeAArch64TargetInfo(); LLVMInitializeAArch64Target(); @@ -55,8 +57,8 @@ protected: MachineModuleInfo MMI(TM.get()); - MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), - MMI.getContext(), 0); + STI = TM->getSubtargetImpl(*F); + MF = std::make_unique<MachineFunction>(*F, *TM, *STI, MMI.getContext(), 0); DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None); if (!DAG) @@ -337,7 +339,7 @@ TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_ADDC) { } TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -356,7 +358,7 @@ TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { } TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto Int8VT = EVT::getIntegerVT(Context, 8); @@ -382,7 +384,7 @@ TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { } TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto Int8VT = EVT::getIntegerVT(Context, 8); @@ -784,7 +786,7 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_VSHL) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -804,7 +806,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -828,7 +830,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -844,7 +846,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -864,7 +866,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { } TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -880,7 +882,7 @@ TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -898,7 +900,7 @@ TEST_F(AArch64SelectionDAGTest, } TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -914,7 +916,7 @@ TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -932,7 +934,7 @@ TEST_F(AArch64SelectionDAGTest, } TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; unsigned NumElts = 16; diff --git a/llvm/unittests/Target/AArch64/SMEAttributesTest.cpp b/llvm/unittests/Target/AArch64/SMEAttributesTest.cpp index bd0e53c..595dcd2 100644 --- a/llvm/unittests/Target/AArch64/SMEAttributesTest.cpp +++ b/llvm/unittests/Target/AArch64/SMEAttributesTest.cpp @@ -1,4 +1,4 @@ -#include "Utils/AArch64SMEAttributes.h" +#include "AArch64SMEAttributes.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp index ca9afde..c763da9 100644 --- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp +++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -#include "ARMISelLowering.h" +#include "ARMSelectionDAGInfo.h" #include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/AsmParser/Parser.h" diff --git a/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp b/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp index da71300..321c092 100644 --- a/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp +++ b/llvm/unittests/Target/SPIRV/SPIRVAPITest.cpp @@ -20,7 +20,6 @@ #include "gtest/gtest.h" #include <gmock/gmock.h> #include <string> -#include <utility> namespace llvm { diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index c55cd94..1a4bdda 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -1194,7 +1194,7 @@ R"(All available -march extensions for RISC-V xwchc 2.2 Experimental extensions - p 0.15 + p 0.18 zibi 0.1 zicfilp 1.0 This is a long dummy description zicfiss 1.0 diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 0e5d40a..92e2d77 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1413,7 +1413,6 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_PREDRES, AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_F32MM, - AArch64::AEK_F64MM, AArch64::AEK_TME, AArch64::AEK_LS64, AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, AArch64::AEK_SME, AArch64::AEK_SMEF64F64, @@ -1452,7 +1451,9 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { AArch64::AEK_GCIE, AArch64::AEK_SME2P3, AArch64::AEK_SVE2P3, AArch64::AEK_SVE_B16MM, AArch64::AEK_F16MM, AArch64::AEK_F16F32DOT, - AArch64::AEK_F16F32MM, + AArch64::AEK_F16F32MM, AArch64::AEK_MOPS_GO, + AArch64::AEK_POE2, AArch64::AEK_TEV, + AArch64::AEK_BTIE, AArch64::AEK_F64MM, }; std::vector<StringRef> Features; @@ -1511,7 +1512,6 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+i8mm")); EXPECT_TRUE(llvm::is_contained(Features, "+f32mm")); EXPECT_TRUE(llvm::is_contained(Features, "+f64mm")); - EXPECT_TRUE(llvm::is_contained(Features, "+tme")); EXPECT_TRUE(llvm::is_contained(Features, "+ls64")); EXPECT_TRUE(llvm::is_contained(Features, "+brbe")); EXPECT_TRUE(llvm::is_contained(Features, "+pauth")); @@ -1576,6 +1576,10 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+f16mm")); EXPECT_TRUE(llvm::is_contained(Features, "+f16f32dot")); EXPECT_TRUE(llvm::is_contained(Features, "+f16f32mm")); + EXPECT_TRUE(llvm::is_contained(Features, "+mops-go")); + EXPECT_TRUE(llvm::is_contained(Features, "+poe2")); + EXPECT_TRUE(llvm::is_contained(Features, "+tev")); + EXPECT_TRUE(llvm::is_contained(Features, "+btie")); // Assuming we listed every extension above, this should produce the same // result. @@ -1696,7 +1700,6 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"rcpc", "norcpc", "+rcpc", "-rcpc"}, {"rng", "norng", "+rand", "-rand"}, {"memtag", "nomemtag", "+mte", "-mte"}, - {"tme", "notme", "+tme", "-tme"}, {"pauth", "nopauth", "+pauth", "-pauth"}, {"ssbs", "nossbs", "+ssbs", "-ssbs"}, {"sb", "nosb", "+sb", "-sb"}, @@ -1754,6 +1757,10 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"f16mm", "nof16mm", "+f16mm", "-f16mm"}, {"f16f32dot", "nof16f32dot", "+f16f32dot", "-f16f32dot"}, {"f16f32mm", "nof16f32mm", "+f16f32mm", "-f16f32mm"}, + {"mops-go", "nomops-go", "+mops-go", "-mops-go"}, + {"poe2", "nopoe2", "+poe2", "-poe2"}, + {"tev", "notev", "+tev", "-tev"}, + {"btie", "nobtie", "+btie", "-btie"}, }; for (unsigned i = 0; i < std::size(ArchExt); i++) { diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp index 3e80369..df8284d 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -2630,6 +2630,17 @@ TEST(TripleTest, isMacOSVersionLT) { EXPECT_FALSE(T.isMacOSXVersionLT(10, 15, 0)); } +TEST(TripleTest, isMacOSVersionGE) { + Triple T = Triple("x86_64-apple-macos11"); + EXPECT_FALSE(T.isMacOSXVersionGE(11, 1, 0)); + EXPECT_TRUE(T.isMacOSXVersionGE(10, 15, 0)); + + T = Triple("x86_64-apple-darwin20"); + EXPECT_FALSE(T.isMacOSXVersionGE(11, 1, 0)); + EXPECT_TRUE(T.isMacOSXVersionGE(11, 0, 0)); + EXPECT_TRUE(T.isMacOSXVersionGE(10, 15, 0)); +} + TEST(TripleTest, CanonicalizeOSVersion) { EXPECT_EQ(VersionTuple(10, 15, 4), Triple::getCanonicalVersionForOS(Triple::MacOSX, diff --git a/llvm/unittests/Transforms/IPO/AttributorTest.cpp b/llvm/unittests/Transforms/IPO/AttributorTest.cpp index e345c60..8d90b30 100644 --- a/llvm/unittests/Transforms/IPO/AttributorTest.cpp +++ b/llvm/unittests/Transforms/IPO/AttributorTest.cpp @@ -17,7 +17,6 @@ #include "llvm/Testing/Support/Error.h" #include "llvm/Transforms/Utils/CallGraphUpdater.h" #include "gtest/gtest.h" -#include <memory> namespace llvm { diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp index c37ed5d..896e1de 100644 --- a/llvm/unittests/Transforms/Utils/LocalTest.cpp +++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp @@ -679,7 +679,6 @@ TEST(Local, FindDbgRecords) { findDbgUsers(Arg, Records); EXPECT_EQ(Records.size(), 1u); - SmallVector<DbgValueInst *> Vals; Records.clear(); // Arg (%a) is used twice by a single dbg_assign. Check findDbgValues returns // only 1 pointer to it rather than 2. diff --git a/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp b/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp index ce002e9..9fc9fb5 100644 --- a/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp +++ b/llvm/unittests/Transforms/Utils/LoopUtilsTest.cpp @@ -14,6 +14,7 @@ #include "llvm/AsmParser/Parser.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" @@ -195,3 +196,83 @@ TEST(LoopUtils, nestedLoopSharedLatchEstimatedTripCount) { EXPECT_EQ(getLoopEstimatedTripCount(Outer), std::nullopt); }); } + +// {get,set}LoopEstimatedTripCount implement special handling of zero. +TEST(LoopUtils, zeroEstimatedTripCount) { + LLVMContext C; + const char *IR = + "define void @foo(i1 %c) {\n" + "entry:\n" + " br label %loop0\n" + "loop0:\n" + " br i1 %c, label %loop0, label %loop1\n" + "loop1:\n" + " br i1 %c, label %loop1, label %loop2, !llvm.loop !1\n" + "loop2:\n" + " br i1 %c, label %loop2, label %exit, !prof !5, !llvm.loop !2\n" + "exit:\n" + " ret void\n" + "}\n" + "!1 = distinct !{!1, !3}\n" + "!2 = distinct !{!2, !3, !4}\n" + "!3 = !{!\"foo\", i32 5}\n" + "!4 = !{!\"llvm.loop.estimated_trip_count\", i32 10}\n" + "!5 = !{!\"branch_weights\", i32 1, i32 9}\n" + "\n"; + + // With EstimatedLoopInvocationWeight, setLoopEstimatedTripCount sets branch + // weights and llvm.loop.estimated_trip_count all to 0, so + // getLoopEstimatedTripCount returns std::nullopt. It does not touch other + // loop metadata, if any. + std::unique_ptr<Module> M = parseIR(C, IR); + run(*M, "foo", + [&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) { + assert(LI.end() - LI.begin() == 3 && "Expected three loops"); + for (Loop *L : LI) { + Instruction &LatchBranch = *L->getLoopLatch()->getTerminator(); + std::optional<int> Foo = getOptionalIntLoopAttribute(L, "foo"); + + EXPECT_EQ(setLoopEstimatedTripCount( + L, 0, /*EstimatedLoopInvocationWeight=*/1), + true); + + SmallVector<uint32_t, 2> Weights; + EXPECT_EQ(extractBranchWeights(LatchBranch, Weights), true); + EXPECT_EQ(Weights[0], 0u); + EXPECT_EQ(Weights[1], 0u); + EXPECT_EQ(getOptionalIntLoopAttribute(L, "foo"), Foo); + EXPECT_EQ(getOptionalIntLoopAttribute(L, LLVMLoopEstimatedTripCount), + 0); + EXPECT_EQ(getLoopEstimatedTripCount(L), std::nullopt); + } + }); + + // Without EstimatedLoopInvocationWeight, setLoopEstimatedTripCount sets + // llvm.loop.estimated_trip_count to 0, so getLoopEstimatedTripCount returns + // std::nullopt. It does not touch branch weights or other loop metadata, if + // any. + M = parseIR(C, IR); + run(*M, "foo", + [&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) { + assert(LI.end() - LI.begin() == 3 && "Expected three loops"); + for (Loop *L : LI) { + Instruction &LatchBranch = *L->getLoopLatch()->getTerminator(); + std::optional<int> Foo = getOptionalIntLoopAttribute(L, "foo"); + SmallVector<uint32_t, 2> WeightsOld; + bool HasWeights = extractBranchWeights(LatchBranch, WeightsOld); + + EXPECT_EQ(setLoopEstimatedTripCount(L, 0), true); + + SmallVector<uint32_t, 2> WeightsNew; + EXPECT_EQ(extractBranchWeights(LatchBranch, WeightsNew), HasWeights); + if (HasWeights) { + EXPECT_EQ(WeightsNew[0], WeightsOld[0]); + EXPECT_EQ(WeightsNew[1], WeightsOld[1]); + } + EXPECT_EQ(getOptionalIntLoopAttribute(L, "foo"), Foo); + EXPECT_EQ(getOptionalIntLoopAttribute(L, LLVMLoopEstimatedTripCount), + 0); + EXPECT_EQ(getLoopEstimatedTripCount(L), std::nullopt); + } + }); +} diff --git a/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp b/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp index dd03b4f..752029e 100644 --- a/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp +++ b/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp @@ -120,7 +120,8 @@ TEST_F(MemTransferLowerTest, MemCpyKnownLength) { MemCpyInst *MemCpyI = cast<MemCpyInst>(Inst); auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F); expandMemCpyAsLoop(MemCpyI, TTI, &SE); - auto *CopyLoopBB = getBasicBlockByName(F, "load-store-loop"); + auto *CopyLoopBB = + getBasicBlockByName(F, "static-memcpy-expansion-main-body"); Instruction *LoadInst = getInstructionByOpcode(*CopyLoopBB, Instruction::Load, 1); EXPECT_NE(nullptr, LoadInst->getMetadata(LLVMContext::MD_alias_scope)); @@ -203,7 +204,8 @@ TEST_F(MemTransferLowerTest, AtomicMemCpyKnownLength) { AnyMemCpyInst *MemCpyI = cast<AnyMemCpyInst>(Inst); auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F); expandAtomicMemCpyAsLoop(MemCpyI, TTI, &SE); - auto *CopyLoopBB = getBasicBlockByName(F, "load-store-loop"); + auto *CopyLoopBB = + getBasicBlockByName(F, "static-memcpy-expansion-main-body"); Instruction *LoadInst = getInstructionByOpcode(*CopyLoopBB, Instruction::Load, 1); EXPECT_TRUE(LoadInst->isAtomic()); @@ -248,7 +250,8 @@ TEST_F(MemTransferLowerTest, AtomicMemCpyUnKnownLength) { auto *MemCpyI = cast<AnyMemCpyInst>(Inst); auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F); expandAtomicMemCpyAsLoop(MemCpyI, TTI, &SE); - auto *CopyLoopBB = getBasicBlockByName(F, "loop-memcpy-expansion"); + auto *CopyLoopBB = + getBasicBlockByName(F, "dynamic-memcpy-expansion-main-body"); Instruction *LoadInst = getInstructionByOpcode(*CopyLoopBB, Instruction::Load, 1); EXPECT_TRUE(LoadInst->isAtomic()); diff --git a/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp b/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp index 13cfaf3..503d3a0 100644 --- a/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp +++ b/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp @@ -374,9 +374,6 @@ TEST(SSAUpdaterBulk, SimplifyPHIs) { EXPECT_EQ(Phi, Cmp->getOperand(1)); } -bool EliminateNewDuplicatePHINodes(BasicBlock *BB, - BasicBlock::phi_iterator FirstExistingPN); - // Helper to run both versions on the same input. static void RunEliminateNewDuplicatePHINode( const char *AsmText, diff --git a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp index 7f12deae..60e9c56 100644 --- a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp +++ b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp @@ -451,6 +451,10 @@ TEST(ValueMapperTest, mapValuePtrAuth) { PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "Storage0"); std::unique_ptr<GlobalVariable> Storage1 = std::make_unique<GlobalVariable>( PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "Storage1"); + std::unique_ptr<GlobalVariable> DS0 = std::make_unique<GlobalVariable>( + PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "DS0"); + std::unique_ptr<GlobalVariable> DS1 = std::make_unique<GlobalVariable>( + PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "DS1"); ConstantInt *ConstKey = ConstantInt::get(Int32Ty, 1); ConstantInt *ConstDisc = ConstantInt::get(Int64Ty, 1234); @@ -458,11 +462,12 @@ TEST(ValueMapperTest, mapValuePtrAuth) { ValueToValueMapTy VM; VM[Var0.get()] = Var1.get(); VM[Storage0.get()] = Storage1.get(); + VM[DS0.get()] = DS1.get(); - ConstantPtrAuth *Value = - ConstantPtrAuth::get(Var0.get(), ConstKey, ConstDisc, Storage0.get()); - ConstantPtrAuth *MappedValue = - ConstantPtrAuth::get(Var1.get(), ConstKey, ConstDisc, Storage1.get()); + ConstantPtrAuth *Value = ConstantPtrAuth::get(Var0.get(), ConstKey, ConstDisc, + Storage0.get(), DS0.get()); + ConstantPtrAuth *MappedValue = ConstantPtrAuth::get( + Var1.get(), ConstKey, ConstDisc, Storage1.get(), DS1.get()); EXPECT_EQ(ValueMapper(VM).mapValue(*Value), MappedValue); } diff --git a/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp index b99d656..127e830 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp @@ -113,12 +113,13 @@ compound=true N0 -> N2 [ label="F"] N1 [label = "scalar.ph:\l" + + " EMIT-SCALAR vp\<%6\> = phi [ ir\<%indvars.iv\>, middle.block ], [ ir\<0\>, ir-bb\<entry\> ]\l" + "Successor(s): ir-bb\<for.body\>\l" ] N1 -> N3 [ label=""] N3 [label = "ir-bb\<for.body\>:\l" + - " IR %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]\l" + + " IR %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] (extra operand: vp\<%6\> from scalar.ph)\l" + " IR %arr.idx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv\l" + " IR %l1 = load i32, ptr %arr.idx, align 4\l" + " IR %res = add i32 %l1, 10\l" + @@ -139,12 +140,12 @@ compound=true "vector.body:\l" + " EMIT vp\<%2\> = CANONICAL-INDUCTION ir\<0\>, vp\<%index.next\>\l" + " EMIT-SCALAR ir\<%indvars.iv\> = phi [ ir\<0\>, vector.ph ], [ ir\<%indvars.iv.next\>, vector.body ]\l" + - " EMIT ir\<%arr.idx\> = getelementptr ir\<%A\>, ir\<%indvars.iv\>\l" + + " EMIT ir\<%arr.idx\> = getelementptr inbounds ir\<%A\>, ir\<%indvars.iv\>\l" + " EMIT ir\<%l1\> = load ir\<%arr.idx\>\l" + " EMIT ir\<%res\> = add ir\<%l1\>, ir\<10\>\l" + " EMIT store ir\<%res\>, ir\<%arr.idx\>\l" + " EMIT ir\<%indvars.iv.next\> = add ir\<%indvars.iv\>, ir\<1\>\l" + - " EMIT ir\<%exitcond\> = icmp ir\<%indvars.iv.next\>, ir\<%N\>\l" + + " EMIT ir\<%exitcond\> = icmp ne ir\<%indvars.iv.next\>, ir\<%N\>\l" + " EMIT vp\<%3\> = not ir\<%exitcond\>\l" + " EMIT vp\<%index.next\> = add nuw vp\<%2\>, vp\<%0\>\l" + " EMIT branch-on-count vp\<%index.next\>, vp\<%1\>\l" + @@ -282,12 +283,13 @@ compound=true N0 -> N2 [ label="F"] N1 [label = "scalar.ph:\l" + + " EMIT-SCALAR vp\<%6\> = phi [ ir\<%iv\>, middle.block ], [ ir\<0\>, ir-bb\<entry\> ]\l" + "Successor(s): ir-bb\<loop.header\>\l" ] N1 -> N3 [ label=""] N3 [label = "ir-bb\<loop.header\>:\l" + - " IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]\l" + + " IR %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] (extra operand: vp\<%6\> from scalar.ph)\l" + " IR %arr.idx = getelementptr inbounds i32, ptr %A, i64 %iv\l" + " IR %l1 = load i32, ptr %arr.idx, align 4\l" + " IR %c = icmp eq i32 %l1, 0\l" + @@ -305,9 +307,9 @@ compound=true "vector.body:\l" + " EMIT vp\<%2\> = CANONICAL-INDUCTION ir\<0\>, vp\<%index.next\>\l" + " EMIT-SCALAR ir\<%iv\> = phi [ ir\<0\>, vector.ph ], [ ir\<%iv.next\>, loop.latch ]\l" + - " EMIT ir\<%arr.idx\> = getelementptr ir\<%A\>, ir\<%iv\>\l" + + " EMIT ir\<%arr.idx\> = getelementptr inbounds ir\<%A\>, ir\<%iv\>\l" + " EMIT ir\<%l1\> = load ir\<%arr.idx\>\l" + - " EMIT ir\<%c\> = icmp ir\<%l1\>, ir\<0\>\l" + + " EMIT ir\<%c\> = icmp eq ir\<%l1\>, ir\<0\>\l" + "Successor(s): loop.latch\l" ] N4 -> N6 [ label=""] @@ -316,7 +318,7 @@ compound=true " EMIT ir\<%res\> = add ir\<%l1\>, ir\<10\>\l" + " EMIT store ir\<%res\>, ir\<%arr.idx\>\l" + " EMIT ir\<%iv.next\> = add ir\<%iv\>, ir\<1\>\l" + - " EMIT ir\<%exitcond\> = icmp ir\<%iv.next\>, ir\<%N\>\l" + + " EMIT ir\<%exitcond\> = icmp ne ir\<%iv.next\>, ir\<%N\>\l" + " EMIT vp\<%3\> = not ir\<%exitcond\>\l" + " EMIT vp\<%index.next\> = add nuw vp\<%2\>, vp\<%0\>\l" + " EMIT branch-on-count vp\<%index.next\>, vp\<%1\>\l" + diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp index 82ecc16..a6a1f67 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -35,9 +35,9 @@ namespace { using VPInstructionTest = VPlanTestBase; TEST_F(VPInstructionTest, insertBefore) { - VPInstruction *I1 = new VPInstruction(0, {}); - VPInstruction *I2 = new VPInstruction(1, {}); - VPInstruction *I3 = new VPInstruction(2, {}); + VPInstruction *I1 = new VPInstruction(VPInstruction::StepVector, {}); + VPInstruction *I2 = new VPInstruction(VPInstruction::VScale, {}); + VPInstruction *I3 = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock &VPBB1 = *getPlan().createVPBasicBlock(""); VPBB1.appendRecipe(I1); @@ -50,9 +50,9 @@ TEST_F(VPInstructionTest, insertBefore) { } TEST_F(VPInstructionTest, eraseFromParent) { - VPInstruction *I1 = new VPInstruction(0, {}); - VPInstruction *I2 = new VPInstruction(1, {}); - VPInstruction *I3 = new VPInstruction(2, {}); + VPInstruction *I1 = new VPInstruction(VPInstruction::StepVector, {}); + VPInstruction *I2 = new VPInstruction(VPInstruction::VScale, {}); + VPInstruction *I3 = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock &VPBB1 = *getPlan().createVPBasicBlock(""); VPBB1.appendRecipe(I1); @@ -70,9 +70,9 @@ TEST_F(VPInstructionTest, eraseFromParent) { } TEST_F(VPInstructionTest, moveAfter) { - VPInstruction *I1 = new VPInstruction(0, {}); - VPInstruction *I2 = new VPInstruction(1, {}); - VPInstruction *I3 = new VPInstruction(2, {}); + VPInstruction *I1 = new VPInstruction(VPInstruction::StepVector, {}); + VPInstruction *I2 = new VPInstruction(VPInstruction::VScale, {}); + VPInstruction *I3 = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock &VPBB1 = *getPlan().createVPBasicBlock(""); VPBB1.appendRecipe(I1); @@ -83,8 +83,8 @@ TEST_F(VPInstructionTest, moveAfter) { CHECK_ITERATOR(VPBB1, I2, I1, I3); - VPInstruction *I4 = new VPInstruction(4, {}); - VPInstruction *I5 = new VPInstruction(5, {}); + VPInstruction *I4 = new VPInstruction(VPInstruction::VScale, {}); + VPInstruction *I5 = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock &VPBB2 = *getPlan().createVPBasicBlock(""); VPBB2.appendRecipe(I4); VPBB2.appendRecipe(I5); @@ -97,9 +97,9 @@ TEST_F(VPInstructionTest, moveAfter) { } TEST_F(VPInstructionTest, moveBefore) { - VPInstruction *I1 = new VPInstruction(0, {}); - VPInstruction *I2 = new VPInstruction(1, {}); - VPInstruction *I3 = new VPInstruction(2, {}); + VPInstruction *I1 = new VPInstruction(VPInstruction::StepVector, {}); + VPInstruction *I2 = new VPInstruction(VPInstruction::VScale, {}); + VPInstruction *I3 = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock &VPBB1 = *getPlan().createVPBasicBlock(""); VPBB1.appendRecipe(I1); @@ -110,8 +110,8 @@ TEST_F(VPInstructionTest, moveBefore) { CHECK_ITERATOR(VPBB1, I2, I1, I3); - VPInstruction *I4 = new VPInstruction(4, {}); - VPInstruction *I5 = new VPInstruction(5, {}); + VPInstruction *I4 = new VPInstruction(VPInstruction::VScale, {}); + VPInstruction *I5 = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock &VPBB2 = *getPlan().createVPBasicBlock(""); VPBB2.appendRecipe(I4); VPBB2.appendRecipe(I5); @@ -136,7 +136,7 @@ TEST_F(VPInstructionTest, setOperand) { IntegerType *Int32 = IntegerType::get(C, 32); VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2)); - VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {VPV1, VPV2}); EXPECT_EQ(1u, VPV1->getNumUsers()); EXPECT_EQ(I1, *VPV1->user_begin()); EXPECT_EQ(1u, VPV2->getNumUsers()); @@ -179,7 +179,7 @@ TEST_F(VPInstructionTest, replaceAllUsesWith) { IntegerType *Int32 = IntegerType::get(C, 32); VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2)); - VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {VPV1, VPV2}); // Replace all uses of VPV1 with VPV3. VPValue *VPV3 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3)); @@ -210,7 +210,7 @@ TEST_F(VPInstructionTest, replaceAllUsesWith) { EXPECT_EQ(0u, VPV2->getNumUsers()); EXPECT_EQ(0u, VPV3->getNumUsers()); - VPInstruction *I2 = new VPInstruction(0, {VPV1, VPV2}); + VPInstruction *I2 = new VPInstruction(Instruction::Add, {VPV1, VPV2}); EXPECT_EQ(3u, VPV1->getNumUsers()); VPV1->replaceAllUsesWith(VPV3); EXPECT_EQ(3u, VPV3->getNumUsers()); @@ -223,7 +223,7 @@ TEST_F(VPInstructionTest, releaseOperandsAtDeletion) { IntegerType *Int32 = IntegerType::get(C, 32); VPValue *VPV1 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VPV2 = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); - VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {VPV1, VPV2}); EXPECT_EQ(1u, VPV1->getNumUsers()); EXPECT_EQ(I1, *VPV1->user_begin()); @@ -706,7 +706,7 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) { TEST_F(VPBasicBlockTest, splitAtEnd) { VPlan &Plan = getPlan(); - VPInstruction *VPI = new VPInstruction(0, {}); + VPInstruction *VPI = new VPInstruction(VPInstruction::StepVector, {}); VPBasicBlock *VPBB = Plan.createVPBasicBlock("VPBB1", VPI); VPBlockUtils::connectBlocks(Plan.getEntry(), VPBB); VPBlockUtils::connectBlocks(VPBB, Plan.getScalarHeader()); @@ -720,16 +720,14 @@ TEST_F(VPBasicBlockTest, splitAtEnd) { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) TEST_F(VPBasicBlockTest, print) { - VPInstruction *TC = new VPInstruction(Instruction::PHI, {}); - VPlan &Plan = getPlan(TC); + VPlan &Plan = getPlan(); IntegerType *Int32 = IntegerType::get(C, 32); VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPBasicBlock *VPBB0 = Plan.getEntry(); - VPBB0->appendRecipe(TC); VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val}); VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val}); - VPInstruction *I3 = new VPInstruction(Instruction::Br, {I1, I2}); + VPInstruction *I3 = new VPInstruction(Instruction::Store, {I1, I2}); VPBasicBlock *VPBB1 = Plan.createVPBasicBlock(""); VPBB1->appendRecipe(I1); @@ -738,7 +736,7 @@ TEST_F(VPBasicBlockTest, print) { VPBB1->setName("bb1"); VPInstruction *I4 = new VPInstruction(Instruction::Mul, {I2, I1}); - VPInstruction *I5 = new VPInstruction(Instruction::Br, {I4}); + VPInstruction *I5 = new VPInstruction(Instruction::Freeze, {I4}); VPBasicBlock *VPBB2 = Plan.createVPBasicBlock(""); VPBB2->appendRecipe(I4); VPBB2->appendRecipe(I5); @@ -751,8 +749,8 @@ TEST_F(VPBasicBlockTest, print) { std::string I3Dump; raw_string_ostream OS(I3Dump); VPSlotTracker SlotTracker; - I3->print(OS, "", SlotTracker); - EXPECT_EQ("EMIT br <badref>, <badref>", I3Dump); + cast<VPRecipeBase>(I3)->print(OS, "", SlotTracker); + EXPECT_EQ("EMIT store <badref>, <badref>", I3Dump); } VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader()); @@ -762,28 +760,27 @@ TEST_F(VPBasicBlockTest, print) { Plan.printDOT(OS); const char *ExpectedStr = R"(digraph VPlan { -graph [labelloc=t, fontsize=30; label="Vectorization Plan\n for UF\>=1\nvp\<%1\> = original trip-count\n"] +graph [labelloc=t, fontsize=30; label="Vectorization Plan\n for UF\>=1\nLive-in ir\<1024\> = original trip-count\n"] node [shape=rect, fontname=Courier, fontsize=30] edge [fontname=Courier, fontsize=30] compound=true N0 [label = "preheader:\l" + - " EMIT-SCALAR vp\<%1\> = phi \l" + "Successor(s): bb1\l" ] N0 -> N1 [ label=""] N1 [label = "bb1:\l" + - " EMIT vp\<%2\> = add ir\<1\>, ir\<1\>\l" + - " EMIT vp\<%3\> = sub vp\<%2\>, ir\<1\>\l" + - " EMIT br vp\<%2\>, vp\<%3\>\l" + + " EMIT vp\<%1\> = add ir\<1\>, ir\<1\>\l" + + " EMIT vp\<%2\> = sub vp\<%1\>, ir\<1\>\l" + + " EMIT store vp\<%1\>, vp\<%2\>\l" + "Successor(s): bb2\l" ] N1 -> N2 [ label=""] N2 [label = "bb2:\l" + - " EMIT vp\<%5\> = mul vp\<%3\>, vp\<%2\>\l" + - " EMIT br vp\<%5\>\l" + + " EMIT vp\<%4\> = mul vp\<%2\>, vp\<%1\>\l" + + " EMIT vp\<%5\> = freeze vp\<%4\>\l" + "Successor(s): ir-bb\<scalar.header\>\l" ] N2 -> N3 [ label=""] @@ -796,9 +793,9 @@ compound=true EXPECT_EQ(ExpectedStr, FullDump); const char *ExpectedBlock1Str = R"(bb1: - EMIT vp<%2> = add ir<1>, ir<1> - EMIT vp<%3> = sub vp<%2>, ir<1> - EMIT br vp<%2>, vp<%3> + EMIT vp<%1> = add ir<1>, ir<1> + EMIT vp<%2> = sub vp<%1>, ir<1> + EMIT store vp<%1>, vp<%2> Successor(s): bb2 )"; std::string Block1Dump; @@ -808,8 +805,8 @@ Successor(s): bb2 // Ensure that numbering is good when dumping the second block in isolation. const char *ExpectedBlock2Str = R"(bb2: - EMIT vp<%5> = mul vp<%3>, vp<%2> - EMIT br vp<%5> + EMIT vp<%4> = mul vp<%2>, vp<%1> + EMIT vp<%5> = freeze vp<%4> Successor(s): ir-bb<scalar.header> )"; std::string Block2Dump; @@ -821,25 +818,25 @@ Successor(s): ir-bb<scalar.header> std::string I3Dump; raw_string_ostream OS(I3Dump); VPSlotTracker SlotTracker(&Plan); - I3->print(OS, "", SlotTracker); - EXPECT_EQ("EMIT br vp<%2>, vp<%3>", I3Dump); + cast<VPRecipeBase>(I3)->print(OS, "", SlotTracker); + EXPECT_EQ("EMIT store vp<%1>, vp<%2>", I3Dump); } { std::string I4Dump; raw_string_ostream OS(I4Dump); OS << *I4; - EXPECT_EQ("EMIT vp<%5> = mul vp<%3>, vp<%2>", I4Dump); + EXPECT_EQ("EMIT vp<%4> = mul vp<%2>, vp<%1>", I4Dump); } } TEST_F(VPBasicBlockTest, printPlanWithVFsAndUFs) { - VPInstruction *TC = new VPInstruction(Instruction::Sub, {}); - VPlan &Plan = getPlan(TC); + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPBasicBlock *VPBB0 = Plan.getEntry(); - VPBB0->appendRecipe(TC); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val}); VPBasicBlock *VPBB1 = Plan.createVPBasicBlock(""); VPBB1->appendRecipe(I1); VPBB1->setName("bb1"); @@ -855,14 +852,13 @@ TEST_F(VPBasicBlockTest, printPlanWithVFsAndUFs) { Plan.print(OS); const char *ExpectedStr = R"(VPlan 'TestPlan for VF={4},UF>=1' { -vp<%1> = original trip-count +Live-in ir<1024> = original trip-count preheader: - EMIT vp<%1> = sub Successor(s): bb1 bb1: - EMIT vp<%2> = add + EMIT vp<%1> = add ir<1>, ir<1> Successor(s): ir-bb<scalar.header> ir-bb<scalar.header>: @@ -879,14 +875,13 @@ No successors Plan.print(OS); const char *ExpectedStr = R"(VPlan 'TestPlan for VF={4,vscale x 8},UF>=1' { -vp<%1> = original trip-count +Live-in ir<1024> = original trip-count preheader: - EMIT vp<%1> = sub Successor(s): bb1 bb1: - EMIT vp<%2> = add + EMIT vp<%1> = add ir<1>, ir<1> Successor(s): ir-bb<scalar.header> ir-bb<scalar.header>: @@ -903,14 +898,13 @@ No successors Plan.print(OS); const char *ExpectedStr = R"(VPlan 'TestPlan for VF={4,vscale x 8},UF={4}' { -vp<%1> = original trip-count +Live-in ir<1024> = original trip-count preheader: - EMIT vp<%1> = sub Successor(s): bb1 bb1: - EMIT vp<%2> = add + EMIT vp<%1> = add ir<1>, ir<1> Successor(s): ir-bb<scalar.header> ir-bb<scalar.header>: @@ -922,7 +916,7 @@ No successors } TEST_F(VPBasicBlockTest, cloneAndPrint) { - VPlan &Plan = getPlan(nullptr); + VPlan &Plan = getPlan(); VPBasicBlock *VPBB0 = Plan.getEntry(); IntegerType *Int32 = IntegerType::get(C, 32); @@ -940,7 +934,7 @@ TEST_F(VPBasicBlockTest, cloneAndPrint) { VPBlockUtils::connectBlocks(VPBB0, VPBB1); const char *ExpectedStr = R"(digraph VPlan { -graph [labelloc=t, fontsize=30; label="Vectorization Plan\n for UF\>=1\n"] +graph [labelloc=t, fontsize=30; label="Vectorization Plan\n for UF\>=1\nLive-in ir\<1024\> = original trip-count\n"] node [shape=rect, fontname=Courier, fontsize=30] edge [fontname=Courier, fontsize=30] compound=true @@ -1002,7 +996,7 @@ TEST_F(VPRecipeTest, CastVPInstructionToVPUser) { VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPInstruction Recipe(Instruction::Add, {Op1, Op2}); - checkVPRecipeCastImpl<VPInstruction, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPInstruction, VPUser, VPIRMetadata>(&Recipe); } TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) { @@ -1015,9 +1009,9 @@ TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) { SmallVector<VPValue *, 2> Args; Args.push_back(Op1); Args.push_back(Op2); - VPWidenRecipe WidenR(*AI, make_range(Args.begin(), Args.end())); + VPWidenRecipe WidenR(*AI, Args); - checkVPRecipeCastImpl<VPWidenRecipe, VPUser>(&WidenR); + checkVPRecipeCastImpl<VPWidenRecipe, VPUser, VPIRMetadata>(&WidenR); delete AI; } @@ -1036,7 +1030,7 @@ TEST_F(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) { Args.push_back(CalledFn); VPWidenCallRecipe Recipe(Call, Fn, Args); - checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser, VPIRMetadata>(&Recipe); VPValue *VPV = &Recipe; EXPECT_TRUE(VPV->getDefiningRecipe()); @@ -1059,10 +1053,11 @@ TEST_F(VPRecipeTest, CastVPWidenSelectRecipeToVPUserAndVPDef) { Args.push_back(Op1); Args.push_back(Op2); Args.push_back(Op3); - VPWidenSelectRecipe WidenSelectR(*SelectI, + VPWidenSelectRecipe WidenSelectR(SelectI, make_range(Args.begin(), Args.end())); - checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser>(&WidenSelectR); + checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser, VPIRMetadata>( + &WidenSelectR); VPValue *VPV = &WidenSelectR; EXPECT_EQ(&WidenSelectR, VPV->getDefiningRecipe()); @@ -1098,9 +1093,9 @@ TEST_F(VPRecipeTest, CastVPWidenCastRecipeToVPUser) { IntegerType *Int64 = IntegerType::get(C, 64); auto *Cast = CastInst::CreateZExtOrBitCast(PoisonValue::get(Int32), Int64); VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); - VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, *Cast); + VPWidenCastRecipe Recipe(Instruction::ZExt, Op1, Int64, Cast); - checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser, VPIRMetadata>(&Recipe); delete Cast; } @@ -1111,7 +1106,7 @@ TEST_F(VPRecipeTest, CastVPWidenIntrinsicRecipeToVPUser) { VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPWidenIntrinsicRecipe Recipe(Intrinsic::smax, {Op1, Op2}, Int32); - checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser, VPIRMetadata>(&Recipe); } TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) { @@ -1141,7 +1136,7 @@ TEST_F(VPRecipeTest, CastVPInterleaveRecipeToVPUser) { InterleaveGroup<Instruction> IG(4, false, Align(4)); VPInterleaveRecipe Recipe(&IG, Addr, {}, Mask, false, {}, DebugLoc()); - checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser, VPIRMetadata>(&Recipe); } TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) { @@ -1157,7 +1152,7 @@ TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) { auto *Call = CallInst::Create(FTy, PoisonValue::get(FTy)); VPReplicateRecipe Recipe(Call, make_range(Args.begin(), Args.end()), true); - checkVPRecipeCastImpl<VPReplicateRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPReplicateRecipe, VPUser, VPIRMetadata>(&Recipe); delete Call; } @@ -1181,7 +1176,7 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, {}, {}); - checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser, VPIRMetadata>(&Recipe); VPValue *VPV = Recipe.getVPSingleValue(); EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); @@ -1200,7 +1195,7 @@ TEST_F(VPRecipeTest, CastVPInterleaveEVLRecipeToVPUser) { VPInterleaveRecipe BaseRecipe(&IG, Addr, {}, Mask, false, {}, DebugLoc()); VPInterleaveEVLRecipe Recipe(BaseRecipe, *EVL, Mask); - checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser, VPIRMetadata>(&Recipe); } TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) { @@ -1215,7 +1210,7 @@ TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) { VPWidenLoadRecipe BaseLoad(*Load, Addr, Mask, true, false, {}, {}); VPWidenLoadEVLRecipe Recipe(BaseLoad, Addr, *EVL, Mask); - checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser, VPIRMetadata>(&Recipe); delete Load; } @@ -1231,7 +1226,7 @@ TEST_F(VPRecipeTest, CastVPWidenStoreRecipeToVPUser) { VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPWidenStoreRecipe Recipe(*Store, Addr, StoredVal, Mask, true, false, {}, {}); - checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser, VPIRMetadata>(&Recipe); delete Store; } @@ -1250,7 +1245,7 @@ TEST_F(VPRecipeTest, CastVPWidenStoreEVLRecipeToVPUser) { {}); VPWidenStoreEVLRecipe Recipe(BaseStore, Addr, *EVL, Mask); - checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser>(&Recipe); + checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser, VPIRMetadata>(&Recipe); delete Store; } @@ -1269,7 +1264,7 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { SmallVector<VPValue *, 2> Args; Args.push_back(Op1); Args.push_back(Op2); - VPWidenRecipe Recipe(*AI, make_range(Args.begin(), Args.end())); + VPWidenRecipe Recipe(*AI, Args); EXPECT_FALSE(Recipe.mayHaveSideEffects()); EXPECT_FALSE(Recipe.mayReadFromMemory()); EXPECT_FALSE(Recipe.mayWriteToMemory()); @@ -1288,7 +1283,7 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { Args.push_back(Op1); Args.push_back(Op2); Args.push_back(Op3); - VPWidenSelectRecipe Recipe(*SelectI, make_range(Args.begin(), Args.end())); + VPWidenSelectRecipe Recipe(SelectI, make_range(Args.begin(), Args.end())); EXPECT_FALSE(Recipe.mayHaveSideEffects()); EXPECT_FALSE(Recipe.mayReadFromMemory()); EXPECT_FALSE(Recipe.mayWriteToMemory()); @@ -1323,35 +1318,29 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { } { - auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32), - PoisonValue::get(Int32)); VPValue *ChainOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VecOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPValue *CondOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 3)); - VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), Add, ChainOp, - CondOp, VecOp, false); + VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), ChainOp, VecOp, + CondOp, RdxUnordered{}); EXPECT_FALSE(Recipe.mayHaveSideEffects()); EXPECT_FALSE(Recipe.mayReadFromMemory()); EXPECT_FALSE(Recipe.mayWriteToMemory()); EXPECT_FALSE(Recipe.mayReadOrWriteMemory()); - delete Add; } { - auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32), - PoisonValue::get(Int32)); VPValue *ChainOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VecOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPValue *CondOp = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 3)); - VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), Add, ChainOp, - CondOp, VecOp, false); + VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), ChainOp, VecOp, + CondOp, RdxUnordered{}); VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 4)); VPReductionEVLRecipe EVLRecipe(Recipe, *EVL, CondOp); EXPECT_FALSE(EVLRecipe.mayHaveSideEffects()); EXPECT_FALSE(EVLRecipe.mayReadFromMemory()); EXPECT_FALSE(EVLRecipe.mayWriteToMemory()); EXPECT_FALSE(EVLRecipe.mayReadOrWriteMemory()); - delete Add; } { @@ -1417,7 +1406,7 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { Args.push_back(Op1); Args.push_back(Op2); Args.push_back(CalledFn); - VPWidenCallRecipe Recipe(Call, TheFn, Args); + VPWidenCallRecipe Recipe(Call, TheFn, Args, VPIRFlags(), VPIRMetadata()); EXPECT_FALSE(Recipe.mayHaveSideEffects()); EXPECT_FALSE(Recipe.mayReadFromMemory()); EXPECT_FALSE(Recipe.mayWriteToMemory()); @@ -1473,8 +1462,7 @@ TEST_F(VPRecipeTest, dumpRecipeInPlan) { VPValue *ExtVPV2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); Args.push_back(ExtVPV1); Args.push_back(ExtVPV2); - VPWidenRecipe *WidenR = - new VPWidenRecipe(*AI, make_range(Args.begin(), Args.end())); + VPWidenRecipe *WidenR = new VPWidenRecipe(*AI, Args); VPBB1->appendRecipe(WidenR); { @@ -1695,30 +1683,27 @@ TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) { TEST_F(VPRecipeTest, CastVPReductionRecipeToVPUser) { IntegerType *Int32 = IntegerType::get(C, 32); - auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32), - PoisonValue::get(Int32)); VPValue *ChainOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VecOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPValue *CondOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3)); - VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), Add, ChainOp, - CondOp, VecOp, false); + VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), ChainOp, VecOp, + CondOp, RdxUnordered{}); checkVPRecipeCastImpl<VPReductionRecipe, VPUser>(&Recipe); - delete Add; + EXPECT_TRUE(isa<VPUser>(&Recipe)); + VPRecipeBase *BaseR = &Recipe; + EXPECT_TRUE(isa<VPUser>(BaseR)); } TEST_F(VPRecipeTest, CastVPReductionEVLRecipeToVPUser) { IntegerType *Int32 = IntegerType::get(C, 32); - auto *Add = BinaryOperator::CreateAdd(PoisonValue::get(Int32), - PoisonValue::get(Int32)); VPValue *ChainOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *VecOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPValue *CondOp = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 3)); - VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), Add, ChainOp, - CondOp, VecOp, false); + VPReductionRecipe Recipe(RecurKind::Add, FastMathFlags(), ChainOp, VecOp, + CondOp, RdxUnordered{}); VPValue *EVL = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 0)); VPReductionEVLRecipe EVLRecipe(Recipe, *EVL, CondOp); checkVPRecipeCastImpl<VPReductionEVLRecipe, VPUser>(&EVLRecipe); - delete Add; } } // namespace @@ -1732,8 +1717,8 @@ struct VPDoubleValueDef : public VPRecipeBase { void execute(struct VPTransformState &State) override {} #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - void print(raw_ostream &O, const Twine &Indent, - VPSlotTracker &SlotTracker) const override {} + void printRecipe(raw_ostream &O, const Twine &Indent, + VPSlotTracker &SlotTracker) const override {} #endif }; @@ -1744,15 +1729,15 @@ TEST(VPDoubleValueDefTest, traverseUseLists) { // directions. // Create a new VPDef which defines 2 values and has 2 operands. - VPInstruction Op0(20, {}); - VPInstruction Op1(30, {}); + VPInstruction Op0(VPInstruction::StepVector, {}); + VPInstruction Op1(VPInstruction::VScale, {}); VPDoubleValueDef DoubleValueDef({&Op0, &Op1}); // Create a new users of the defined values. - VPInstruction I1( - 1, {DoubleValueDef.getVPValue(0), DoubleValueDef.getVPValue(1)}); - VPInstruction I2(2, {DoubleValueDef.getVPValue(0)}); - VPInstruction I3(3, {DoubleValueDef.getVPValue(1)}); + VPInstruction I1(Instruction::Add, {DoubleValueDef.getVPValue(0), + DoubleValueDef.getVPValue(1)}); + VPInstruction I2(Instruction::Freeze, {DoubleValueDef.getVPValue(0)}); + VPInstruction I3(Instruction::Freeze, {DoubleValueDef.getVPValue(1)}); // Check operands of the VPDef (traversing upwards). SmallVector<VPValue *, 4> DoubleOperands(DoubleValueDef.op_begin(), diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h index ed6e13b..3a585e9 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h +++ b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h @@ -86,16 +86,25 @@ protected: class VPlanTestBase : public testing::Test { protected: LLVMContext C; - std::unique_ptr<BasicBlock> ScalarHeader; + std::unique_ptr<Module> M; + Function *F; + BasicBlock *ScalarHeader; SmallVector<std::unique_ptr<VPlan>> Plans; - VPlanTestBase() : ScalarHeader(BasicBlock::Create(C, "scalar.header")) { - BranchInst::Create(&*ScalarHeader, &*ScalarHeader); + VPlanTestBase() { + M = std::make_unique<Module>("VPlanTestModule", C); + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), false); + F = Function::Create(FTy, GlobalValue::ExternalLinkage, "f", M.get()); + ScalarHeader = BasicBlock::Create(C, "scalar.header", F); + BranchInst::Create(ScalarHeader, ScalarHeader); } - VPlan &getPlan(VPValue *TC = nullptr) { - Plans.push_back(std::make_unique<VPlan>(&*ScalarHeader, TC)); - return *Plans.back(); + VPlan &getPlan() { + Plans.push_back(std::make_unique<VPlan>(ScalarHeader)); + VPlan &Plan = *Plans.back(); + VPValue *DefaultTC = Plan.getConstantInt(32, 1024); + Plan.setTripCount(DefaultTC); + return Plan; } }; diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp index 169114e..97783a6 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp @@ -22,8 +22,8 @@ namespace { TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) { VPlan &Plan = getPlan(); VPValue *Zero = Plan.getConstantInt(32, 0); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); - VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI}); + VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero}); + VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPBasicBlock *VPBB1 = Plan.getEntry(); @@ -43,9 +43,9 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) { #if GTEST_HAS_STREAM_REDIRECTION #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) EXPECT_STREQ("Use before def!\n" - " EMIT vp<%1> = sub vp<%2>\n" + " EMIT vp<%1> = sub vp<%2>, ir<0>\n" " before\n" - " EMIT vp<%2> = add ir<0>\n", + " EMIT vp<%2> = add ir<0>, ir<0>\n", ::testing::internal::GetCapturedStderr().c_str()); #else EXPECT_STREQ("Use before def!\n", @@ -57,8 +57,8 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) { TEST_F(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) { VPlan &Plan = getPlan(); VPValue *Zero = Plan.getConstantInt(32, 0); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); - VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI}); + VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero}); + VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -82,9 +82,9 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) { #if GTEST_HAS_STREAM_REDIRECTION #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) EXPECT_STREQ("Use before def!\n" - " EMIT vp<%1> = sub vp<%3>\n" + " EMIT vp<%1> = sub vp<%3>, ir<0>\n" " before\n" - " EMIT vp<%3> = add ir<0>\n", + " EMIT vp<%3> = add ir<0>, ir<0>\n", ::testing::internal::GetCapturedStderr().c_str()); #else EXPECT_STREQ("Use before def!\n", @@ -99,7 +99,7 @@ TEST_F(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) { auto *Phi = PHINode::Create(Int32, 1); VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 0)); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); + VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -132,7 +132,7 @@ TEST_F(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) { EXPECT_STREQ("Use before def!\n" " BLEND ir<<badref>> = vp<%2>\n" " before\n" - " EMIT vp<%2> = add ir<0>\n", + " EMIT vp<%2> = add ir<0>, ir<0>\n", ::testing::internal::GetCapturedStderr().c_str()); #else EXPECT_STREQ("Use before def!\n", @@ -153,7 +153,7 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) { VPBasicBlock *VPBB3 = Plan.createVPBasicBlock(""); VPBasicBlock *VPBB4 = Plan.createVPBasicBlock(""); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); + VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero}); VPPhi *Phi = new VPPhi({DefI}, {}); VPBB2->appendRecipe(Phi); VPBB2->appendRecipe(DefI); @@ -171,7 +171,7 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) { #if GTEST_HAS_STREAM_REDIRECTION #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) EXPECT_STREQ("Incoming def does not dominate incoming block!\n" - " EMIT vp<%2> = add ir<0>\n" + " EMIT vp<%2> = add ir<0>, ir<0>\n" " does not dominate preheader for\n" " EMIT-SCALAR vp<%1> = phi [ vp<%2>, preheader ]", ::testing::internal::GetCapturedStderr().c_str()); @@ -185,7 +185,7 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) { TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) { VPlan &Plan = getPlan(); VPValue *Zero = Plan.getConstantInt(32, 0); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -219,7 +219,7 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) { TEST_F(VPVerifierTest, DuplicateSuccessorsInsideRegion) { VPlan &Plan = getPlan(); VPValue *Zero = Plan.getConstantInt(32, 0); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -263,7 +263,7 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) { auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPBB2->appendRecipe(CanIV); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); + VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero, Zero}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {DefI}); @@ -346,6 +346,8 @@ TEST_F(VPIRVerifierTest, testVerifyIRPhiInScalarHeaderVPIRBB) { Function *F = M.getFunction("f"); BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor(); auto Plan = buildVPlan(LoopHeader); + VPValue *Zero = Plan->getConstantInt(32, 0); + Plan->getScalarHeader()->front().addOperand(Zero); #if GTEST_HAS_STREAM_REDIRECTION ::testing::internal::CaptureStderr(); @@ -383,12 +385,10 @@ TEST_F(VPIRVerifierTest, testVerifyIRPhiInExitVPIRBB) { auto *HeaderBlock = cast<VPBasicBlock>(Plan->getVectorLoopRegion()->getEntry()); VPInstruction *DefI = - new VPInstruction(VPInstruction::ExtractLastElement, + new VPInstruction(VPInstruction::ExtractLastLane, {HeaderBlock->front().getVPSingleValue()}); DefI->insertBefore(Plan->getMiddleBlock()->getTerminator()); Plan->getExitBlocks()[0]->front().addOperand(DefI); - VPValue *Zero = Plan->getConstantInt(32, 0); - Plan->getScalarHeader()->front().addOperand(Zero); #if GTEST_HAS_STREAM_REDIRECTION ::testing::internal::CaptureStderr(); diff --git a/llvm/unittests/tools/llvm-exegesis/Mips/RegisterAliasingTest.cpp b/llvm/unittests/tools/llvm-exegesis/Mips/RegisterAliasingTest.cpp index 9cce106..62a7ee5 100644 --- a/llvm/unittests/tools/llvm-exegesis/Mips/RegisterAliasingTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/Mips/RegisterAliasingTest.cpp @@ -9,7 +9,6 @@ #include "RegisterAliasing.h" #include <cassert> -#include <memory> #include "MipsInstrInfo.h" #include "TestBase.h" diff --git a/llvm/unittests/tools/llvm-exegesis/Mips/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/Mips/TargetTest.cpp index 1f458c0..d18ece9 100644 --- a/llvm/unittests/tools/llvm-exegesis/Mips/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/Mips/TargetTest.cpp @@ -9,7 +9,6 @@ #include "Target.h" #include <cassert> -#include <memory> #include "MCTargetDesc/MipsMCTargetDesc.h" #include "TestBase.h" diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp index 13a1e5a..b45adc6 100644 --- a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp @@ -9,7 +9,6 @@ #include "Target.h" #include <cassert> -#include <memory> #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "TestBase.h" diff --git a/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp index e24c8b8..418c97f 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp @@ -10,7 +10,6 @@ #include "RegisterAliasing.h" #include <cassert> -#include <memory> #include "TestBase.h" #include "X86InstrInfo.h" diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp index 97b9a19..20a55d8 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp @@ -9,7 +9,6 @@ #include "SchedClassResolution.h" #include <cassert> -#include <memory> #include "TestBase.h" #include "llvm/MC/TargetRegistry.h" diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp index 5953f4e..3e0b1f4 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp @@ -16,8 +16,6 @@ #include "X86InstrInfo.h" #include "llvm/ADT/SetOperations.h" -#include <unordered_set> - namespace llvm { namespace exegesis { namespace { diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 5a21a69..e375856 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -9,7 +9,6 @@ #include "Target.h" #include <cassert> -#include <memory> #include "MCTargetDesc/X86MCTargetDesc.h" #include "MmapUtils.h" |
