diff options
Diffstat (limited to 'llvm/unittests')
185 files changed, 8824 insertions, 1465 deletions
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index fbe96bb..99cc38b 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -10118,7 +10118,7 @@ TEST(APFloatTest, Float4E2M1FNToFloat) { } TEST(APFloatTest, AddOrSubtractSignificand) { - typedef detail::IEEEFloatUnitTestHelper Helper; + using Helper = detail::IEEEFloatUnitTestHelper; // Test cases are all combinations of: // {equal exponents, LHS larger exponent, RHS larger exponent} // {equal significands, LHS larger significand, RHS larger significand} 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 12ba004..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; @@ -21,7 +22,7 @@ template <typename T> class BitVectorTest : public ::testing::Test { }; // Test both BitVector and SmallBitVector with the same suite of tests. -typedef ::testing::Types<BitVector, SmallBitVector> BitVectorTestTypes; +using BitVectorTestTypes = ::testing::Types<BitVector, SmallBitVector>; TYPED_TEST_SUITE(BitVectorTest, BitVectorTestTypes, ); TYPED_TEST(BitVectorTest, TrivialOperation) { @@ -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,9 +864,90 @@ 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 } -typedef std::vector<std::pair<int, int>> RangeList; +using RangeList = std::vector<std::pair<int, int>>; template <typename VecType> static inline VecType createBitVector(uint32_t Size, diff --git a/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp b/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp index 0cd7fd3..571e4d2 100644 --- a/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp +++ b/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp @@ -21,7 +21,7 @@ using namespace llvm; namespace llvm { TEST(BreadthFristIteratorTest, Basic) { - typedef bf_iterator<Graph<4>> BFIter; + using BFIter = bf_iterator<Graph<4>>; Graph<4> G; G.AddEdge(0, 1); @@ -46,7 +46,7 @@ TEST(BreadthFristIteratorTest, Basic) { } TEST(BreadthFristIteratorTest, Cycle) { - typedef bf_iterator<Graph<4>> BFIter; + using BFIter = bf_iterator<Graph<4>>; Graph<4> G; G.AddEdge(0, 1); @@ -78,7 +78,7 @@ TEST(BreadthFristIteratorTest, Cycle) { static_assert( std::is_convertible_v<decltype(*std::declval<bf_iterator<Graph<3>>>()), - typename bf_iterator<Graph<3>>::reference>); + bf_iterator<Graph<3>>::reference>); // bf_iterator should be (at-least) a forward-iterator static_assert(std::is_base_of_v<std::forward_iterator_tag, diff --git a/llvm/unittests/ADT/CombinationGeneratorTest.cpp b/llvm/unittests/ADT/CombinationGeneratorTest.cpp index f3e174a..cf187e6 100644 --- a/llvm/unittests/ADT/CombinationGeneratorTest.cpp +++ b/llvm/unittests/ADT/CombinationGeneratorTest.cpp @@ -12,9 +12,7 @@ #include "llvm/Support/ErrorHandling.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include <algorithm> #include <cstddef> -#include <iterator> #include <vector> using namespace llvm; diff --git a/llvm/unittests/ADT/ConcurrentHashtableTest.cpp b/llvm/unittests/ADT/ConcurrentHashtableTest.cpp index ee1ee41..05c4809 100644 --- a/llvm/unittests/ADT/ConcurrentHashtableTest.cpp +++ b/llvm/unittests/ADT/ConcurrentHashtableTest.cpp @@ -14,14 +14,13 @@ #include "gtest/gtest.h" #include <limits> #include <random> -#include <vector> using namespace llvm; using namespace parallel; namespace { class String { public: - String() {} + String() = default; const std::string &getKey() const { return Data; } template <typename AllocatorTy> diff --git a/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp b/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp index f5439478..9f51490 100644 --- a/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp +++ b/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp @@ -9,13 +9,12 @@ #include "llvm/ADT/DAGDeltaAlgorithm.h" #include "llvm/ADT/STLExtras.h" #include "gtest/gtest.h" -#include <algorithm> #include <cstdarg> using namespace llvm; namespace { -typedef DAGDeltaAlgorithm::edge_ty edge_ty; +using edge_ty = DAGDeltaAlgorithm::edge_ty; class FixedDAGDeltaAlgorithm : public DAGDeltaAlgorithm { changeset_ty FailingSet; diff --git a/llvm/unittests/ADT/DeltaAlgorithmTest.cpp b/llvm/unittests/ADT/DeltaAlgorithmTest.cpp index 24e18f4..530bd1c 100644 --- a/llvm/unittests/ADT/DeltaAlgorithmTest.cpp +++ b/llvm/unittests/ADT/DeltaAlgorithmTest.cpp @@ -9,7 +9,6 @@ #include "llvm/ADT/DeltaAlgorithm.h" #include "llvm/ADT/STLExtras.h" #include "gtest/gtest.h" -#include <algorithm> #include <cstdarg> using namespace llvm; diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp index aceb4f3..553d159 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp @@ -129,18 +129,17 @@ typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr; // Register these types for testing. // clang-format off -typedef ::testing::Types<DenseMap<uint32_t, uint32_t>, - DenseMap<uint32_t *, uint32_t *>, - DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>, - DenseMap<EnumClass, uint32_t>, - DenseMap<std::optional<uint32_t>, uint32_t>, - SmallDenseMap<uint32_t, uint32_t>, - SmallDenseMap<uint32_t *, uint32_t *>, - SmallDenseMap<CtorTester, CtorTester, 4, - CtorTesterMapInfo>, - SmallDenseMap<EnumClass, uint32_t>, - SmallDenseMap<std::optional<uint32_t>, uint32_t> - > DenseMapTestTypes; +using DenseMapTestTypes = ::testing::Types< + DenseMap<uint32_t, uint32_t>, + DenseMap<uint32_t *, uint32_t *>, + DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>, + DenseMap<EnumClass, uint32_t>, + DenseMap<std::optional<uint32_t>, uint32_t>, + SmallDenseMap<uint32_t, uint32_t>, + SmallDenseMap<uint32_t *, uint32_t *>, + SmallDenseMap<CtorTester, CtorTester, 4, CtorTesterMapInfo>, + SmallDenseMap<EnumClass, uint32_t>, + SmallDenseMap<std::optional<uint32_t>, uint32_t>>; // clang-format on TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, ); @@ -201,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/DenseSetTest.cpp b/llvm/unittests/ADT/DenseSetTest.cpp index a24f99b..a2a062b 100644 --- a/llvm/unittests/ADT/DenseSetTest.cpp +++ b/llvm/unittests/ADT/DenseSetTest.cpp @@ -96,13 +96,13 @@ private: }; // Register these types for testing. -typedef ::testing::Types<DenseSet<unsigned, TestDenseSetInfo>, - const DenseSet<unsigned, TestDenseSetInfo>, - SmallDenseSet<unsigned, 1, TestDenseSetInfo>, - SmallDenseSet<unsigned, 4, TestDenseSetInfo>, - const SmallDenseSet<unsigned, 4, TestDenseSetInfo>, - SmallDenseSet<unsigned, 64, TestDenseSetInfo>> - DenseSetTestTypes; +using DenseSetTestTypes = + ::testing::Types<DenseSet<unsigned, TestDenseSetInfo>, + const DenseSet<unsigned, TestDenseSetInfo>, + SmallDenseSet<unsigned, 1, TestDenseSetInfo>, + SmallDenseSet<unsigned, 4, TestDenseSetInfo>, + const SmallDenseSet<unsigned, 4, TestDenseSetInfo>, + SmallDenseSet<unsigned, 64, TestDenseSetInfo>>; TYPED_TEST_SUITE(DenseSetTest, DenseSetTestTypes, ); TYPED_TEST(DenseSetTest, Constructor) { diff --git a/llvm/unittests/ADT/DepthFirstIteratorTest.cpp b/llvm/unittests/ADT/DepthFirstIteratorTest.cpp index 95923b8..00312ca 100644 --- a/llvm/unittests/ADT/DepthFirstIteratorTest.cpp +++ b/llvm/unittests/ADT/DepthFirstIteratorTest.cpp @@ -21,7 +21,7 @@ using namespace llvm; namespace llvm { template <typename T> struct CountedSet { - typedef typename SmallPtrSet<T, 4>::iterator iterator; + using iterator = typename SmallPtrSet<T, 4>::iterator; SmallPtrSet<T, 4> S; int InsertVisited = 0; @@ -44,8 +44,8 @@ public: }; TEST(DepthFirstIteratorTest, ActuallyUpdateIterator) { - typedef CountedSet<Graph<3>::NodeType *> StorageT; - typedef df_iterator<Graph<3>, StorageT, true> DFIter; + using StorageT = CountedSet<Graph<3>::NodeType *>; + using DFIter = df_iterator<Graph<3>, StorageT, true>; Graph<3> G; G.AddEdge(0, 1); @@ -59,7 +59,7 @@ TEST(DepthFirstIteratorTest, ActuallyUpdateIterator) { static_assert( std::is_convertible_v<decltype(*std::declval<df_iterator<Graph<3>>>()), - typename df_iterator<Graph<3>>::reference>); + df_iterator<Graph<3>>::reference>); // df_iterator should be (at-least) a forward-iterator static_assert(std::is_base_of_v<std::forward_iterator_tag, diff --git a/llvm/unittests/ADT/DirectedGraphTest.cpp b/llvm/unittests/ADT/DirectedGraphTest.cpp index 49ccf06..82a631b 100644 --- a/llvm/unittests/ADT/DirectedGraphTest.cpp +++ b/llvm/unittests/ADT/DirectedGraphTest.cpp @@ -43,7 +43,7 @@ public: class DGTestGraph : public DGTestBase { public: DGTestGraph() = default; - ~DGTestGraph(){}; + ~DGTestGraph() = default; }; using EdgeListTy = SmallVector<DGTestEdge *, 2>; diff --git a/llvm/unittests/ADT/FallibleIteratorTest.cpp b/llvm/unittests/ADT/FallibleIteratorTest.cpp index d338974..c17aa03 100644 --- a/llvm/unittests/ADT/FallibleIteratorTest.cpp +++ b/llvm/unittests/ADT/FallibleIteratorTest.cpp @@ -19,8 +19,8 @@ using namespace llvm; namespace { -using ItemValid = enum { ValidItem, InvalidItem }; -using LinkValid = enum { ValidLink, InvalidLink }; +enum ItemValid { ValidItem, InvalidItem }; +enum LinkValid { ValidLink, InvalidLink }; class Item { public: 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/IListBaseTest.cpp b/llvm/unittests/ADT/IListBaseTest.cpp index bd91568..eeed488 100644 --- a/llvm/unittests/ADT/IListBaseTest.cpp +++ b/llvm/unittests/ADT/IListBaseTest.cpp @@ -19,13 +19,14 @@ template <typename T> class IListBaseTest : public ::testing::Test {}; class Parent; // Test variants with the same test. -typedef ::testing::Types<ilist_base<false, void>, ilist_base<true, void>, ilist_base<false, Parent*>, ilist_base<true, Parent*>> - IListBaseTestTypes; +using IListBaseTestTypes = + ::testing::Types<ilist_base<false, void>, ilist_base<true, void>, + ilist_base<false, Parent *>, ilist_base<true, Parent *>>; TYPED_TEST_SUITE(IListBaseTest, IListBaseTestTypes, ); TYPED_TEST(IListBaseTest, insertBeforeImpl) { - typedef TypeParam list_base_type; - typedef typename list_base_type::node_base_type node_base_type; + using list_base_type = TypeParam; + using node_base_type = typename list_base_type::node_base_type; node_base_type S, A, B; @@ -51,8 +52,8 @@ TYPED_TEST(IListBaseTest, insertBeforeImpl) { } TYPED_TEST(IListBaseTest, removeImpl) { - typedef TypeParam list_base_type; - typedef typename list_base_type::node_base_type node_base_type; + using list_base_type = TypeParam; + using node_base_type = typename list_base_type::node_base_type; node_base_type S, A, B; @@ -80,8 +81,8 @@ TYPED_TEST(IListBaseTest, removeImpl) { } TYPED_TEST(IListBaseTest, removeRangeImpl) { - typedef TypeParam list_base_type; - typedef typename list_base_type::node_base_type node_base_type; + using list_base_type = TypeParam; + using node_base_type = typename list_base_type::node_base_type; node_base_type S, A, B, C, D; @@ -106,8 +107,8 @@ TYPED_TEST(IListBaseTest, removeRangeImpl) { } TYPED_TEST(IListBaseTest, removeRangeImplAllButSentinel) { - typedef TypeParam list_base_type; - typedef typename list_base_type::node_base_type node_base_type; + using list_base_type = TypeParam; + using node_base_type = typename list_base_type::node_base_type; node_base_type S, A, B; @@ -126,8 +127,8 @@ TYPED_TEST(IListBaseTest, removeRangeImplAllButSentinel) { } TYPED_TEST(IListBaseTest, transferBeforeImpl) { - typedef TypeParam list_base_type; - typedef typename list_base_type::node_base_type node_base_type; + using list_base_type = TypeParam; + using node_base_type = typename list_base_type::node_base_type; node_base_type S1, S2, A, B, C, D, E; diff --git a/llvm/unittests/ADT/IListIteratorBitsTest.cpp b/llvm/unittests/ADT/IListIteratorBitsTest.cpp index 97c14265..b430bcb 100644 --- a/llvm/unittests/ADT/IListIteratorBitsTest.cpp +++ b/llvm/unittests/ADT/IListIteratorBitsTest.cpp @@ -93,8 +93,8 @@ TEST(IListIteratorBitsTest, ConsAndAssignment) { class dummy { // Test that we get an ilist_iterator_w_bits out of the node given that the // options are enabled. - using node_options = typename ilist_detail::compute_node_options< - Node, ilist_iterator_bits<true>>::type; + using node_options = + ilist_detail::compute_node_options<Node, ilist_iterator_bits<true>>::type; static_assert(std::is_same<Node::self_iterator, llvm::ilist_iterator_w_bits<node_options, false, false>>::value); @@ -102,7 +102,7 @@ class dummy { // Now test that a plain node, without the option, gets a plain // ilist_iterator. using plain_node_options = - typename ilist_detail::compute_node_options<PlainNode>::type; + ilist_detail::compute_node_options<PlainNode>::type; static_assert(std::is_same< PlainNode::self_iterator, llvm::ilist_iterator<plain_node_options, false, false>>::value); diff --git a/llvm/unittests/ADT/IListIteratorTest.cpp b/llvm/unittests/ADT/IListIteratorTest.cpp index 4e5b847b..54a42582 100644 --- a/llvm/unittests/ADT/IListIteratorTest.cpp +++ b/llvm/unittests/ADT/IListIteratorTest.cpp @@ -141,10 +141,10 @@ TEST(IListIteratorTest, ReverseConstructor) { L.insert(L.end(), B); // Save typing. - typedef simple_ilist<Node>::iterator iterator; - typedef simple_ilist<Node>::reverse_iterator reverse_iterator; - typedef simple_ilist<Node>::const_iterator const_iterator; - typedef simple_ilist<Node>::const_reverse_iterator const_reverse_iterator; + using iterator = simple_ilist<Node>::iterator; + using reverse_iterator = simple_ilist<Node>::reverse_iterator; + using const_iterator = simple_ilist<Node>::const_iterator; + using const_reverse_iterator = simple_ilist<Node>::const_reverse_iterator; // Check conversion values. EXPECT_EQ(L.begin(), iterator(L.rend())); diff --git a/llvm/unittests/ADT/IListNodeBaseTest.cpp b/llvm/unittests/ADT/IListNodeBaseTest.cpp index ef90c71..393f83a 100644 --- a/llvm/unittests/ADT/IListNodeBaseTest.cpp +++ b/llvm/unittests/ADT/IListNodeBaseTest.cpp @@ -17,10 +17,10 @@ namespace { class Parent {}; -typedef ilist_node_base<false, void> RawNode; -typedef ilist_node_base<true, void> TrackingNode; -typedef ilist_node_base<false, Parent> ParentNode; -typedef ilist_node_base<true, Parent> ParentTrackingNode; +using RawNode = ilist_node_base<false, void>; +using TrackingNode = ilist_node_base<true, void>; +using ParentNode = ilist_node_base<false, Parent>; +using ParentTrackingNode = ilist_node_base<true, Parent>; TEST(IListNodeBaseTest, DefaultConstructor) { RawNode A; diff --git a/llvm/unittests/ADT/IListSentinelTest.cpp b/llvm/unittests/ADT/IListSentinelTest.cpp index 1f4a831..709a1a4 100644 --- a/llvm/unittests/ADT/IListSentinelTest.cpp +++ b/llvm/unittests/ADT/IListSentinelTest.cpp @@ -14,18 +14,17 @@ using namespace llvm; namespace { template <class T, class... Options> struct PickSentinel { - typedef ilist_sentinel< - typename ilist_detail::compute_node_options<T, Options...>::type> - type; + using type = ilist_sentinel< + typename ilist_detail::compute_node_options<T, Options...>::type>; }; class Node : public ilist_node<Node> {}; class TrackingNode : public ilist_node<Node, ilist_sentinel_tracking<true>> {}; -typedef PickSentinel<Node>::type Sentinel; -typedef PickSentinel<Node, ilist_sentinel_tracking<true>>::type - TrackingSentinel; -typedef PickSentinel<Node, ilist_sentinel_tracking<false>>::type - NoTrackingSentinel; +using Sentinel = PickSentinel<Node>::type; +using TrackingSentinel = + PickSentinel<Node, ilist_sentinel_tracking<true>>::type; +using NoTrackingSentinel = + PickSentinel<Node, ilist_sentinel_tracking<false>>::type; struct LocalAccess : ilist_detail::NodeAccess { using NodeAccess::getPrev; diff --git a/llvm/unittests/ADT/IListTest.cpp b/llvm/unittests/ADT/IListTest.cpp index 2fdc8e1..984014f 100644 --- a/llvm/unittests/ADT/IListTest.cpp +++ b/llvm/unittests/ADT/IListTest.cpp @@ -19,7 +19,7 @@ namespace { struct Node : ilist_node<Node> { int Value; - Node() {} + Node() = default; Node(int Value) : Value(Value) {} Node(const Node&) = default; ~Node() { Value = -1; } diff --git a/llvm/unittests/ADT/IntervalMapTest.cpp b/llvm/unittests/ADT/IntervalMapTest.cpp index 99a93ab..06848e2 100644 --- a/llvm/unittests/ADT/IntervalMapTest.cpp +++ b/llvm/unittests/ADT/IntervalMapTest.cpp @@ -8,15 +8,14 @@ #include "llvm/ADT/IntervalMap.h" #include "gtest/gtest.h" -#include <type_traits> using namespace llvm; namespace { -typedef IntervalMap<unsigned, unsigned, 4> UUMap; -typedef IntervalMap<unsigned, unsigned, 4, - IntervalMapHalfOpenInfo<unsigned>> UUHalfOpenMap; +using UUMap = IntervalMap<unsigned, unsigned, 4>; +using UUHalfOpenMap = + IntervalMap<unsigned, unsigned, 4, IntervalMapHalfOpenInfo<unsigned>>; // Empty map tests TEST(IntervalMapTest, EmptyMap) { @@ -713,7 +712,7 @@ TEST(IntervalMapTest, OverlapsHalfOpen) { } TEST(IntervalMapOverlapsTest, SmallMaps) { - typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps; + using UUOverlaps = IntervalMapOverlaps<UUMap, UUMap>; UUMap::Allocator allocator; UUMap mapA(allocator); UUMap mapB(allocator); @@ -757,7 +756,7 @@ TEST(IntervalMapOverlapsTest, SmallMaps) { } TEST(IntervalMapOverlapsTest, BigMaps) { - typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps; + using UUOverlaps = IntervalMapOverlaps<UUMap, UUMap>; UUMap::Allocator allocator; UUMap mapA(allocator); UUMap mapB(allocator); diff --git a/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp b/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp index f4f2083..6da4227 100644 --- a/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp +++ b/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp @@ -25,9 +25,9 @@ struct SimpleRefCounted : Base<SimpleRefCounted<Base>> { template <typename T> struct IntrusiveRefCntPtrTest : testing::Test {}; -typedef ::testing::Types<SimpleRefCounted<RefCountedBase>, - SimpleRefCounted<ThreadSafeRefCountedBase>> - IntrusiveRefCntTypes; +using IntrusiveRefCntTypes = + ::testing::Types<SimpleRefCounted<RefCountedBase>, + SimpleRefCounted<ThreadSafeRefCountedBase>>; TYPED_TEST_SUITE(IntrusiveRefCntPtrTest, IntrusiveRefCntTypes, ); TYPED_TEST(IntrusiveRefCntPtrTest, RefCountedBaseCopyDoesNotLeak) { diff --git a/llvm/unittests/ADT/IteratorTest.cpp b/llvm/unittests/ADT/IteratorTest.cpp index 691fbce..9dd8c1a 100644 --- a/llvm/unittests/ADT/IteratorTest.cpp +++ b/llvm/unittests/ADT/IteratorTest.cpp @@ -48,11 +48,10 @@ struct AdaptedIter : iterator_adaptor_base<AdaptedIter, WeirdIter> {}; // Test that iterator_adaptor_base forwards typedefs, if value_type is // unchanged. -static_assert(std::is_same_v<typename AdaptedIter::value_type, Shadow<0>>, ""); -static_assert(std::is_same_v<typename AdaptedIter::difference_type, Shadow<1>>, - ""); -static_assert(std::is_same_v<typename AdaptedIter::pointer, Shadow<2>>, ""); -static_assert(std::is_same_v<typename AdaptedIter::reference, Shadow<3>>, ""); +static_assert(std::is_same_v<AdaptedIter::value_type, Shadow<0>>, ""); +static_assert(std::is_same_v<AdaptedIter::difference_type, Shadow<1>>, ""); +static_assert(std::is_same_v<AdaptedIter::pointer, Shadow<2>>, ""); +static_assert(std::is_same_v<AdaptedIter::reference, Shadow<3>>, ""); // Ensure that pointe{e,r}_iterator adaptors correctly forward the category of // the underlying iterator. @@ -178,8 +177,8 @@ TEST(PointeeIteratorTest, Basic) { V.push_back(&arr[2]); V.push_back(&arr[3]); - typedef pointee_iterator<SmallVectorImpl<int *>::const_iterator> - test_iterator; + using test_iterator = + pointee_iterator<SmallVectorImpl<int *>::const_iterator>; test_iterator Begin, End; Begin = V.begin(); @@ -219,9 +218,8 @@ TEST(PointeeIteratorTest, SmartPointer) { V.push_back(std::make_unique<int>(3)); V.push_back(std::make_unique<int>(4)); - typedef pointee_iterator< - SmallVectorImpl<std::unique_ptr<int>>::const_iterator> - test_iterator; + using test_iterator = + pointee_iterator<SmallVectorImpl<std::unique_ptr<int>>::const_iterator>; test_iterator Begin, End; Begin = V.begin(); 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/PointerSumTypeTest.cpp b/llvm/unittests/ADT/PointerSumTypeTest.cpp index fbf59f3..11e657a 100644 --- a/llvm/unittests/ADT/PointerSumTypeTest.cpp +++ b/llvm/unittests/ADT/PointerSumTypeTest.cpp @@ -17,10 +17,9 @@ struct PointerSumTypeTest : public testing::Test { float f; int i1, i2; - typedef PointerSumType<Kinds, PointerSumTypeMember<Float, float *>, - PointerSumTypeMember<Int1, int *>, - PointerSumTypeMember<Int2, int *>> - SumType; + using SumType = PointerSumType<Kinds, PointerSumTypeMember<Float, float *>, + PointerSumTypeMember<Int1, int *>, + PointerSumTypeMember<Int2, int *>>; SumType a, b, c, n; PointerSumTypeTest() diff --git a/llvm/unittests/ADT/PointerUnionTest.cpp b/llvm/unittests/ADT/PointerUnionTest.cpp index acddb78..d8ac3aed 100644 --- a/llvm/unittests/ADT/PointerUnionTest.cpp +++ b/llvm/unittests/ADT/PointerUnionTest.cpp @@ -12,9 +12,9 @@ using namespace llvm; namespace { -typedef PointerUnion<int *, float *> PU; -typedef PointerUnion<int *, float *, long long *> PU3; -typedef PointerUnion<int *, float *, long long *, double *> PU4; +using PU = PointerUnion<int *, float *>; +using PU3 = PointerUnion<int *, float *, long long *>; +using PU4 = PointerUnion<int *, float *, long long *, double *>; struct PointerUnionTest : public testing::Test { float f; @@ -116,9 +116,9 @@ TEST_F(PointerUnionTest, Get) { template<int I> struct alignas(8) Aligned {}; -typedef PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *, - Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *> - PU8; +using PU8 = + PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *, + Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *>; TEST_F(PointerUnionTest, ManyElements) { Aligned<0> a0; diff --git a/llvm/unittests/ADT/PostOrderIteratorTest.cpp b/llvm/unittests/ADT/PostOrderIteratorTest.cpp index 4c2a66e..e875dd6 100644 --- a/llvm/unittests/ADT/PostOrderIteratorTest.cpp +++ b/llvm/unittests/ADT/PostOrderIteratorTest.cpp @@ -23,7 +23,7 @@ namespace { // Whether we're able to compile TEST(PostOrderIteratorTest, Compiles) { - typedef SmallPtrSet<void *, 4> ExtSetTy; + using ExtSetTy = SmallPtrSet<void *, 4>; // Tests that template specializations are kept up to date void *Null = nullptr; @@ -44,7 +44,7 @@ TEST(PostOrderIteratorTest, Compiles) { static_assert( std::is_convertible_v<decltype(*std::declval<po_iterator<Graph<3>>>()), - typename po_iterator<Graph<3>>::reference>); + po_iterator<Graph<3>>::reference>); // Test post-order and reverse post-order traversals for simple graph type. TEST(PostOrderIteratorTest, PostOrderAndReversePostOrderTraverrsal) { diff --git a/llvm/unittests/ADT/PriorityWorklistTest.cpp b/llvm/unittests/ADT/PriorityWorklistTest.cpp index f12d32a..08a4773 100644 --- a/llvm/unittests/ADT/PriorityWorklistTest.cpp +++ b/llvm/unittests/ADT/PriorityWorklistTest.cpp @@ -20,8 +20,8 @@ namespace { using namespace llvm; template <typename T> class PriorityWorklistTest : public ::testing::Test {}; -typedef ::testing::Types<PriorityWorklist<int>, SmallPriorityWorklist<int, 2>> - TestTypes; +using TestTypes = + ::testing::Types<PriorityWorklist<int>, SmallPriorityWorklist<int, 2>>; TYPED_TEST_SUITE(PriorityWorklistTest, TestTypes, ); TYPED_TEST(PriorityWorklistTest, Basic) { diff --git a/llvm/unittests/ADT/RangeAdapterTest.cpp b/llvm/unittests/ADT/RangeAdapterTest.cpp index c1a8a98..6849ccbc 100644 --- a/llvm/unittests/ADT/RangeAdapterTest.cpp +++ b/llvm/unittests/ADT/RangeAdapterTest.cpp @@ -24,8 +24,8 @@ class ReverseOnlyVector { public: ReverseOnlyVector(std::initializer_list<int> list) : Vec(list) {} - typedef std::vector<int>::reverse_iterator reverse_iterator; - typedef std::vector<int>::const_reverse_iterator const_reverse_iterator; + using reverse_iterator = std::vector<int>::reverse_iterator; + using const_reverse_iterator = std::vector<int>::const_reverse_iterator; reverse_iterator rbegin() { return Vec.rbegin(); } reverse_iterator rend() { return Vec.rend(); } const_reverse_iterator rbegin() const { return Vec.rbegin(); } @@ -41,11 +41,11 @@ class BidirectionalVector { public: BidirectionalVector(std::initializer_list<int> list) : Vec(list) {} - typedef std::vector<int>::iterator iterator; + using iterator = std::vector<int>::iterator; iterator begin() const; iterator end() const; - typedef std::vector<int>::reverse_iterator reverse_iterator; + using reverse_iterator = std::vector<int>::reverse_iterator; reverse_iterator rbegin() const { return Vec.rbegin(); } reverse_iterator rend() const { return Vec.rend(); } }; @@ -58,15 +58,15 @@ class BidirectionalVectorConsts { public: BidirectionalVectorConsts(std::initializer_list<int> list) : Vec(list) {} - typedef std::vector<int>::iterator iterator; - typedef std::vector<int>::const_iterator const_iterator; + using iterator = std::vector<int>::iterator; + using const_iterator = std::vector<int>::const_iterator; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; - typedef std::vector<int>::reverse_iterator reverse_iterator; - typedef std::vector<int>::const_reverse_iterator const_reverse_iterator; + using reverse_iterator = std::vector<int>::reverse_iterator; + using const_reverse_iterator = std::vector<int>::const_reverse_iterator; reverse_iterator rbegin() { return Vec.rbegin(); } reverse_iterator rend() { return Vec.rend(); } const_reverse_iterator rbegin() const { return Vec.rbegin(); } @@ -80,7 +80,7 @@ class CustomIteratorVector { public: CustomIteratorVector(std::initializer_list<int> list) : V(list) {} - typedef std::vector<int>::iterator iterator; + using iterator = std::vector<int>::iterator; class reverse_iterator { std::vector<int>::iterator I; @@ -126,8 +126,8 @@ template <typename R> void TestRev(const R &r) { // Test fixture template <typename T> class RangeAdapterLValueTest : public ::testing::Test {}; -typedef ::testing::Types<std::vector<int>, std::list<int>, int[4]> - RangeAdapterLValueTestTypes; +using RangeAdapterLValueTestTypes = + ::testing::Types<std::vector<int>, std::list<int>, int[4]>; TYPED_TEST_SUITE(RangeAdapterLValueTest, RangeAdapterLValueTestTypes, ); TYPED_TEST(RangeAdapterLValueTest, TrivialOperation) { @@ -140,10 +140,10 @@ TYPED_TEST(RangeAdapterLValueTest, TrivialOperation) { template <typename T> struct RangeAdapterRValueTest : testing::Test {}; -typedef ::testing::Types<std::vector<int>, std::list<int>, CustomIteratorVector, - ReverseOnlyVector, BidirectionalVector, - BidirectionalVectorConsts> - RangeAdapterRValueTestTypes; +using RangeAdapterRValueTestTypes = + ::testing::Types<std::vector<int>, std::list<int>, CustomIteratorVector, + ReverseOnlyVector, BidirectionalVector, + BidirectionalVectorConsts>; TYPED_TEST_SUITE(RangeAdapterRValueTest, RangeAdapterRValueTestTypes, ); TYPED_TEST(RangeAdapterRValueTest, TrivialOperation) { diff --git a/llvm/unittests/ADT/SCCIteratorTest.cpp b/llvm/unittests/ADT/SCCIteratorTest.cpp index 4835095..5f08829 100644 --- a/llvm/unittests/ADT/SCCIteratorTest.cpp +++ b/llvm/unittests/ADT/SCCIteratorTest.cpp @@ -21,7 +21,7 @@ TEST(SCCIteratorTest, AllSmallGraphs) { // create graphs for which every node has a self-edge. #define NUM_NODES 4 #define NUM_GRAPHS (NUM_NODES * (NUM_NODES - 1)) - typedef Graph<NUM_NODES> GT; + using GT = Graph<NUM_NODES>; /// Enumerate all graphs using NUM_GRAPHS bits. static_assert(NUM_GRAPHS < sizeof(unsigned) * CHAR_BIT, "Too many graphs!"); diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 966b1f0..e356f6b 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -60,7 +60,7 @@ TEST(STLExtrasTest, EnumerateLValue) { // Test that a simple LValue can be enumerated and gives correct results with // multiple types, including the empty container. std::vector<char> foo = {'a', 'b', 'c'}; - typedef std::pair<std::size_t, char> CharPairType; + using CharPairType = std::pair<std::size_t, char>; std::vector<CharPairType> CharResults; for (auto [index, value] : llvm::enumerate(foo)) { @@ -72,7 +72,7 @@ TEST(STLExtrasTest, EnumerateLValue) { CharPairType(2u, 'c'))); // Test a const range of a different type. - typedef std::pair<std::size_t, int> IntPairType; + using IntPairType = std::pair<std::size_t, int>; std::vector<IntPairType> IntResults; const std::vector<int> bar = {1, 2, 3}; for (auto [index, value] : llvm::enumerate(bar)) { @@ -111,7 +111,7 @@ TEST(STLExtrasTest, EnumerateModifyLValue) { TEST(STLExtrasTest, EnumerateRValueRef) { // Test that an rvalue can be enumerated. - typedef std::pair<std::size_t, int> PairType; + using PairType = std::pair<std::size_t, int>; std::vector<PairType> Results; auto Enumerator = llvm::enumerate(std::vector<int>{1, 2, 3}); @@ -138,7 +138,7 @@ TEST(STLExtrasTest, EnumerateModifyRValue) { // Test that when enumerating an rvalue, modification still works (even if // this isn't terribly useful, it at least shows that we haven't snuck an // extra const in there somewhere. - typedef std::pair<std::size_t, char> PairType; + using PairType = std::pair<std::size_t, char>; std::vector<PairType> Results; for (auto X : llvm::enumerate(std::vector<char>{'1', '2', '3'})) { @@ -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/STLForwardCompatTest.cpp b/llvm/unittests/ADT/STLForwardCompatTest.cpp index c6ae6e3..d0092fd 100644 --- a/llvm/unittests/ADT/STLForwardCompatTest.cpp +++ b/llvm/unittests/ADT/STLForwardCompatTest.cpp @@ -11,7 +11,6 @@ #include "gtest/gtest.h" #include <optional> -#include <tuple> #include <type_traits> #include <utility> diff --git a/llvm/unittests/ADT/SequenceTest.cpp b/llvm/unittests/ADT/SequenceTest.cpp index 7b7dc85..ab50ad0 100644 --- a/llvm/unittests/ADT/SequenceTest.cpp +++ b/llvm/unittests/ADT/SequenceTest.cpp @@ -11,8 +11,9 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include <algorithm> -#include <numeric> +#include <iterator> +#include <limits> +#include <vector> using namespace llvm; 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/ADT/SimpleIListTest.cpp b/llvm/unittests/ADT/SimpleIListTest.cpp index c2992ba..cf3df8c 100644 --- a/llvm/unittests/ADT/SimpleIListTest.cpp +++ b/llvm/unittests/ADT/SimpleIListTest.cpp @@ -605,8 +605,8 @@ struct Tag2 {}; struct DoubleNode : ilist_node<DoubleNode, ilist_tag<Tag1>>, ilist_node<DoubleNode, ilist_tag<Tag2>> { - typedef ilist_node<DoubleNode, ilist_tag<Tag1>> Node1Type; - typedef ilist_node<DoubleNode, ilist_tag<Tag2>> Node2Type; + using Node1Type = ilist_node<DoubleNode, ilist_tag<Tag1>>; + using Node2Type = ilist_node<DoubleNode, ilist_tag<Tag2>>; Node1Type::self_iterator getIterator1() { return Node1Type::getIterator(); } Node2Type::self_iterator getIterator2() { return Node2Type::getIterator(); } @@ -617,8 +617,8 @@ struct DoubleNode : ilist_node<DoubleNode, ilist_tag<Tag1>>, return Node2Type::getIterator(); } }; -typedef simple_ilist<DoubleNode, ilist_tag<Tag1>> TaggedList1Type; -typedef simple_ilist<DoubleNode, ilist_tag<Tag2>> TaggedList2Type; +using TaggedList1Type = simple_ilist<DoubleNode, ilist_tag<Tag1>>; +using TaggedList2Type = simple_ilist<DoubleNode, ilist_tag<Tag2>>; TEST(SimpleIListTest, TaggedLists) { TaggedList1Type L1; diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp index a627091..fe7a827 100644 --- a/llvm/unittests/ADT/SmallPtrSetTest.cpp +++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp @@ -57,7 +57,7 @@ TEST(SmallPtrSetTest, GrowthTest) { SmallPtrSet<int *, 4> s; - typedef SmallPtrSet<int *, 4>::iterator iter; + using iter = SmallPtrSet<int *, 4>::iterator; s.insert(&buf[0]); s.insert(&buf[1]); diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp index 2f4df8a..db85824 100644 --- a/llvm/unittests/ADT/SmallStringTest.cpp +++ b/llvm/unittests/ADT/SmallStringTest.cpp @@ -23,7 +23,7 @@ namespace { // Test fixture class class SmallStringTest : public testing::Test { protected: - typedef SmallString<40> StringType; + using StringType = SmallString<40>; StringType theString; diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp index 1a01f30..dbc626d 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp @@ -159,7 +159,7 @@ int Constructable::numCopyAssignmentCalls; int Constructable::numMoveAssignmentCalls; struct NonCopyable { - NonCopyable() {} + NonCopyable() = default; NonCopyable(NonCopyable &&) {} NonCopyable &operator=(NonCopyable &&) { return *this; } private: @@ -226,13 +226,10 @@ protected: VectorT otherVector; }; - -typedef ::testing::Types<SmallVector<Constructable, 0>, - SmallVector<Constructable, 1>, - SmallVector<Constructable, 2>, - SmallVector<Constructable, 4>, - SmallVector<Constructable, 5> - > SmallVectorTestTypes; +using SmallVectorTestTypes = ::testing::Types< + SmallVector<Constructable, 0>, SmallVector<Constructable, 1>, + SmallVector<Constructable, 2>, SmallVector<Constructable, 4>, + SmallVector<Constructable, 5>>; TYPED_TEST_SUITE(SmallVectorTest, SmallVectorTestTypes, ); // Constructor test. @@ -537,11 +534,11 @@ TYPED_TEST(SmallVectorTest, AppendNonIterTest) { } struct output_iterator { - typedef std::output_iterator_tag iterator_category; - typedef int value_type; - typedef int difference_type; - typedef value_type *pointer; - typedef value_type &reference; + using iterator_category = std::output_iterator_tag; + using value_type = int; + using difference_type = int; + using pointer = value_type *; + using reference = value_type &; operator int() { return 2; } operator Constructable() { return 7; } }; @@ -896,7 +893,7 @@ protected: VectorT2 otherVector; }; -typedef ::testing::Types< +using DualSmallVectorTestTypes = ::testing::Types< // Small mode -> Small mode. std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 4>>, // Small mode -> Big mode. @@ -904,8 +901,7 @@ typedef ::testing::Types< // Big mode -> Small mode. std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 4>>, // Big mode -> Big mode. - std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>> - > DualSmallVectorTestTypes; + std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>>>; TYPED_TEST_SUITE(DualSmallVectorsTest, DualSmallVectorTestTypes, ); diff --git a/llvm/unittests/ADT/SparseMultiSetTest.cpp b/llvm/unittests/ADT/SparseMultiSetTest.cpp index 54f7bc99..91d37f4 100644 --- a/llvm/unittests/ADT/SparseMultiSetTest.cpp +++ b/llvm/unittests/ADT/SparseMultiSetTest.cpp @@ -13,7 +13,7 @@ using namespace llvm; namespace { -typedef SparseMultiSet<unsigned> USet; +using USet = SparseMultiSet<unsigned>; // Empty set tests. TEST(SparseMultiSetTest, EmptySet) { @@ -211,7 +211,7 @@ struct Alt { }; TEST(SparseMultiSetTest, AltStructSet) { - typedef SparseMultiSet<Alt> ASet; + using ASet = SparseMultiSet<Alt>; ASet Set; Set.setUniverse(10); Set.insert(Alt(1005)); diff --git a/llvm/unittests/ADT/SparseSetTest.cpp b/llvm/unittests/ADT/SparseSetTest.cpp index 4fbf1ca..f2b9329 100644 --- a/llvm/unittests/ADT/SparseSetTest.cpp +++ b/llvm/unittests/ADT/SparseSetTest.cpp @@ -13,7 +13,7 @@ using namespace llvm; namespace { -typedef SparseSet<unsigned> USet; +using USet = SparseSet<unsigned>; // Empty set tests. TEST(SparseSetTest, EmptySet) { @@ -166,7 +166,7 @@ struct Alt { }; TEST(SparseSetTest, AltStructSet) { - typedef SparseSet<Alt> ASet; + using ASet = SparseSet<Alt>; ASet Set; Set.setUniverse(10); Set.insert(Alt(1005)); diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp index 92ae364..1d92de4 100644 --- a/llvm/unittests/ADT/StringMapTest.cpp +++ b/llvm/unittests/ADT/StringMapTest.cpp @@ -367,7 +367,7 @@ TEST_F(StringMapTest, NonDefaultConstructable) { } struct Immovable { - Immovable() {} + Immovable() = default; Immovable(Immovable &&) = delete; // will disable the other special members }; diff --git a/llvm/unittests/ADT/StringSwitchTest.cpp b/llvm/unittests/ADT/StringSwitchTest.cpp index c94feb5..75d50f4 100644 --- a/llvm/unittests/ADT/StringSwitchTest.cpp +++ b/llvm/unittests/ADT/StringSwitchTest.cpp @@ -240,6 +240,23 @@ TEST(StringSwitchTest, CasesCopies) { EXPECT_EQ(NumCopies, 1u); } +TEST(StringSwitchTest, StringSwitchMultipleMatches) { + auto Translate = [](StringRef S) { + return llvm::StringSwitch<int>(S) + .CaseLower("A", 0) + .Case("b", 1) + .Case("a", 2) + .CasesLower({"a", "b"}, 3) + .DefaultUnreachable(); + }; + + // Check that the value of the first match is returned. + EXPECT_EQ(0, Translate("A")); + EXPECT_EQ(0, Translate("a")); + EXPECT_EQ(3, Translate("B")); + EXPECT_EQ(1, Translate("b")); +} + TEST(StringSwitchTest, DefaultUnreachable) { auto Translate = [](StringRef S) { return llvm::StringSwitch<int>(S) diff --git a/llvm/unittests/ADT/TestGraph.h b/llvm/unittests/ADT/TestGraph.h index a59ab50..bb2ec47 100644 --- a/llvm/unittests/ADT/TestGraph.h +++ b/llvm/unittests/ADT/TestGraph.h @@ -34,7 +34,7 @@ public: /// NodeSubset - A subset of the graph's nodes. class NodeSubset { - typedef unsigned char BitVector; // Where the limitation N <= 8 comes from. + using BitVector = unsigned char; // Where the limitation N <= 8 comes from. BitVector Elements; NodeSubset(BitVector e) : Elements(e) {} public: @@ -96,7 +96,7 @@ public: }; /// NodeType - Node index and set of children of the node. - typedef std::pair<unsigned, NodeSubset> NodeType; + using NodeType = std::pair<unsigned, NodeSubset>; private: /// Nodes - The list of nodes for this graph. @@ -233,8 +233,8 @@ public: template <unsigned N> struct GraphTraits<Graph<N> > { - typedef typename Graph<N>::NodeType *NodeRef; - typedef typename Graph<N>::ChildIterator ChildIteratorType; + using NodeRef = typename Graph<N>::NodeType *; + using ChildIteratorType = typename Graph<N>::ChildIterator; static NodeRef getEntryNode(const Graph<N> &G) { return G.AccessNode(0); } static ChildIteratorType child_begin(NodeRef Node) { diff --git a/llvm/unittests/ADT/TinyPtrVectorTest.cpp b/llvm/unittests/ADT/TinyPtrVectorTest.cpp index af4ae4f..c77721d 100644 --- a/llvm/unittests/ADT/TinyPtrVectorTest.cpp +++ b/llvm/unittests/ADT/TinyPtrVectorTest.cpp @@ -28,14 +28,14 @@ template <typename PointerTy, unsigned IntBits, typename IntType, typename PtrTraits, typename Info> struct RemovePointer< PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>> { - typedef typename RemovePointer<PointerTy>::type type; + using type = typename RemovePointer<PointerTy>::type; }; template <typename VectorT> class TinyPtrVectorTest : public testing::Test { protected: - typedef typename VectorT::value_type PtrT; - typedef typename RemovePointer<PtrT>::type ValueT; + using PtrT = typename VectorT::value_type; + using ValueT = typename RemovePointer<PtrT>::type; using PtrTraits = PointerLikeTypeTraits<PtrT>; VectorT V; @@ -78,9 +78,9 @@ protected: } }; -typedef ::testing::Types<TinyPtrVector<int *>, TinyPtrVector<double *>, - TinyPtrVector<PointerIntPair<int *, 1>>> - TinyPtrVectorTestTypes; +using TinyPtrVectorTestTypes = + ::testing::Types<TinyPtrVector<int *>, TinyPtrVector<double *>, + TinyPtrVector<PointerIntPair<int *, 1>>>; TYPED_TEST_SUITE(TinyPtrVectorTest, TinyPtrVectorTestTypes, ); TYPED_TEST(TinyPtrVectorTest, EmptyTest) { diff --git a/llvm/unittests/ADT/TypeSwitchTest.cpp b/llvm/unittests/ADT/TypeSwitchTest.cpp index b801228..0a92717 100644 --- a/llvm/unittests/ADT/TypeSwitchTest.cpp +++ b/llvm/unittests/ADT/TypeSwitchTest.cpp @@ -167,7 +167,7 @@ TEST(TypeSwitchTest, DefaultNullptr) { TEST(TypeSwitchTest, DefaultNullptrForPointerLike) { struct Value { void *ptr; - Value(const Value &other) : ptr(other.ptr) {} + Value(const Value &other) = default; Value(std::nullptr_t) : ptr(nullptr) {} Value() : Value(nullptr) {} }; diff --git a/llvm/unittests/Analysis/AliasAnalysisTest.cpp b/llvm/unittests/Analysis/AliasAnalysisTest.cpp index 06066b1..a28d318 100644 --- a/llvm/unittests/Analysis/AliasAnalysisTest.cpp +++ b/llvm/unittests/Analysis/AliasAnalysisTest.cpp @@ -232,18 +232,18 @@ TEST_F(AliasAnalysisTest, BatchAAPhiCycles) { LLVMContext C; SMDiagnostic Err; std::unique_ptr<Module> M = parseAssemblyString(R"( - define void @f(i8* noalias %a, i1 %c) { + define void @f(ptr noalias %a, i1 %c) { entry: br label %loop loop: - %phi = phi i8* [ null, %entry ], [ %a2, %loop ] + %phi = phi ptr [ null, %entry ], [ %a2, %loop ] %offset1 = phi i64 [ 0, %entry ], [ %offset2, %loop] %offset2 = add i64 %offset1, 1 - %a1 = getelementptr i8, i8* %a, i64 %offset1 - %a2 = getelementptr i8, i8* %a, i64 %offset2 - %s1 = select i1 %c, i8* %a1, i8* %phi - %s2 = select i1 %c, i8* %a2, i8* %a1 + %a1 = getelementptr i8, ptr %a, i64 %offset1 + %a2 = getelementptr i8, ptr %a, i64 %offset2 + %s1 = select i1 %c, ptr %a1, ptr %phi + %s2 = select i1 %c, ptr %a2, ptr %a1 br label %loop } )", Err, C); @@ -280,15 +280,15 @@ TEST_F(AliasAnalysisTest, BatchAAPhiAssumption) { LLVMContext C; SMDiagnostic Err; std::unique_ptr<Module> M = parseAssemblyString(R"( - define void @f(i8* %a.base, i8* %b.base, i1 %c) { + define void @f(ptr %a.base, ptr %b.base, i1 %c) { entry: br label %loop loop: - %a = phi i8* [ %a.next, %loop ], [ %a.base, %entry ] - %b = phi i8* [ %b.next, %loop ], [ %b.base, %entry ] - %a.next = getelementptr i8, i8* %a, i64 1 - %b.next = getelementptr i8, i8* %b, i64 1 + %a = phi ptr [ %a.next, %loop ], [ %a.base, %entry ] + %b = phi ptr [ %b.next, %loop ], [ %b.base, %entry ] + %a.next = getelementptr i8, ptr %a, i64 1 + %b.next = getelementptr i8, ptr %b, i64 1 br label %loop } )", Err, C); @@ -318,16 +318,16 @@ TEST_F(AliasAnalysisTest, PartialAliasOffset) { LLVMContext C; SMDiagnostic Err; std::unique_ptr<Module> M = parseAssemblyString(R"( - define void @foo(float* %arg, i32 %i) { + define void @foo(ptr %arg, i32 %i) { bb: %i2 = zext i32 %i to i64 - %i3 = getelementptr inbounds float, float* %arg, i64 %i2 - %i4 = bitcast float* %i3 to <2 x float>* - %L1 = load <2 x float>, <2 x float>* %i4, align 16 + %i3 = getelementptr inbounds float, ptr %arg, i64 %i2 + %i4 = bitcast ptr %i3 to ptr + %L1 = load <2 x float>, ptr %i4, align 16 %i7 = add nuw nsw i32 %i, 1 %i8 = zext i32 %i7 to i64 - %i9 = getelementptr inbounds float, float* %arg, i64 %i8 - %L2 = load float, float* %i9, align 4 + %i9 = getelementptr inbounds float, ptr %arg, i64 %i8 + %L2 = load float, ptr %i9, align 4 ret void } )", @@ -353,11 +353,11 @@ TEST_F(AliasAnalysisTest, PartialAliasOffsetSign) { LLVMContext C; SMDiagnostic Err; std::unique_ptr<Module> M = parseAssemblyString(R"( - define void @f(i64* %p) { - %L1 = load i64, i64* %p - %p.i8 = bitcast i64* %p to i8* - %q = getelementptr i8, i8* %p.i8, i32 1 - %L2 = load i8, i8* %q + define void @f(ptr %p) { + %L1 = load i64, ptr %p + %p.i8 = bitcast ptr %p to ptr + %q = getelementptr i8, ptr %p.i8, i32 1 + %L2 = load i8, ptr %q ret void } )", @@ -388,10 +388,10 @@ protected: public: AAPassInfraTest() - : M(parseAssemblyString("define i32 @f(i32* %x, i32* %y) {\n" + : M(parseAssemblyString("define i32 @f(ptr %x, ptr %y) {\n" "entry:\n" - " %lx = load i32, i32* %x\n" - " %ly = load i32, i32* %y\n" + " %lx = load i32, ptr %x\n" + " %ly = load i32, ptr %y\n" " %sum = add i32 %lx, %ly\n" " ret i32 %sum\n" "}\n", diff --git a/llvm/unittests/Analysis/AliasSetTrackerTest.cpp b/llvm/unittests/Analysis/AliasSetTrackerTest.cpp index e784e6e..b5adc84 100644 --- a/llvm/unittests/Analysis/AliasSetTrackerTest.cpp +++ b/llvm/unittests/Analysis/AliasSetTrackerTest.cpp @@ -26,13 +26,13 @@ TEST(AliasSetTracker, AliasUnknownInst) { ; Function Attrs: nounwind ssp uwtable define i32 @read_a() #0 { - %1 = load i32, i32* @a, align 4, !tbaa !3 + %1 = load i32, ptr @a, align 4, !tbaa !3 ret i32 %1 } ; Function Attrs: nounwind ssp uwtable define void @write_b() #0 { - store float 1.000000e+01, float* @b, align 4, !tbaa !7 + store float 1.000000e+01, ptr @b, align 4, !tbaa !7 ret void } @@ -72,7 +72,7 @@ TEST(AliasSetTracker, AliasUnknownInst) { AliasSetTracker AST(BAA); for (auto &BB : *Test) AST.add(BB); - // There should be 2 disjoint alias sets. 1 from each call. + // There should be 2 disjoint alias sets. 1 from each call. ASSERT_EQ((int)AST.getAliasSets().size(), 2); // Directly test aliasesUnknownInst. diff --git a/llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp b/llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp index 5fd2ecc..921e2aa 100644 --- a/llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp +++ b/llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp @@ -74,18 +74,18 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) { EnableKnowledgeRetention.setValue(true); StringRef Head = "declare void @llvm.assume(i1)\n" - "declare void @func(i32*, i32*, i32*)\n" - "declare void @func1(i32*, i32*, i32*, i32*)\n" - "declare void @func_many(i32*) \"no-jump-tables\" nounwind " + "declare void @func(ptr, ptr, ptr)\n" + "declare void @func1(ptr, ptr, ptr, ptr)\n" + "declare void @func_many(ptr) \"no-jump-tables\" nounwind " "\"less-precise-fpmad\" willreturn norecurse\n" - "define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {\n"; + "define void @test(ptr %P, ptr %P1, ptr %P2, ptr %P3) {\n"; StringRef Tail = "ret void\n" "}"; std::vector<std::pair<StringRef, llvm::function_ref<void(Instruction *)>>> Tests; Tests.push_back(std::make_pair( - "call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align " - "8 noalias %P1, i32* align 8 noundef %P2)\n", + "call void @func(ptr nonnull align 4 dereferenceable(16) %P, ptr align " + "8 noalias %P1, ptr align 8 noundef %P2)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -103,11 +103,11 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) { Attribute::AttrKind::Alignment, 4)); })); Tests.push_back(std::make_pair( - "call void @func1(i32* nonnull align 32 dereferenceable(48) %P, i32* " + "call void @func1(ptr nonnull align 32 dereferenceable(48) %P, ptr " "nonnull " - "align 8 dereferenceable(28) %P, i32* nonnull align 64 " + "align 8 dereferenceable(28) %P, ptr nonnull align 64 " "dereferenceable(4) " - "%P, i32* nonnull align 16 dereferenceable(12) %P)\n", + "%P, ptr nonnull align 16 dereferenceable(12) %P)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -127,7 +127,7 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) { Attribute::AttrKind::Alignment, 64)); })); Tests.push_back(std::make_pair( - "call void @func_many(i32* align 8 noundef %P1) cold\n", [](Instruction *I) { + "call void @func_many(ptr align 8 noundef %P1) cold\n", [](Instruction *I) { ShouldPreserveAllAttributes.setValue(true); auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -142,11 +142,11 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) { ASSERT_TRUE(hasMatchesExactlyAttributes(Assume, nullptr, "")); })); Tests.push_back(std::make_pair( - "call void @func1(i32* readnone align 32 " - "dereferenceable(48) noalias %P, i32* " - "align 8 dereferenceable(28) %P1, i32* align 64 " + "call void @func1(ptr readnone align 32 " + "dereferenceable(48) noalias %P, ptr " + "align 8 dereferenceable(28) %P1, ptr align 64 " "dereferenceable(4) " - "%P2, i32* nonnull align 16 dereferenceable(12) %P3)\n", + "%P2, ptr nonnull align 16 dereferenceable(12) %P3)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -178,11 +178,11 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) { })); Tests.push_back(std::make_pair( - "call void @func1(i32* readnone align 32 " - "dereferenceable(48) noalias %P, i32* " - "align 8 dereferenceable(28) %P1, i32* align 64 " + "call void @func1(ptr readnone align 32 " + "dereferenceable(48) noalias %P, ptr " + "align 8 dereferenceable(28) %P1, ptr align 64 " "dereferenceable(4) " - "%P2, i32* nonnull align 16 dereferenceable(12) %P3)\n", + "%P2, ptr nonnull align 16 dereferenceable(12) %P3)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -204,8 +204,8 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) { Attribute::AttrKind::Dereferenceable, 48)); })); Tests.push_back(std::make_pair( - "call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align " - "8 noalias %P1, i32* %P1)\n", + "call void @func(ptr nonnull align 4 dereferenceable(16) %P, ptr align " + "8 noalias %P1, ptr %P1)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -251,18 +251,18 @@ TEST(AssumeQueryAPI, fillMapFromAssume) { EnableKnowledgeRetention.setValue(true); StringRef Head = "declare void @llvm.assume(i1)\n" - "declare void @func(i32*, i32*, i32*)\n" - "declare void @func1(i32*, i32*, i32*, i32*)\n" - "declare void @func_many(i32*) \"no-jump-tables\" nounwind " + "declare void @func(ptr, ptr, ptr)\n" + "declare void @func1(ptr, ptr, ptr, ptr)\n" + "declare void @func_many(ptr) \"no-jump-tables\" nounwind " "\"less-precise-fpmad\" willreturn norecurse\n" - "define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {\n"; + "define void @test(ptr %P, ptr %P1, ptr %P2, ptr %P3) {\n"; StringRef Tail = "ret void\n" "}"; std::vector<std::pair<StringRef, llvm::function_ref<void(Instruction *)>>> Tests; Tests.push_back(std::make_pair( - "call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align " - "8 noalias %P1, i32* align 8 dereferenceable(8) %P2)\n", + "call void @func(ptr nonnull align 4 dereferenceable(16) %P, ptr align " + "8 noalias %P1, ptr align 8 dereferenceable(8) %P2)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -283,11 +283,11 @@ TEST(AssumeQueryAPI, fillMapFromAssume) { {4, 4})); })); Tests.push_back(std::make_pair( - "call void @func1(i32* nonnull align 32 dereferenceable(48) %P, i32* " + "call void @func1(ptr nonnull align 32 dereferenceable(48) %P, ptr " "nonnull " - "align 8 dereferenceable(28) %P, i32* nonnull align 64 " + "align 8 dereferenceable(28) %P, ptr nonnull align 64 " "dereferenceable(4) " - "%P, i32* nonnull align 16 dereferenceable(12) %P)\n", + "%P, ptr nonnull align 16 dereferenceable(12) %P)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -310,7 +310,7 @@ TEST(AssumeQueryAPI, fillMapFromAssume) { Map, Assume, {I->getOperand(0), Attribute::Alignment}, {64, 64})); })); Tests.push_back(std::make_pair( - "call void @func_many(i32* align 8 %P1) cold\n", [](Instruction *I) { + "call void @func_many(ptr align 8 %P1) cold\n", [](Instruction *I) { ShouldPreserveAllAttributes.setValue(true); auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -331,11 +331,11 @@ TEST(AssumeQueryAPI, fillMapFromAssume) { ASSERT_TRUE(Map.empty()); })); Tests.push_back(std::make_pair( - "call void @func1(i32* readnone align 32 " - "dereferenceable(48) noalias %P, i32* " - "align 8 dereferenceable(28) %P1, i32* align 64 " + "call void @func1(ptr readnone align 32 " + "dereferenceable(48) noalias %P, ptr " + "align 8 dereferenceable(28) %P1, ptr align 64 " "dereferenceable(4) " - "%P2, i32* nonnull align 16 dereferenceable(12) %P3)\n", + "%P2, ptr nonnull align 16 dereferenceable(12) %P3)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -371,8 +371,8 @@ TEST(AssumeQueryAPI, fillMapFromAssume) { /// Keep this test last as it modifies the function. Tests.push_back(std::make_pair( - "call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align " - "8 noalias %P1, i32* %P2)\n", + "call void @func(ptr nonnull align 4 dereferenceable(16) %P, ptr align " + "8 noalias %P1, ptr %P2)\n", [](Instruction *I) { auto *Assume = buildAssumeFromInst(I); Assume->insertBefore(I->getIterator()); @@ -507,11 +507,11 @@ TEST(AssumeQueryAPI, AssumptionCache) { SMDiagnostic Err; std::unique_ptr<Module> Mod = parseAssemblyString( "declare void @llvm.assume(i1)\n" - "define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3, i1 %B) {\n" - "call void @llvm.assume(i1 true) [\"nonnull\"(i32* %P), \"align\"(i32* " - "%P2, i32 4), \"align\"(i32* %P, i32 8)]\n" - "call void @llvm.assume(i1 %B) [\"test\"(i32* %P1), " - "\"dereferenceable\"(i32* %P, i32 4)]\n" + "define void @test(ptr %P, ptr %P1, ptr %P2, ptr %P3, i1 %B) {\n" + "call void @llvm.assume(i1 true) [\"nonnull\"(ptr %P), \"align\"(ptr " + "%P2, i32 4), \"align\"(ptr %P, i32 8)]\n" + "call void @llvm.assume(i1 %B) [\"test\"(ptr %P1), " + "\"dereferenceable\"(ptr %P, i32 4)]\n" "ret void\n}\n", Err, C); if (!Mod) @@ -569,11 +569,11 @@ TEST(AssumeQueryAPI, Alignment) { SMDiagnostic Err; std::unique_ptr<Module> Mod = parseAssemblyString( "declare void @llvm.assume(i1)\n" - "define void @test(i32* %P, i32* %P1, i32* %P2, i32 %I3, i1 %B) {\n" - "call void @llvm.assume(i1 true) [\"align\"(i32* %P, i32 8, i32 %I3)]\n" - "call void @llvm.assume(i1 true) [\"align\"(i32* %P1, i32 %I3, i32 " + "define void @test(ptr %P, ptr %P1, ptr %P2, i32 %I3, i1 %B) {\n" + "call void @llvm.assume(i1 true) [\"align\"(ptr %P, i32 8, i32 %I3)]\n" + "call void @llvm.assume(i1 true) [\"align\"(ptr %P1, i32 %I3, i32 " "%I3)]\n" - "call void @llvm.assume(i1 true) [\"align\"(i32* %P2, i32 16, i32 8)]\n" + "call void @llvm.assume(i1 true) [\"align\"(ptr %P2, i32 16, i32 8)]\n" "ret void\n}\n", Err, C); if (!Mod) diff --git a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp index 17240a1..bf5afe8 100644 --- a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp +++ b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp @@ -1936,26 +1936,26 @@ TEST_F(CGSCCPassManagerTest, TestDeletionOfFunctionInNonTrivialRefSCC) { TEST_F(CGSCCPassManagerTest, TestInsertionOfNewNonTrivialCallEdge) { std::unique_ptr<Module> M = parseIR("define void @f1() {\n" "entry:\n" - " %a = bitcast void ()* @f4 to i8*\n" - " %b = bitcast void ()* @f2 to i8*\n" + " %a = bitcast ptr @f4 to ptr\n" + " %b = bitcast ptr @f2 to ptr\n" " ret void\n" "}\n" "define void @f2() {\n" "entry:\n" - " %a = bitcast void ()* @f1 to i8*\n" - " %b = bitcast void ()* @f3 to i8*\n" + " %a = bitcast ptr @f1 to ptr\n" + " %b = bitcast ptr @f3 to ptr\n" " ret void\n" "}\n" "define void @f3() {\n" "entry:\n" - " %a = bitcast void ()* @f2 to i8*\n" - " %b = bitcast void ()* @f4 to i8*\n" + " %a = bitcast ptr @f2 to ptr\n" + " %b = bitcast ptr @f4 to ptr\n" " ret void\n" "}\n" "define void @f4() {\n" "entry:\n" - " %a = bitcast void ()* @f3 to i8*\n" - " %b = bitcast void ()* @f1 to i8*\n" + " %a = bitcast ptr @f3 to ptr\n" + " %b = bitcast ptr @f1 to ptr\n" " ret void\n" "}\n"); diff --git a/llvm/unittests/Analysis/CaptureTrackingTest.cpp b/llvm/unittests/Analysis/CaptureTrackingTest.cpp index ea3f21e..d7ee525 100644 --- a/llvm/unittests/Analysis/CaptureTrackingTest.cpp +++ b/llvm/unittests/Analysis/CaptureTrackingTest.cpp @@ -20,27 +20,27 @@ using namespace llvm; TEST(CaptureTracking, MaxUsesToExplore) { StringRef Assembly = R"( ; Function Attrs: nounwind ssp uwtable - declare void @doesnt_capture(i8* nocapture, i8* nocapture, i8* nocapture, - i8* nocapture, i8* nocapture) + declare void @doesnt_capture(ptr nocapture, ptr nocapture, ptr nocapture, + ptr nocapture, ptr nocapture) ; %arg has 5 uses - define void @test_few_uses(i8* %arg) { - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) + define void @test_few_uses(ptr %arg) { + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) ret void } ; %arg has 50 uses - define void @test_many_uses(i8* %arg) { - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) - call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg) + define void @test_many_uses(ptr %arg) { + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) + call void @doesnt_capture(ptr %arg, ptr %arg, ptr %arg, ptr %arg, ptr %arg) ret void } )"; @@ -85,12 +85,12 @@ struct CollectingCaptureTracker : public CaptureTracker { TEST(CaptureTracking, MultipleUsesInSameInstruction) { StringRef Assembly = R"( - declare void @call(i8*, i8*, i8*) + declare void @call(ptr, ptr, ptr) - define void @test(i8* %arg, i8** %ptr) { - call void @call(i8* %arg, i8* nocapture %arg, i8* %arg) [ "bundle"(i8* %arg) ] - cmpxchg i8** %ptr, i8* %arg, i8* %arg acq_rel monotonic - icmp eq i8* %arg, %arg + define void @test(ptr %arg, ptr %ptr) { + call void @call(ptr %arg, ptr nocapture %arg, ptr %arg) [ "bundle"(ptr %arg) ] + cmpxchg ptr %ptr, ptr %arg, ptr %arg acq_rel monotonic + icmp eq ptr %arg, %arg ret void } )"; diff --git a/llvm/unittests/Analysis/DDGTest.cpp b/llvm/unittests/Analysis/DDGTest.cpp index 7fcdfdb..12944a3 100644 --- a/llvm/unittests/Analysis/DDGTest.cpp +++ b/llvm/unittests/Analysis/DDGTest.cpp @@ -51,7 +51,7 @@ TEST(DDGTest, getDependencies) { "target datalayout = \"e-m:e-i64:64-n32:64\"\n" "target triple = \"powerpc64le-unknown-linux-gnu\"\n" "\n" - "define dso_local void @foo(i32 signext %n, i32* noalias %A, i32* " + "define dso_local void @foo(i32 signext %n, ptr noalias %A, ptr " "noalias %B) {\n" "entry:\n" " %cmp1 = icmp sgt i32 %n, 0\n" @@ -64,16 +64,16 @@ TEST(DDGTest, getDependencies) { " for.body:\n" " %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ " "%indvars.iv.next, %for.body ]\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv\n" + " %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv\n" " %0 = trunc i64 %indvars.iv to i32\n" - " store i32 %0, i32* %arrayidx, align 4\n" + " store i32 %0, ptr %arrayidx, align 4\n" " %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n" - " %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 " + " %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 " "%indvars.iv.next\n" - " %1 = load i32, i32* %arrayidx2, align 4\n" + " %1 = load i32, ptr %arrayidx2, align 4\n" " %add3 = add nsw i32 %1, 1\n" - " %arrayidx5 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv\n" - " store i32 %add3, i32* %arrayidx5, align 4\n" + " %arrayidx5 = getelementptr inbounds i32, ptr %B, i64 %indvars.iv\n" + " store i32 %add3, ptr %arrayidx5, align 4\n" " %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n" " br i1 %exitcond, label %for.body, label %for.end.loopexit\n" "\n" @@ -142,8 +142,8 @@ TEST(DDGTest, avoidDuplicateEdgesToFromPiBlocks) { const char *ModuleStr = "target datalayout = \"e-m:e-i64:64-n32:64-v256:256:256-v512:512:512\"\n" "\n" - "define void @foo(float* noalias %A, float* noalias %B, float* noalias " - "%C, float* noalias %D, i32 signext %n) {\n" + "define void @foo(ptr noalias %A, ptr noalias %B, ptr noalias " + "%C, ptr noalias %D, i32 signext %n) {\n" "entry:\n" " %cmp1 = icmp sgt i32 %n, 0\n" " br i1 %cmp1, label %for.body.preheader, label %for.end\n" @@ -156,26 +156,26 @@ TEST(DDGTest, avoidDuplicateEdgesToFromPiBlocks) { "%for.body.preheader, %if.end\n" " %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, " "%if.end ]\n" - " %arrayidx = getelementptr inbounds float, float* %A, i64 %indvars.iv\n" - " %loadASubI = load float, float* %arrayidx, align 4\n" - " %arrayidx2 = getelementptr inbounds float, float* %B, i64 " + " %arrayidx = getelementptr inbounds float, ptr %A, i64 %indvars.iv\n" + " %loadASubI = load float, ptr %arrayidx, align 4\n" + " %arrayidx2 = getelementptr inbounds float, ptr %B, i64 " "%indvars.iv\n" - " %loadBSubI = load float, float* %arrayidx2, align 4\n" + " %loadBSubI = load float, ptr %arrayidx2, align 4\n" " %add = fadd fast float %loadASubI, %loadBSubI\n" - " %arrayidx4 = getelementptr inbounds float, float* %A, i64 " + " %arrayidx4 = getelementptr inbounds float, ptr %A, i64 " "%indvars.iv\n" - " store float %add, float* %arrayidx4, align 4\n" - " %arrayidx6 = getelementptr inbounds float, float* %A, i64 " + " store float %add, ptr %arrayidx4, align 4\n" + " %arrayidx6 = getelementptr inbounds float, ptr %A, i64 " "%indvars.iv\n" - " %0 = load float, float* %arrayidx6, align 4\n" + " %0 = load float, ptr %arrayidx6, align 4\n" " %add7 = fadd fast float %0, 1.000000e+00\n" " %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n" - " %arrayidx10 = getelementptr inbounds float, float* %B, i64 " + " %arrayidx10 = getelementptr inbounds float, ptr %B, i64 " "%indvars.iv.next\n" - " store float %add7, float* %arrayidx10, align 4\n" - " %arrayidx12 = getelementptr inbounds float, float* %A, i64 " + " store float %add7, ptr %arrayidx10, align 4\n" + " %arrayidx12 = getelementptr inbounds float, ptr %A, i64 " "%indvars.iv\n" - " %1 = load float, float* %arrayidx12, align 4\n" + " %1 = load float, ptr %arrayidx12, align 4\n" " %cmp13 = fcmp fast ogt float %1, 1.000000e+02\n" " br i1 %cmp13, label %if.then, label %if.else\n" "\n" @@ -188,7 +188,7 @@ TEST(DDGTest, avoidDuplicateEdgesToFromPiBlocks) { "if.end: ; preds = %if.else, " "%if.then\n" " %ff.0 = phi float [ %add, %if.then ], [ %add7, %if.else ]\n" - " store float %ff.0, float* %C, align 4\n" + " store float %ff.0, ptr %C, align 4\n" " %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n" " br i1 %exitcond, label %for.body, label %for.end.loopexit\n" "\n" diff --git a/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp b/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp index cabfc2a..9f5fe57 100644 --- a/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp +++ b/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp @@ -17,7 +17,6 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "gtest/gtest.h" -#include <algorithm> using namespace llvm; diff --git a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp index 497da8f..dc5d0a8 100644 --- a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp +++ b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp @@ -457,7 +457,7 @@ entry: ret void } -define i32 @caller() personality i32 (...)* @__gxx_personality_v0 { +define i32 @caller() personality ptr @__gxx_personality_v0 { entry: invoke void @callee() to label %cont unwind label %exc @@ -466,7 +466,7 @@ cont: ret i32 0 exc: - %exn = landingpad {i8*, i32} + %exn = landingpad {ptr, i32} cleanup ret i32 1 } @@ -498,7 +498,7 @@ TEST_F(FunctionPropertiesAnalysisTest, InvokeUnreachableHandler) { R"IR( declare void @might_throw() -define internal i32 @callee() personality i32 (...)* @__gxx_personality_v0 { +define internal i32 @callee() personality ptr @__gxx_personality_v0 { entry: invoke void @might_throw() to label %cont unwind label %exc @@ -507,12 +507,12 @@ cont: ret i32 0 exc: - %exn = landingpad {i8*, i32} + %exn = landingpad {ptr, i32} cleanup - resume { i8*, i32 } %exn + resume { ptr, i32 } %exn } -define i32 @caller() personality i32 (...)* @__gxx_personality_v0 { +define i32 @caller() personality ptr @__gxx_personality_v0 { entry: %X = invoke i32 @callee() to label %cont unwind label %Handler @@ -521,7 +521,7 @@ cont: ret i32 %X Handler: - %exn = landingpad {i8*, i32} + %exn = landingpad {ptr, i32} cleanup ret i32 1 } @@ -554,7 +554,7 @@ TEST_F(FunctionPropertiesAnalysisTest, Rethrow) { R"IR( declare void @might_throw() -define internal i32 @callee() personality i32 (...)* @__gxx_personality_v0 { +define internal i32 @callee() personality ptr @__gxx_personality_v0 { entry: invoke void @might_throw() to label %cont unwind label %exc @@ -563,12 +563,12 @@ cont: ret i32 0 exc: - %exn = landingpad {i8*, i32} + %exn = landingpad {ptr, i32} cleanup - resume { i8*, i32 } %exn + resume { ptr, i32 } %exn } -define i32 @caller() personality i32 (...)* @__gxx_personality_v0 { +define i32 @caller() personality ptr @__gxx_personality_v0 { entry: %X = invoke i32 @callee() to label %cont unwind label %Handler @@ -577,7 +577,7 @@ cont: ret i32 %X Handler: - %exn = landingpad {i8*, i32} + %exn = landingpad {ptr, i32} cleanup ret i32 1 } @@ -612,18 +612,18 @@ declare void @external_func() @exception_type2 = external global i8 -define internal void @inner() personality i8* null { +define internal void @inner() personality ptr null { invoke void @external_func() to label %cont unwind label %lpad cont: ret void lpad: %lp = landingpad i32 - catch i8* @exception_type1 + catch ptr @exception_type1 resume i32 %lp } -define void @outer() personality i8* null { +define void @outer() personality ptr null { invoke void @inner() to label %cont unwind label %lpad cont: @@ -631,7 +631,7 @@ cont: lpad: %lp = landingpad i32 cleanup - catch i8* @exception_type2 + catch ptr @exception_type2 resume i32 %lp } @@ -666,18 +666,18 @@ declare void @external_func() @exception_type2 = external global i8 -define internal void @inner() personality i8* null { +define internal void @inner() personality ptr null { invoke void @external_func() to label %cont unwind label %lpad cont: ret void lpad: %lp = landingpad i32 - catch i8* @exception_type1 + catch ptr @exception_type1 resume i32 %lp } -define void @outer(i32 %a) personality i8* null { +define void @outer(i32 %a) personality ptr null { entry: %i = icmp slt i32 %a, 0 br i1 %i, label %if.then, label %cont @@ -689,7 +689,7 @@ cont: lpad: %lp = landingpad i32 cleanup - catch i8* @exception_type2 + catch ptr @exception_type2 resume i32 %lp } @@ -931,9 +931,9 @@ TEST_F(FunctionPropertiesAnalysisTest, DetailedOperandCount) { @a = global i64 1 define i64 @f1(i64 %e) { - %b = load i64, i64* @a + %b = load i64, ptr @a %c = add i64 %b, 2 - %d = call i64 asm "mov $1,$0", "=r,r" (i64 %c) + %d = call i64 asm "mov $1,$0", "=r,r" (i64 %c) %f = add i64 %d, %e ret i64 %f } diff --git a/llvm/unittests/Analysis/IR2VecTest.cpp b/llvm/unittests/Analysis/IR2VecTest.cpp index 8ffc5f6..1aa0e42 100644 --- a/llvm/unittests/Analysis/IR2VecTest.cpp +++ b/llvm/unittests/Analysis/IR2VecTest.cpp @@ -18,7 +18,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include <map> #include <vector> using namespace llvm; diff --git a/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/llvm/unittests/Analysis/LazyCallGraphTest.cpp index 4a4ff32..5c0bfbd 100644 --- a/llvm/unittests/Analysis/LazyCallGraphTest.cpp +++ b/llvm/unittests/Analysis/LazyCallGraphTest.cpp @@ -142,78 +142,78 @@ static const char DiamondOfTriangles[] = static const char DiamondOfTrianglesRefGraph[] = "define void @a1() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @a2, void ()** %a\n" - " store void ()* @b2, void ()** %a\n" - " store void ()* @c3, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @a2, ptr %a\n" + " store ptr @b2, ptr %a\n" + " store ptr @c3, ptr %a\n" " ret void\n" "}\n" "define void @a2() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @a3, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @a3, ptr %a\n" " ret void\n" "}\n" "define void @a3() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @a1, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @a1, ptr %a\n" " ret void\n" "}\n" "define void @b1() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @b2, void ()** %a\n" - " store void ()* @d3, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @b2, ptr %a\n" + " store ptr @d3, ptr %a\n" " ret void\n" "}\n" "define void @b2() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @b3, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @b3, ptr %a\n" " ret void\n" "}\n" "define void @b3() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @b1, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @b1, ptr %a\n" " ret void\n" "}\n" "define void @c1() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @c2, void ()** %a\n" - " store void ()* @d2, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @c2, ptr %a\n" + " store ptr @d2, ptr %a\n" " ret void\n" "}\n" "define void @c2() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @c3, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @c3, ptr %a\n" " ret void\n" "}\n" "define void @c3() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @c1, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @c1, ptr %a\n" " ret void\n" "}\n" "define void @d1() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @d2, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @d2, ptr %a\n" " ret void\n" "}\n" "define void @d2() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @d3, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @d3, ptr %a\n" " ret void\n" "}\n" "define void @d3() {\n" "entry:\n" - " %a = alloca void ()*\n" - " store void ()* @d1, void ()** %a\n" + " %a = alloca ptr\n" + " store ptr @d1, ptr %a\n" " ret void\n" "}\n"; @@ -1005,20 +1005,20 @@ TEST(LazyCallGraphTest, IncomingEdgeInsertionLargeRefCycle) { std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n" "entry:\n" - " %p = alloca void ()*\n" - " store void ()* @b, void ()** %p\n" + " %p = alloca ptr\n" + " store ptr @b, ptr %p\n" " ret void\n" "}\n" "define void @b() {\n" "entry:\n" - " %p = alloca void ()*\n" - " store void ()* @c, void ()** %p\n" + " %p = alloca ptr\n" + " store ptr @c, ptr %p\n" " ret void\n" "}\n" "define void @c() {\n" "entry:\n" - " %p = alloca void ()*\n" - " store void ()* @d, void ()** %p\n" + " %p = alloca ptr\n" + " store ptr @d, ptr %p\n" " ret void\n" "}\n" "define void @d() {\n" @@ -1306,25 +1306,25 @@ TEST(LazyCallGraphTest, InternalEdgeRemoval) { LLVMContext Context; // A nice fully connected (including self-edges) RefSCC. std::unique_ptr<Module> M = parseAssembly( - Context, "define void @a(i8** %ptr) {\n" + Context, "define void @a(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @a, ptr %ptr\n" + " store ptr @b, ptr %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n" - "define void @b(i8** %ptr) {\n" + "define void @b(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @a, ptr %ptr\n" + " store ptr @b, ptr %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n" - "define void @c(i8** %ptr) {\n" + "define void @c(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @a, ptr %ptr\n" + " store ptr @b, ptr %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1384,25 +1384,25 @@ TEST(LazyCallGraphTest, InternalMultiEdgeRemoval) { LLVMContext Context; // A nice fully connected (including self-edges) RefSCC. std::unique_ptr<Module> M = parseAssembly( - Context, "define void @a(i8** %ptr) {\n" + Context, "define void @a(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @a, ptr %ptr\n" + " store ptr @b, ptr %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n" - "define void @b(i8** %ptr) {\n" + "define void @b(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @a, ptr %ptr\n" + " store ptr @b, ptr %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n" - "define void @c(i8** %ptr) {\n" + "define void @c(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @a, ptr %ptr\n" + " store ptr @b, ptr %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1454,22 +1454,22 @@ TEST(LazyCallGraphTest, InternalNoOpEdgeRemoval) { // Reference edges: a -> b -> c -> a // Call edges: a -> c -> b -> a std::unique_ptr<Module> M = parseAssembly( - Context, "define void @a(i8** %ptr) {\n" + Context, "define void @a(ptr %ptr) {\n" "entry:\n" - " call void @b(i8** %ptr)\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " call void @b(ptr %ptr)\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n" - "define void @b(i8** %ptr) {\n" + "define void @b(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n" - " call void @c(i8** %ptr)\n" + " store ptr @a, ptr %ptr\n" + " call void @c(ptr %ptr)\n" " ret void\n" "}\n" - "define void @c(i8** %ptr) {\n" + "define void @c(ptr %ptr) {\n" "entry:\n" - " call void @a(i8** %ptr)\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" + " call void @a(ptr %ptr)\n" + " store ptr @b, ptr %ptr\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1622,24 +1622,24 @@ TEST(LazyCallGraphTest, InternalRefEdgeToCall) { "entry:\n" " call void @b()\n" " call void @c()\n" - " store void()* @d, void()** undef\n" + " store ptr @d, ptr undef\n" " ret void\n" "}\n" "define void @b() {\n" "entry:\n" - " store void()* @c, void()** undef\n" + " store ptr @c, ptr undef\n" " call void @d()\n" " ret void\n" "}\n" "define void @c() {\n" "entry:\n" - " store void()* @b, void()** undef\n" + " store ptr @b, ptr undef\n" " call void @d()\n" " ret void\n" "}\n" "define void @d() {\n" "entry:\n" - " store void()* @a, void()** undef\n" + " store ptr @a, ptr undef\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1745,13 +1745,13 @@ TEST(LazyCallGraphTest, InternalRefEdgeToCallNoCycleInterleaved) { "}\n" "define void @c3() {\n" "entry:\n" - " store void()* @b1, void()** undef\n" + " store ptr @b1, ptr undef\n" " call void @d()\n" " ret void\n" "}\n" "define void @d() {\n" "entry:\n" - " store void()* @a, void()** undef\n" + " store ptr @a, ptr undef\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1875,13 +1875,13 @@ TEST(LazyCallGraphTest, InternalRefEdgeToCallBothPartitionAndMerge) { "}\n" "define void @f() {\n" "entry:\n" - " store void()* @b, void()** undef\n" + " store ptr @b, ptr undef\n" " call void @g()\n" " ret void\n" "}\n" "define void @g() {\n" "entry:\n" - " store void()* @a, void()** undef\n" + " store ptr @a, ptr undef\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1962,9 +1962,9 @@ TEST(LazyCallGraphTest, HandleBlockAddress) { "bb:\n" " unreachable\n" "}\n" - "define void @g(i8** %ptr) {\n" + "define void @g(ptr %ptr) {\n" "entry:\n" - " store i8* blockaddress(@f, %bb), i8** %ptr\n" + " store ptr blockaddress(@f, %bb), ptr %ptr\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -1991,9 +1991,9 @@ TEST(LazyCallGraphTest, HandleBlockAddress2) { parseAssembly(Context, "define void @f() {\n" " ret void\n" "}\n" - "define void @g(i8** %ptr) {\n" + "define void @g(ptr %ptr) {\n" "bb:\n" - " store i8* blockaddress(@g, %bb), i8** %ptr\n" + " store ptr blockaddress(@g, %bb), ptr %ptr\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -2018,31 +2018,31 @@ TEST(LazyCallGraphTest, ReplaceNodeFunction) { // function. std::unique_ptr<Module> M = parseAssembly(Context, - "define void @a(i8** %ptr) {\n" + "define void @a(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n" + " store ptr @d, ptr %ptr\n" " ret void\n" "}\n" - "define void @b(i8** %ptr) {\n" + "define void @b(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n" - " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n" - " call void @d(i8** %ptr)" + " store ptr @d, ptr %ptr\n" + " store ptr @d, ptr %ptr\n" + " call void @d(ptr %ptr)" " ret void\n" "}\n" - "define void @c(i8** %ptr) {\n" + "define void @c(ptr %ptr) {\n" "entry:\n" - " call void @d(i8** %ptr)" - " call void @d(i8** %ptr)" - " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n" + " call void @d(ptr %ptr)" + " call void @d(ptr %ptr)" + " store ptr @d, ptr %ptr\n" " ret void\n" "}\n" - "define void @d(i8** %ptr) {\n" + "define void @d(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" - " call void @c(i8** %ptr)" - " call void @d(i8** %ptr)" - " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n" + " store ptr @b, ptr %ptr\n" + " call void @c(ptr %ptr)" + " call void @d(ptr %ptr)" + " store ptr @d, ptr %ptr\n" " ret void\n" "}\n"); LazyCallGraph CG = buildCG(*M); @@ -2098,25 +2098,25 @@ TEST(LazyCallGraphTest, RemoveFunctionWithSpuriousRef) { // A graph with a couple of RefSCCs. std::unique_ptr<Module> M = parseAssembly(Context, - "define void @a(i8** %ptr) {\n" + "define void @a(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n" + " store ptr @d, ptr %ptr\n" " ret void\n" "}\n" - "define void @b(i8** %ptr) {\n" + "define void @b(ptr %ptr) {\n" "entry:\n" - " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n" + " store ptr @c, ptr %ptr\n" " ret void\n" "}\n" - "define void @c(i8** %ptr) {\n" + "define void @c(ptr %ptr) {\n" "entry:\n" - " call void @d(i8** %ptr)" + " call void @d(ptr %ptr)" " ret void\n" "}\n" - "define void @d(i8** %ptr) {\n" + "define void @d(ptr %ptr) {\n" "entry:\n" - " call void @c(i8** %ptr)" - " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n" + " call void @c(ptr %ptr)" + " store ptr @b, ptr %ptr\n" " ret void\n" "}\n" "define void @dead() {\n" @@ -2965,7 +2965,7 @@ TEST(LazyCallGraphTest, AddSplitFunctions5) { LLVMContext Context; std::unique_ptr<Module> M = parseAssembly(Context, "define void @f() {\n" - " %1 = bitcast void ()* @f2 to i8*\n" + " %1 = bitcast ptr @f2 to ptr\n" " ret void\n" "}\n" "define void @f2() {\n" diff --git a/llvm/unittests/Analysis/SparsePropagation.cpp b/llvm/unittests/Analysis/SparsePropagation.cpp index ca73a48..0cbf5de 100644 --- a/llvm/unittests/Analysis/SparsePropagation.cpp +++ b/llvm/unittests/Analysis/SparsePropagation.cpp @@ -357,9 +357,9 @@ TEST_F(SparsePropagationTest, GlobalVariableOverDefined) { /// Test that we propagate information through function returns. /// -/// define internal i64 @f(i1* %cond) { +/// define internal i64 @f(ptr %cond) { /// if: -/// %0 = load i1, i1* %cond +/// %0 = load i1, ptr %cond /// br i1 %0, label %then, label %else /// /// then: @@ -397,9 +397,9 @@ TEST_F(SparsePropagationTest, FunctionDefined) { /// Test that we propagate information through function returns. /// -/// define internal i64 @f(i1* %cond) { +/// define internal i64 @f(ptr %cond) { /// if: -/// %0 = load i1, i1* %cond +/// %0 = load i1, ptr %cond /// br i1 %0, label %then, label %else /// /// then: diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp index b334195..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()); @@ -277,6 +277,12 @@ TEST_F(TargetLibraryInfoTest, ValidProto) { "declare x86_fp80 @logbl(x86_fp80)\n" "declare float @logf(float)\n" "declare x86_fp80 @logl(x86_fp80)\n" + "declare double @nextafter(double, double)\n" + "declare float @nextafterf(float, float)\n" + "declare x86_fp80 @nextafterl(x86_fp80, x86_fp80)\n" + "declare double @nexttoward(double, x86_fp80)\n" + "declare float @nexttowardf(float, x86_fp80)\n" + "declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80)\n" "declare i8* @malloc(i64)\n" "declare i8* @memccpy(i8*, i8*, i32, i64)\n" "declare i8* @memchr(i8*, i32, i64)\n" @@ -688,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/Analysis/UnrollAnalyzerTest.cpp b/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp index d5ba175..3c7ee7ad 100644 --- a/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp +++ b/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp @@ -214,18 +214,18 @@ TEST(UnrollAnalyzerTest, PtrCmpSimplifications) { "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n" "define void @ptr_cmp(i8 *%a) {\n" "entry:\n" - " %limit = getelementptr i8, i8* %a, i64 40\n" - " %start.iv2 = getelementptr i8, i8* %a, i64 7\n" + " %limit = getelementptr i8, ptr %a, i64 40\n" + " %start.iv2 = getelementptr i8, ptr %a, i64 7\n" " br label %loop.body\n" "loop.body:\n" - " %iv.0 = phi i8* [ %a, %entry ], [ %iv.1, %loop.body ]\n" - " %iv2.0 = phi i8* [ %start.iv2, %entry ], [ %iv2.1, %loop.body ]\n" - " %cmp = icmp eq i8* %iv2.0, %iv.0\n" - " %cmp2 = icmp slt i8* %iv2.0, %iv.0\n" - " %cmp3 = icmp ult i8* %iv2.0, %iv.0\n" - " %iv.1 = getelementptr inbounds i8, i8* %iv.0, i64 1\n" - " %iv2.1 = getelementptr inbounds i8, i8* %iv2.0, i64 1\n" - " %exitcond = icmp ne i8* %iv.1, %limit\n" + " %iv.0 = phi ptr [ %a, %entry ], [ %iv.1, %loop.body ]\n" + " %iv2.0 = phi ptr [ %start.iv2, %entry ], [ %iv2.1, %loop.body ]\n" + " %cmp = icmp eq ptr %iv2.0, %iv.0\n" + " %cmp2 = icmp slt ptr %iv2.0, %iv.0\n" + " %cmp3 = icmp ult ptr %iv2.0, %iv.0\n" + " %iv.1 = getelementptr inbounds i8, ptr %iv.0, i64 1\n" + " %iv2.1 = getelementptr inbounds i8, ptr %iv2.0, i64 1\n" + " %exitcond = icmp ne ptr %iv.1, %limit\n" " br i1 %exitcond, label %loop.body, label %loop.exit\n" "loop.exit:\n" " ret void\n" @@ -248,14 +248,14 @@ TEST(UnrollAnalyzerTest, PtrCmpSimplifications) { Instruction *Cmp2 = &*BBI++; Instruction *Cmp3 = &*BBI++; // Check simplification expected on the 5th iteration. - // Check that "%cmp = icmp eq i8* %iv2.0, %iv.0" is simplified to 0. + // Check that "%cmp = icmp eq ptr %iv2.0, %iv.0" is simplified to 0. auto I1 = SimplifiedValuesVector[5].find(Cmp1); EXPECT_TRUE(I1 != SimplifiedValuesVector[5].end()); EXPECT_EQ(cast<ConstantInt>((*I1).second)->getZExtValue(), 0U); - // Check that "%cmp2 = icmp slt i8* %iv2.0, %iv.0" does not simplify + // Check that "%cmp2 = icmp slt ptr %iv2.0, %iv.0" does not simplify auto I2 = SimplifiedValuesVector[5].find(Cmp2); EXPECT_TRUE(I2 == SimplifiedValuesVector[5].end()); - // Check that "%cmp3 = icmp ult i8* %iv2.0, %iv.0" is simplified to 0. + // Check that "%cmp3 = icmp ult ptr %iv2.0, %iv.0" is simplified to 0. auto I3 = SimplifiedValuesVector[5].find(Cmp3); EXPECT_TRUE(I3 != SimplifiedValuesVector[5].end()); EXPECT_EQ(cast<ConstantInt>((*I1).second)->getZExtValue(), 0U); @@ -271,8 +271,8 @@ TEST(UnrollAnalyzerTest, CastSimplifications) { "\n" "loop:\n" " %iv = phi i64 [ 0, %entry ], [ %inc, %loop ]\n" - " %array_const_idx = getelementptr inbounds [10 x i32], [10 x i32]* @known_constant, i64 0, i64 %iv\n" - " %const_array_element = load i32, i32* %array_const_idx, align 4\n" + " %array_const_idx = getelementptr inbounds [10 x i32], ptr @known_constant, i64 0, i64 %iv\n" + " %const_array_element = load i32, ptr %array_const_idx, align 4\n" " %se = sext i32 %const_array_element to i64\n" " %ze = zext i32 %const_array_element to i64\n" " %tr = trunc i32 %const_array_element to i8\n" diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index bb0280ee..89a0fae 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -2697,9 +2697,9 @@ TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPWithRange) { parseAssembly( "define void @test(ptr %p) {\n" " %A = load i64, ptr %p, !range !{i64 64, i64 65536}\n" - " %APtr = inttoptr i64 %A to float*" - " %APtrPlus512 = getelementptr float, float* %APtr, i32 128\n" - " %c = icmp ugt float* %APtrPlus512, inttoptr (i32 523 to float*)\n" + " %APtr = inttoptr i64 %A to ptr" + " %APtrPlus512 = getelementptr float, ptr %APtr, i32 128\n" + " %c = icmp ugt ptr %APtrPlus512, inttoptr (i32 523 to ptr)\n" " call void @llvm.assume(i1 %c)\n" " ret void\n" "}\n" @@ -2730,9 +2730,9 @@ TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPWithRangeNoOverlap) { parseAssembly( "define void @test(ptr %p) {\n" " %A = load i64, ptr %p, !range !{i64 32, i64 64}\n" - " %APtr = inttoptr i64 %A to float*" - " %APtrPlus512 = getelementptr float, float* %APtr, i32 128\n" - " %c = icmp ugt float* %APtrPlus512, inttoptr (i32 523 to float*)\n" + " %APtr = inttoptr i64 %A to ptr" + " %APtrPlus512 = getelementptr float, ptr %APtr, i32 128\n" + " %c = icmp ugt ptr %APtrPlus512, inttoptr (i32 523 to ptr)\n" " call void @llvm.assume(i1 %c)\n" " ret void\n" "}\n" diff --git a/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp b/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp index 3a5ba9a..dd8826c 100644 --- a/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp +++ b/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp @@ -40,7 +40,7 @@ TEST_F(MsgPackWriter, TestWriteFixPositiveInt) { MPWriter.write(u); std::string Output = OStream.str(); EXPECT_EQ(Output.size(), 1u); - EXPECT_EQ(Output.data()[0], static_cast<uint8_t>(u)); + EXPECT_EQ(Output[0], static_cast<uint8_t>(u)); } } @@ -128,7 +128,7 @@ TEST_F(MsgPackWriter, TestWriteFixNegativeInt) { MPWriter.write(i); std::string Output = OStream.str(); EXPECT_EQ(Output.size(), 1u); - EXPECT_EQ(static_cast<int8_t>(Output.data()[0]), static_cast<int8_t>(i)); + EXPECT_EQ(static_cast<int8_t>(Output[0]), static_cast<int8_t>(i)); } } diff --git a/llvm/unittests/CAS/ActionCacheTest.cpp b/llvm/unittests/CAS/ActionCacheTest.cpp index db67e30..692da23 100644 --- a/llvm/unittests/CAS/ActionCacheTest.cpp +++ b/llvm/unittests/CAS/ActionCacheTest.cpp @@ -21,7 +21,7 @@ using namespace llvm; using namespace llvm::cas; TEST_P(CASTest, ActionCacheHit) { - std::shared_ptr<ObjectStore> CAS = createObjectStore(); + std::unique_ptr<ObjectStore> CAS = createObjectStore(); std::unique_ptr<ActionCache> Cache = createActionCache(); std::optional<ObjectProxy> ID; @@ -36,7 +36,7 @@ TEST_P(CASTest, ActionCacheHit) { } TEST_P(CASTest, ActionCacheMiss) { - std::shared_ptr<ObjectStore> CAS = createObjectStore(); + std::unique_ptr<ObjectStore> CAS = createObjectStore(); std::unique_ptr<ActionCache> Cache = createActionCache(); std::optional<ObjectProxy> ID1, ID2; @@ -59,7 +59,7 @@ TEST_P(CASTest, ActionCacheMiss) { } TEST_P(CASTest, ActionCacheRewrite) { - std::shared_ptr<ObjectStore> CAS = createObjectStore(); + std::unique_ptr<ObjectStore> CAS = createObjectStore(); std::unique_ptr<ActionCache> Cache = createActionCache(); std::optional<ObjectProxy> ID1, ID2; diff --git a/llvm/unittests/CAS/BuiltinUnifiedCASDatabasesTest.cpp b/llvm/unittests/CAS/BuiltinUnifiedCASDatabasesTest.cpp new file mode 100644 index 0000000..19522e9 --- /dev/null +++ b/llvm/unittests/CAS/BuiltinUnifiedCASDatabasesTest.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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/CAS/BuiltinUnifiedCASDatabases.h" +#include "CASTestConfig.h" +#include "llvm/CAS/ActionCache.h" +#include "llvm/CAS/ObjectStore.h" +#include "llvm/Testing/Support/Error.h" +#include "llvm/Testing/Support/SupportHelpers.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::cas; + +TEST_F(OnDiskCASTest, UnifiedCASMaterializationCheckPreventsGarbageCollection) { + unittest::TempDir Temp("on-disk-unified-cas", /*Unique=*/true); + + auto WithCAS = [&](llvm::function_ref<void(ObjectStore &)> Action) { + std::pair<std::unique_ptr<ObjectStore>, std::unique_ptr<ActionCache>> DBs; + ASSERT_THAT_ERROR( + createOnDiskUnifiedCASDatabases(Temp.path()).moveInto(DBs), + Succeeded()); + ObjectStore &CAS = *DBs.first; + ASSERT_THAT_ERROR(CAS.setSizeLimit(1), Succeeded()); + Action(CAS); + }; + + std::optional<CASID> ID; + + // Create an object in the CAS. + WithCAS([&ID](ObjectStore &CAS) { + std::optional<ObjectRef> Ref; + ASSERT_THAT_ERROR(CAS.store({}, "blah").moveInto(Ref), Succeeded()); + ASSERT_TRUE(Ref.has_value()); + + ID = CAS.getID(*Ref); + }); + + // Check materialization and prune the storage. + WithCAS([&ID](ObjectStore &CAS) { + std::optional<ObjectRef> Ref = CAS.getReference(*ID); + ASSERT_TRUE(Ref.has_value()); + + std::optional<bool> IsMaterialized; + ASSERT_THAT_ERROR(CAS.isMaterialized(*Ref).moveInto(IsMaterialized), + Succeeded()); + ASSERT_TRUE(IsMaterialized); + + ASSERT_THAT_ERROR(CAS.pruneStorageData(), Succeeded()); + }); + + // Verify that the previous materialization check kept the object in the CAS. + WithCAS([&ID](ObjectStore &CAS) { + std::optional<ObjectRef> Ref = CAS.getReference(*ID); + ASSERT_TRUE(Ref.has_value()); + + std::optional<bool> IsMaterialized; + ASSERT_THAT_ERROR(CAS.isMaterialized(*Ref).moveInto(IsMaterialized), + Succeeded()); + ASSERT_TRUE(IsMaterialized); + }); +} diff --git a/llvm/unittests/CAS/CASTestConfig.cpp b/llvm/unittests/CAS/CASTestConfig.cpp index 10e4b68..08cbf1d 100644 --- a/llvm/unittests/CAS/CASTestConfig.cpp +++ b/llvm/unittests/CAS/CASTestConfig.cpp @@ -8,6 +8,7 @@ #include "CASTestConfig.h" #include "llvm/CAS/ObjectStore.h" +#include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" #include <mutex> @@ -15,7 +16,8 @@ using namespace llvm; using namespace llvm::cas; static CASTestingEnv createInMemory(int I) { - return CASTestingEnv{createInMemoryCAS(), createInMemoryActionCache()}; + return CASTestingEnv{createInMemoryCAS(), createInMemoryActionCache(), + std::nullopt}; } INSTANTIATE_TEST_SUITE_P(InMemoryCAS, CASTest, @@ -23,7 +25,7 @@ INSTANTIATE_TEST_SUITE_P(InMemoryCAS, CASTest, #if LLVM_ENABLE_ONDISK_CAS namespace llvm::cas::ondisk { -extern void setMaxMappingSize(uint64_t Size); +void setMaxMappingSize(uint64_t Size); } // namespace llvm::cas::ondisk void setMaxOnDiskCASMappingSize() { @@ -31,6 +33,17 @@ void setMaxOnDiskCASMappingSize() { std::call_once( Flag, [] { llvm::cas::ondisk::setMaxMappingSize(100 * 1024 * 1024); }); } + +static CASTestingEnv createOnDisk(int I) { + unittest::TempDir Temp("on-disk-cas", /*Unique=*/true); + std::unique_ptr<ObjectStore> CAS; + EXPECT_THAT_ERROR(createOnDiskCAS(Temp.path()).moveInto(CAS), Succeeded()); + std::unique_ptr<ActionCache> Cache; + EXPECT_THAT_ERROR(createOnDiskActionCache(Temp.path()).moveInto(Cache), + Succeeded()); + return CASTestingEnv{std::move(CAS), std::move(Cache), std::move(Temp)}; +} +INSTANTIATE_TEST_SUITE_P(OnDiskCAS, CASTest, ::testing::Values(createOnDisk)); #else void setMaxOnDiskCASMappingSize() {} #endif /* LLVM_ENABLE_ONDISK_CAS */ diff --git a/llvm/unittests/CAS/CASTestConfig.h b/llvm/unittests/CAS/CASTestConfig.h index 8d3c553..e3139c9 100644 --- a/llvm/unittests/CAS/CASTestConfig.h +++ b/llvm/unittests/CAS/CASTestConfig.h @@ -6,16 +6,33 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_UNITTESTS_CASTESTCONFIG_H +#define LLVM_UNITTESTS_CASTESTCONFIG_H + #include "llvm/CAS/ActionCache.h" #include "llvm/CAS/ObjectStore.h" +#include "llvm/Testing/Support/SupportHelpers.h" #include "gtest/gtest.h" +#include <memory> -#ifndef LLVM_UNITTESTS_CASTESTCONFIG_H -#define LLVM_UNITTESTS_CASTESTCONFIG_H +#ifdef _WIN32 +#include "llvm/Support/VersionTuple.h" +#include "llvm/Support/Windows/WindowsSupport.h" +#endif + +namespace llvm::unittest::cas { +class MockEnv { + void anchor(); + +public: + virtual ~MockEnv(); +}; +} // namespace llvm::unittest::cas struct CASTestingEnv { std::unique_ptr<llvm::cas::ObjectStore> CAS; std::unique_ptr<llvm::cas::ActionCache> Cache; + std::optional<llvm::unittest::TempDir> Temp; }; void setMaxOnDiskCASMappingSize(); @@ -24,26 +41,52 @@ void setMaxOnDiskCASMappingSize(); class OnDiskCASTest : public ::testing::Test { protected: void SetUp() override { +#if !LLVM_ENABLE_ONDISK_CAS + GTEST_SKIP() << "OnDiskCAS is not enabled"; +#endif // Use a smaller database size for testing to conserve disk space. setMaxOnDiskCASMappingSize(); } }; +// Parametered test fixture for ObjectStore and ActionCache tests. class CASTest : public testing::TestWithParam<std::function<CASTestingEnv(int)>> { protected: std::optional<int> NextCASIndex; + llvm::SmallVector<llvm::unittest::TempDir> Dirs; + + llvm::SmallVector<std::unique_ptr<llvm::unittest::cas::MockEnv>> Envs; + std::unique_ptr<llvm::cas::ObjectStore> createObjectStore() { auto TD = GetParam()(++(*NextCASIndex)); + if (TD.Temp) + Dirs.push_back(std::move(*TD.Temp)); return std::move(TD.CAS); } std::unique_ptr<llvm::cas::ActionCache> createActionCache() { auto TD = GetParam()(++(*NextCASIndex)); + if (TD.Temp) + Dirs.push_back(std::move(*TD.Temp)); return std::move(TD.Cache); } - void SetUp() override { NextCASIndex = 0; } - void TearDown() override { NextCASIndex = std::nullopt; } + + 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(); + } + + void TearDown() override { + NextCASIndex = std::nullopt; + Dirs.clear(); + Envs.clear(); + } }; #endif diff --git a/llvm/unittests/CAS/CMakeLists.txt b/llvm/unittests/CAS/CMakeLists.txt index da469f7..91e49be 100644 --- a/llvm/unittests/CAS/CMakeLists.txt +++ b/llvm/unittests/CAS/CMakeLists.txt @@ -1,9 +1,11 @@ set(ONDISK_CAS_TEST_SOURCES + BuiltinUnifiedCASDatabasesTest.cpp OnDiskGraphDBTest.cpp OnDiskDataAllocatorTest.cpp OnDiskKeyValueDBTest.cpp OnDiskTrieRawHashMapTest.cpp ProgramTest.cpp + UnifiedOnDiskCacheTest.cpp ) set(LLVM_OPTIONAL_SOURCES diff --git a/llvm/unittests/CAS/ObjectStoreTest.cpp b/llvm/unittests/CAS/ObjectStoreTest.cpp index 54083fd..b43ae33 100644 --- a/llvm/unittests/CAS/ObjectStoreTest.cpp +++ b/llvm/unittests/CAS/ObjectStoreTest.cpp @@ -1,4 +1,4 @@ -//===- ObjectStoreTest.cpp ------------------------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -76,7 +76,7 @@ multiline text multiline text multiline text multiline text multiline text)", // Run validation on all CASIDs. for (int I = 0, E = IDs.size(); I != E; ++I) - ASSERT_THAT_ERROR(CAS1->validate(IDs[I]), Succeeded()); + ASSERT_THAT_ERROR(CAS1->validateObject(IDs[I]), Succeeded()); // Check that the blobs can be retrieved multiple times. for (int I = 0, E = IDs.size(); I != E; ++I) { @@ -120,15 +120,15 @@ TEST_P(CASTest, BlobsBig) { std::optional<CASID> ID2; ASSERT_THAT_ERROR(CAS->createProxy({}, String1).moveInto(ID1), Succeeded()); ASSERT_THAT_ERROR(CAS->createProxy({}, String1).moveInto(ID2), Succeeded()); - ASSERT_THAT_ERROR(CAS->validate(*ID1), Succeeded()); - ASSERT_THAT_ERROR(CAS->validate(*ID2), Succeeded()); + ASSERT_THAT_ERROR(CAS->validateObject(*ID1), Succeeded()); + ASSERT_THAT_ERROR(CAS->validateObject(*ID2), Succeeded()); ASSERT_EQ(ID1, ID2); String1.append(String2); ASSERT_THAT_ERROR(CAS->createProxy({}, String2).moveInto(ID1), Succeeded()); ASSERT_THAT_ERROR(CAS->createProxy({}, String2).moveInto(ID2), Succeeded()); - ASSERT_THAT_ERROR(CAS->validate(*ID1), Succeeded()); - ASSERT_THAT_ERROR(CAS->validate(*ID2), Succeeded()); + ASSERT_THAT_ERROR(CAS->validateObject(*ID1), Succeeded()); + ASSERT_THAT_ERROR(CAS->validateObject(*ID2), Succeeded()); ASSERT_EQ(ID1, ID2); String2.append(String1); } @@ -176,10 +176,11 @@ multiline text multiline text multiline text multiline text multiline text)", // Check basic printing of IDs. IDs.push_back(CAS1->getID(*Node)); - auto ID = CAS1->getID(Nodes.back()); - EXPECT_EQ(ID.toString(), IDs.back().toString()); - EXPECT_EQ(*Node, Nodes.back()); - EXPECT_EQ(ID, IDs.back()); + EXPECT_EQ(IDs.back().toString(), IDs.back().toString()); + EXPECT_EQ(Nodes.front(), Nodes.front()); + EXPECT_EQ(Nodes.back(), Nodes.back()); + EXPECT_EQ(IDs.front(), IDs.front()); + EXPECT_EQ(IDs.back(), IDs.back()); if (Nodes.size() <= 1) continue; EXPECT_NE(Nodes.front(), Nodes.back()); @@ -266,7 +267,7 @@ TEST_P(CASTest, NodesBig) { } for (auto ID : CreatedNodes) - ASSERT_THAT_ERROR(CAS->validate(CAS->getID(ID)), Succeeded()); + ASSERT_THAT_ERROR(CAS->validateObject(CAS->getID(ID)), Succeeded()); } #if LLVM_ENABLE_THREADS @@ -332,17 +333,124 @@ static void testBlobsParallel1(ObjectStore &CAS, uint64_t BlobSize) { } TEST_P(CASTest, BlobsParallel) { - std::shared_ptr<ObjectStore> CAS = createObjectStore(); + std::unique_ptr<ObjectStore> CAS = createObjectStore(); uint64_t Size = 1ULL * 1024; ASSERT_NO_FATAL_FAILURE(testBlobsParallel1(*CAS, Size)); } #ifdef EXPENSIVE_CHECKS TEST_P(CASTest, BlobsBigParallel) { - std::shared_ptr<ObjectStore> CAS = createObjectStore(); + std::unique_ptr<ObjectStore> CAS = createObjectStore(); // 100k is large enough to be standalone files in our on-disk cas. uint64_t Size = 100ULL * 1024; ASSERT_NO_FATAL_FAILURE(testBlobsParallel1(*CAS, Size)); } #endif // EXPENSIVE_CHECKS + +#ifndef _WIN32 // create_link won't work for directories on Windows +TEST_F(OnDiskCASTest, OnDiskCASBlobsParallelMultiCAS) { + // This test intentionally uses symlinked paths to the same CAS to subvert the + // shared memory mappings that would normally be created within a single + // process. This breaks the lock file guarantees, so we must be careful not + // to create or destroy the CAS objects concurrently, which is when the locks + // are normally important. + unittest::TempDir Temp("on-disk-cas", /*Unique=*/true); + ASSERT_EQ(sys::fs::create_directory(Temp.path("real_cas")), + std::error_code()); + ASSERT_EQ(sys::fs::create_link("real_cas", Temp.path("sym_cas1")), + std::error_code()); + ASSERT_EQ(sys::fs::create_link("real_cas", Temp.path("sym_cas2")), + std::error_code()); + ASSERT_EQ(sys::fs::create_link("real_cas", Temp.path("sym_cas3")), + std::error_code()); + + std::unique_ptr<ObjectStore> CAS1, CAS2, CAS3, CAS4; + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("real_cas")).moveInto(CAS1), + Succeeded()); + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("sym_cas1")).moveInto(CAS2), + Succeeded()); + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("sym_cas2")).moveInto(CAS3), + Succeeded()); + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("sym_cas3")).moveInto(CAS4), + Succeeded()); + + uint64_t Size = 1ULL * 1024; + ASSERT_NO_FATAL_FAILURE(testBlobsParallel(*CAS1, *CAS2, *CAS3, *CAS4, Size)); +} + +TEST_F(OnDiskCASTest, OnDiskCASBlobsBigParallelMultiCAS) { + // See comment in BlobsParallelMultiCAS. + unittest::TempDir Temp("on-disk-cas", /*Unique=*/true); + ASSERT_EQ(sys::fs::create_directory(Temp.path("real_cas")), + std::error_code()); + ASSERT_EQ(sys::fs::create_link("real_cas", Temp.path("sym_cas1")), + std::error_code()); + ASSERT_EQ(sys::fs::create_link("real_cas", Temp.path("sym_cas2")), + std::error_code()); + ASSERT_EQ(sys::fs::create_link("real_cas", Temp.path("sym_cas3")), + std::error_code()); + + std::unique_ptr<ObjectStore> CAS1, CAS2, CAS3, CAS4; + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("real_cas")).moveInto(CAS1), + Succeeded()); + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("sym_cas1")).moveInto(CAS2), + Succeeded()); + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("sym_cas2")).moveInto(CAS3), + Succeeded()); + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path("sym_cas3")).moveInto(CAS4), + Succeeded()); + + // 100k is large enough to be standalone files in our on-disk cas. + uint64_t Size = 100ULL * 1024; + ASSERT_NO_FATAL_FAILURE(testBlobsParallel(*CAS1, *CAS2, *CAS3, *CAS4, Size)); +} +#endif // _WIN32 #endif // LLVM_ENABLE_THREADS + +TEST_F(OnDiskCASTest, OnDiskCASDiskSize) { + unittest::TempDir Temp("on-disk-cas", /*Unique=*/true); + std::unique_ptr<ObjectStore> CAS; + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path()).moveInto(CAS), Succeeded()); + + uint64_t MaxSize = 100 * 1024 * 1024; + + // Check that we map the files to the correct size. + auto CheckFileSizes = [&](bool Mapped) { + bool FoundIndex = false, FoundData = false; + std::error_code EC; + for (sys::fs::directory_iterator I(Temp.path(), EC), E; I != E && !EC; + I.increment(EC)) { + StringRef Filename = sys::path::filename(I->path()); + if (Filename.starts_with("index.") && !Filename.ends_with(".shared")) { + FoundIndex = true; + ASSERT_TRUE(I->status()); + if (Mapped) + EXPECT_EQ(I->status()->getSize(), MaxSize); + else + EXPECT_LT(I->status()->getSize(), MaxSize); + } + if (Filename.starts_with("data.") && !Filename.ends_with(".shared")) { + FoundData = true; + ASSERT_TRUE(I->status()); + if (Mapped) + EXPECT_EQ(I->status()->getSize(), MaxSize); + else + EXPECT_LT(I->status()->getSize(), MaxSize); + } + } + ASSERT_TRUE(FoundIndex); + ASSERT_TRUE(FoundData); + }; + + // Check that we have the full mapping size when the CAS is open. + CheckFileSizes(/*Mapped=*/true); + CAS.reset(); + // Check that the CAS is shrunk to a smaller size. + CheckFileSizes(/*Mapped=*/false); + + // Repeat the checks when starting from an existing CAS. + ASSERT_THAT_ERROR(createOnDiskCAS(Temp.path()).moveInto(CAS), Succeeded()); + CheckFileSizes(/*Mapped=*/true); + CAS.reset(); + CheckFileSizes(/*Mapped=*/false); +} diff --git a/llvm/unittests/CAS/OnDiskCommonUtils.h b/llvm/unittests/CAS/OnDiskCommonUtils.h index 89f93e0..48a1830 100644 --- a/llvm/unittests/CAS/OnDiskCommonUtils.h +++ b/llvm/unittests/CAS/OnDiskCommonUtils.h @@ -12,6 +12,8 @@ #include "llvm/CAS/BuiltinObjectHasher.h" #include "llvm/CAS/OnDiskGraphDB.h" +#include "llvm/CAS/OnDiskKeyValueDB.h" +#include "llvm/CAS/UnifiedOnDiskCache.h" #include "llvm/Support/BLAKE3.h" #include "llvm/Testing/Support/Error.h" @@ -58,6 +60,25 @@ inline Expected<ObjectID> store(OnDiskGraphDB &DB, StringRef Data, return ID; } +inline Expected<ObjectID> cachePut(OnDiskKeyValueDB &DB, ArrayRef<uint8_t> Key, + ObjectID ID) { + auto Value = UnifiedOnDiskCache::getValueFromObjectID(ID); + auto Result = DB.put(Key, Value); + if (!Result) + return Result.takeError(); + return UnifiedOnDiskCache::getObjectIDFromValue(*Result); +} + +inline Expected<std::optional<ObjectID>> cacheGet(OnDiskKeyValueDB &DB, + ArrayRef<uint8_t> Key) { + auto Result = DB.get(Key); + if (!Result) + return Result.takeError(); + if (!*Result) + return std::nullopt; + return UnifiedOnDiskCache::getObjectIDFromValue(**Result); +} + inline Error printTree(OnDiskGraphDB &DB, ObjectID ID, raw_ostream &OS, unsigned Indent = 0) { std::optional<ondisk::ObjectHandle> Obj; diff --git a/llvm/unittests/CAS/OnDiskGraphDBTest.cpp b/llvm/unittests/CAS/OnDiskGraphDBTest.cpp index 3c2e963..e9c73bf 100644 --- a/llvm/unittests/CAS/OnDiskGraphDBTest.cpp +++ b/llvm/unittests/CAS/OnDiskGraphDBTest.cpp @@ -102,7 +102,7 @@ TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInSingleNode) { std::unique_ptr<OnDiskGraphDB> DB; ASSERT_THAT_ERROR( OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType), - std::move(UpstreamDB), + UpstreamDB.get(), OnDiskGraphDB::FaultInPolicy::SingleNode) .moveInto(DB), Succeeded()); @@ -208,7 +208,7 @@ TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInFullTree) { unittest::TempDir Temp("ondiskcas", /*Unique=*/true); std::unique_ptr<OnDiskGraphDB> DB; ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType), - std::move(UpstreamDB), + UpstreamDB.get(), OnDiskGraphDB::FaultInPolicy::FullTree) .moveInto(DB), Succeeded()); @@ -264,14 +264,14 @@ TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInPolicyConflict) { unittest::TempDir Temp("ondiskcas", /*Unique=*/true); std::unique_ptr<OnDiskGraphDB> DB; ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3", - sizeof(HashType), - std::move(UpstreamDB), Policy1) + sizeof(HashType), UpstreamDB.get(), + Policy1) .moveInto(DB), Succeeded()); DB.reset(); ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3", - sizeof(HashType), - std::move(UpstreamDB), Policy2) + sizeof(HashType), UpstreamDB.get(), + Policy2) .moveInto(DB), Failed()); }; diff --git a/llvm/unittests/CAS/UnifiedOnDiskCacheTest.cpp b/llvm/unittests/CAS/UnifiedOnDiskCacheTest.cpp new file mode 100644 index 0000000..09aebc2 --- /dev/null +++ b/llvm/unittests/CAS/UnifiedOnDiskCacheTest.cpp @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// 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/CAS/UnifiedOnDiskCache.h" +#include "CASTestConfig.h" +#include "OnDiskCommonUtils.h" +#include "llvm/Testing/Support/Error.h" +#include "llvm/Testing/Support/SupportHelpers.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::cas; +using namespace llvm::cas::ondisk; +using namespace llvm::unittest::cas; + +/// Visits all the files of a directory recursively and returns the sum of their +/// sizes. +static Expected<size_t> countFileSizes(StringRef Path) { + size_t TotalSize = 0; + std::error_code EC; + for (sys::fs::directory_iterator DirI(Path, EC), DirE; !EC && DirI != DirE; + DirI.increment(EC)) { + if (DirI->type() == sys::fs::file_type::directory_file) { + Expected<size_t> Subsize = countFileSizes(DirI->path()); + if (!Subsize) + return Subsize.takeError(); + TotalSize += *Subsize; + continue; + } + ErrorOr<sys::fs::basic_file_status> Stat = DirI->status(); + if (!Stat) + return createFileError(DirI->path(), Stat.getError()); + TotalSize += Stat->getSize(); + } + if (EC) + return createFileError(Path, EC); + return TotalSize; +} + +TEST_F(OnDiskCASTest, UnifiedOnDiskCacheTest) { + unittest::TempDir Temp("ondisk-unified", /*Unique=*/true); + std::unique_ptr<UnifiedOnDiskCache> UniDB; + + const uint64_t SizeLimit = 1024ull * 64; + auto reopenDB = [&]() { + UniDB.reset(); + ASSERT_THAT_ERROR(UnifiedOnDiskCache::open(Temp.path(), SizeLimit, "blake3", + sizeof(HashType)) + .moveInto(UniDB), + Succeeded()); + }; + + reopenDB(); + + HashType RootHash; + HashType OtherHash; + HashType Key1Hash; + HashType Key2Hash; + { + OnDiskGraphDB &DB = UniDB->getGraphDB(); + std::optional<ObjectID> ID1; + ASSERT_THAT_ERROR(store(DB, "1", {}).moveInto(ID1), Succeeded()); + std::optional<ObjectID> ID2; + ASSERT_THAT_ERROR(store(DB, "2", {}).moveInto(ID2), Succeeded()); + std::optional<ObjectID> IDRoot; + ASSERT_THAT_ERROR(store(DB, "root", {*ID1, *ID2}).moveInto(IDRoot), + Succeeded()); + ArrayRef<uint8_t> Digest = DB.getDigest(*IDRoot); + ASSERT_EQ(Digest.size(), RootHash.size()); + llvm::copy(Digest, RootHash.data()); + + std::optional<ObjectID> IDOther; + ASSERT_THAT_ERROR(store(DB, "other", {}).moveInto(IDOther), Succeeded()); + Digest = DB.getDigest(*IDOther); + ASSERT_EQ(Digest.size(), OtherHash.size()); + llvm::copy(Digest, OtherHash.data()); + + Key1Hash = digest("key1"); + std::optional<ObjectID> Val; + ASSERT_THAT_ERROR( + cachePut(UniDB->getKeyValueDB(), Key1Hash, *IDRoot).moveInto(Val), + Succeeded()); + EXPECT_EQ(IDRoot, Val); + + Key2Hash = digest("key2"); + std::optional<ObjectID> KeyID; + ASSERT_THAT_ERROR(DB.getReference(Key2Hash).moveInto(KeyID), Succeeded()); + ASSERT_THAT_ERROR(cachePut(UniDB->getKeyValueDB(), + UniDB->getGraphDB().getDigest(*KeyID), *ID1) + .moveInto(Val), + Succeeded()); + } + + auto checkTree = [&](const HashType &Digest, StringRef ExpectedTree) { + OnDiskGraphDB &DB = UniDB->getGraphDB(); + std::optional<ObjectID> ID; + ASSERT_THAT_ERROR(DB.getReference(Digest).moveInto(ID), Succeeded()); + std::string PrintedTree; + raw_string_ostream OS(PrintedTree); + ASSERT_THAT_ERROR(printTree(DB, *ID, OS), Succeeded()); + EXPECT_EQ(PrintedTree, ExpectedTree); + }; + auto checkRootTree = [&]() { + return checkTree(RootHash, "root\n 1\n 2\n"); + }; + + auto checkKey = [&](const HashType &Key, StringRef ExpectedData) { + OnDiskGraphDB &DB = UniDB->getGraphDB(); + std::optional<ObjectID> Val; + ASSERT_THAT_ERROR(cacheGet(UniDB->getKeyValueDB(), Key).moveInto(Val), + Succeeded()); + + ASSERT_TRUE(Val.has_value()); + std::optional<ondisk::ObjectHandle> Obj; + ASSERT_THAT_ERROR(DB.load(*Val).moveInto(Obj), Succeeded()); + EXPECT_EQ(toStringRef(DB.getObjectData(*Obj)), ExpectedData); + }; + + checkRootTree(); + checkTree(OtherHash, "other\n"); + checkKey(Key1Hash, "root"); + checkKey(Key2Hash, "1"); + + auto storeBigObject = [&](unsigned Index) { + SmallString<1000> Buf; + Buf.append(970, 'a'); + raw_svector_ostream(Buf) << Index; + std::optional<ObjectID> ID; + ASSERT_THAT_ERROR(store(UniDB->getGraphDB(), Buf, {}).moveInto(ID), + Succeeded()); + }; + + uint64_t PrevStoreSize = UniDB->getStorageSize(); + unsigned Index = 0; + while (!UniDB->hasExceededSizeLimit()) { + storeBigObject(Index++); + } + EXPECT_GT(UniDB->getStorageSize(), PrevStoreSize); + UniDB->setSizeLimit(SizeLimit * 2); + EXPECT_FALSE(UniDB->hasExceededSizeLimit()); + UniDB->setSizeLimit(SizeLimit); + EXPECT_TRUE(UniDB->hasExceededSizeLimit()); + + reopenDB(); + + EXPECT_FALSE(UniDB->hasExceededSizeLimit()); + EXPECT_FALSE(UniDB->needsGarbageCollection()); + + checkRootTree(); + checkKey(Key1Hash, "root"); + + while (!UniDB->hasExceededSizeLimit()) { + storeBigObject(Index++); + } + PrevStoreSize = UniDB->getStorageSize(); + ASSERT_THAT_ERROR(UniDB->close(), Succeeded()); + EXPECT_TRUE(UniDB->needsGarbageCollection()); + + reopenDB(); + EXPECT_TRUE(UniDB->needsGarbageCollection()); + + std::optional<size_t> DirSizeBefore; + ASSERT_THAT_ERROR(countFileSizes(Temp.path()).moveInto(DirSizeBefore), + Succeeded()); + + ASSERT_THAT_ERROR(UnifiedOnDiskCache::collectGarbage(Temp.path()), + Succeeded()); + + std::optional<size_t> DirSizeAfter; + ASSERT_THAT_ERROR(countFileSizes(Temp.path()).moveInto(DirSizeAfter), + Succeeded()); + EXPECT_LT(*DirSizeAfter, *DirSizeBefore); + + reopenDB(); + EXPECT_FALSE(UniDB->needsGarbageCollection()); + + checkRootTree(); + checkKey(Key1Hash, "root"); + + EXPECT_LT(UniDB->getStorageSize(), PrevStoreSize); + + // 'Other' tree and 'Key2' got garbage-collected. + { + OnDiskGraphDB &DB = UniDB->getGraphDB(); + std::optional<ObjectID> ID; + ASSERT_THAT_ERROR(DB.getReference(OtherHash).moveInto(ID), Succeeded()); + EXPECT_FALSE(DB.containsObject(*ID)); + std::optional<ObjectID> Val; + ASSERT_THAT_ERROR(cacheGet(UniDB->getKeyValueDB(), Key2Hash).moveInto(Val), + Succeeded()); + EXPECT_FALSE(Val.has_value()); + } +} diff --git a/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp b/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp index af2d56d..d0991e6 100644 --- a/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp +++ b/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp @@ -383,7 +383,7 @@ class AsmPrinterHandlerTest : public AsmPrinterFixtureBase { public: TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {} - ~TestHandler() override {} + ~TestHandler() override = default; void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {} void beginModule(Module *M) override { Test.BeginCount++; } void endModule() override { Test.EndCount++; } diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt index 18332d2..80d1013 100644 --- a/llvm/unittests/CodeGen/CMakeLists.txt +++ b/llvm/unittests/CodeGen/CMakeLists.txt @@ -39,6 +39,7 @@ add_llvm_unittest(CodeGenTests MachineOperandTest.cpp MIR2VecTest.cpp RegAllocScoreTest.cpp + RegisterTest.cpp PassManagerTest.cpp ScalableVectorMVTsTest.cpp SchedBoundary.cpp @@ -48,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 ff87e7b..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); @@ -1113,7 +1113,7 @@ TEST_F(InstrRefLDVTest, MLocDiamondSpills) { // Create a stack location and ensure it's tracked. SpillLoc SL = {getRegByName("RSP"), StackOffset::getFixed(-8)}; SpillLocationNo SpillNo = *MTracker->getOrTrackSpillLoc(SL); - ASSERT_EQ(MTracker->getNumLocs(), 13u); // Tracks all possible stack locs. + ASSERT_EQ(MTracker->getNumLocs(), 11u); // Tracks all possible stack locs. // Locations are: RSP, stack slots from 2^3 bits wide up to 2^9 for zmm regs, // then slots for sub_8bit_hi and sub_16bit_hi ({8, 8} and {16, 16}). // Finally, one for spilt fp80 registers. @@ -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 a86a68c..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]; } @@ -76,8 +77,10 @@ public: }; class BogusTargetInstrInfo : public TargetInstrInfo { + BogusRegisterInfo RegInfo; + public: - BogusTargetInstrInfo() : TargetInstrInfo() {} + BogusTargetInstrInfo() : TargetInstrInfo(RegInfo) {} }; class BogusSubtarget : public TargetSubtargetInfo { @@ -85,8 +88,8 @@ public: BogusSubtarget(TargetMachine &TM) : TargetSubtargetInfo(Triple(""), "", "", "", {}, {}, {}, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr), - FL(), TL(TM) {} - ~BogusSubtarget() override {} + FL(), TL(TM, *this) {} + ~BogusSubtarget() override = default; const TargetFrameLowering *getFrameLowering() const override { return &FL; } @@ -117,7 +120,7 @@ public: Reloc::Static, CodeModel::Small, CodeGenOptLevel::Default), ST(*this) {} - ~BogusTargetMachine() override {} + ~BogusTargetMachine() override = default; const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override { return &ST; 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 3f3f48f..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; @@ -424,4 +441,24 @@ TEST(MachineOperandTest, HashValue) { ASSERT_TRUE(MO1.isIdenticalTo(MO2)); } +TEST(MachineOperandTest, RegisterLiveOutHashValue) { + LLVMContext Ctx; + Module Mod("Module", Ctx); + auto MF = createMachineFunction(Ctx, Mod); + MachineBasicBlock *MBB = MF->CreateMachineBasicBlock(); + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + auto *MI1 = MF->CreateMachineInstr(MCID, DebugLoc()); + auto *MI2 = MF->CreateMachineInstr(MCID, DebugLoc()); + MBB->insert(MBB->begin(), MI1); + MBB->insert(MBB->begin(), MI2); + uint32_t Mask1 = 0; + uint32_t Mask2 = 0; + MI1->addOperand(*MF, MachineOperand::CreateRegLiveOut(&Mask1)); + MI2->addOperand(*MF, MachineOperand::CreateRegLiveOut(&Mask2)); + auto MO1 = MI1->getOperand(0); + auto MO2 = MI2->getOperand(0); + EXPECT_EQ(hash_value(MO1), hash_value(MO2)); + EXPECT_TRUE(MO1.isIdenticalTo(MO2)); +} + } // end namespace diff --git a/llvm/unittests/CodeGen/RegisterTest.cpp b/llvm/unittests/CodeGen/RegisterTest.cpp new file mode 100644 index 0000000..db2747c --- /dev/null +++ b/llvm/unittests/CodeGen/RegisterTest.cpp @@ -0,0 +1,38 @@ +//===- RegisterTest.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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/Register.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { +TEST(RegisterTest, Idx2StackSlot) { + EXPECT_EQ(Register::index2StackSlot(0), Register::StackSlotZero); + EXPECT_EQ(Register::index2StackSlot(1), Register::StackSlotZero | 1); + EXPECT_EQ(Register::index2StackSlot(-1), + Register::StackSlotZero | Register::StackSlotMask); + int MaxPowOf2 = 1 << (Register::MaxFrameIndexBitwidth - 1); + // Check the highest possible value of frame index + EXPECT_EQ(Register::index2StackSlot(MaxPowOf2 - 1), + Register::StackSlotZero | (MaxPowOf2 - 1)); + // Check the lowest possible value of frame index + EXPECT_EQ(Register::index2StackSlot(-MaxPowOf2), + Register::StackSlotZero | (-MaxPowOf2 & Register::StackSlotMask)); +} + +TEST(RegisterTest, StackSlotIndex) { + int MaxPowOf2 = 1 << (Register::MaxFrameIndexBitwidth - 1); + std::vector<int> FIs = {0, 1 - 1, MaxPowOf2 - 1, -MaxPowOf2}; + + for (int FI : FIs) { + Register Reg = Register::index2StackSlot(FI); + EXPECT_EQ(Reg.stackSlotIndex(), FI); + } +} +} // end namespace 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/CodeView/RandomAccessVisitorTest.cpp b/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp index 5c96199..fab40b9 100644 --- a/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp +++ b/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp @@ -84,7 +84,7 @@ public: class RandomAccessVisitorTest : public testing::Test { public: - RandomAccessVisitorTest() {} + RandomAccessVisitorTest() = default; static void SetUpTestCase() { GlobalState = std::make_unique<GlobalTestState>(); diff --git a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp index b1f19e9..62b7591 100644 --- a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp +++ b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp @@ -21,7 +21,7 @@ using namespace llvm::codeview; class TypeIndexIteratorTest : public testing::Test { public: - TypeIndexIteratorTest() {} + TypeIndexIteratorTest() = default; void SetUp() override { Refs.clear(); diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp index 2fe5260..aa5b292 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp @@ -864,7 +864,7 @@ TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) { } struct AdjustAddressFixtureBase : public CommonFixture { - virtual ~AdjustAddressFixtureBase() {} + virtual ~AdjustAddressFixtureBase() = default; // Create and update the prologue as specified by the subclass, then return // the length of the table. diff --git a/llvm/unittests/DebugInfo/LogicalView/StringPoolTest.cpp b/llvm/unittests/DebugInfo/LogicalView/StringPoolTest.cpp index 27ff449c..e4dc77b 100644 --- a/llvm/unittests/DebugInfo/LogicalView/StringPoolTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/StringPoolTest.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/LogicalView/Core/LVStringPool.h" -#include <vector> #include "gtest/gtest.h" diff --git a/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp b/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp index b010b5fc..20ae253 100644 --- a/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp +++ b/llvm/unittests/DebugInfo/PDB/NativeSessionTest.cpp @@ -19,8 +19,6 @@ #include "gtest/gtest.h" -#include <vector> - using namespace llvm; using namespace llvm::pdb; @@ -42,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/JITLink/JITLinkTestUtils.h b/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h index f03c82f..a2732e3 100644 --- a/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h +++ b/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.h @@ -19,7 +19,7 @@ class MockJITLinkMemoryManager : public llvm::jitlink::JITLinkMemoryManager { public: class Alloc { public: - virtual ~Alloc() {} + virtual ~Alloc() = default; }; class SimpleAlloc : public Alloc { 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 b06aa25..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 @@ -26,6 +28,7 @@ add_llvm_unittest(OrcJITTests IndirectionUtilsTest.cpp JITTargetMachineBuilderTest.cpp LazyCallThroughAndReexportsTest.cpp + LibraryResolverTest.cpp LookupAndRecordAddrsTest.cpp MachOPlatformTest.cpp MapperJITLinkMemoryManagerTest.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/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index ec94083..13070e8 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -15,7 +15,6 @@ #include "llvm/Testing/Support/Error.h" #include <deque> -#include <set> #include <thread> using namespace llvm; diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml new file mode 100644 index 0000000..afd1d9e --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml @@ -0,0 +1,460 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .rela.plt + Align: 0x1000 + Offset: 0x0 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .init + LastSec: .fini + VAddr: 0x1000 + Align: 0x1000 + Offset: 0x1000 + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .rodata + LastSec: .eh_frame + VAddr: 0x2000 + Align: 0x1000 + Offset: 0x2000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .init_array + LastSec: .bss + VAddr: 0x3E10 + Align: 0x1000 + Offset: 0x2E10 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .dynamic + VAddr: 0x3E20 + Align: 0x8 + Offset: 0x2E20 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.build-id + LastSec: .note.gnu.build-id + VAddr: 0x2C8 + Align: 0x4 + Offset: 0x2C8 + - Type: PT_GNU_PROPERTY + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + VAddr: 0x2010 + Align: 0x4 + Offset: 0x2010 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x10 + Offset: 0x0 + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + FirstSec: .init_array + LastSec: .got + VAddr: 0x3E10 + Offset: 0x2E10 +Sections: + - Name: .note.gnu.property + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2A8 + AddressAlign: 0x8 + Notes: + - Name: GNU + Desc: 020000C0040000000300000000000000 + Type: NT_GNU_PROPERTY_TYPE_0 + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2C8 + AddressAlign: 0x4 + Notes: + - Name: GNU + Desc: 73604396C95840D5C380A0950F085A778F94EE7C + Type: NT_PRPSINFO + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x2F0 + Link: .dynsym + AddressAlign: 0x8 + Header: + SymNdx: 0x6 + Shift2: 0x6 + BloomFilter: [ 0x400000080000 ] + HashBuckets: [ 0x0, 0x6 ] + HashValues: [ 0x7C9DCB93 ] + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x318 + Link: .dynstr + AddressAlign: 0x8 + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x3C0 + AddressAlign: 0x1 + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x436 + Link: .dynsym + AddressAlign: 0x2 + Entries: [ 0, 1, 2, 1, 1, 2, 1 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x448 + Link: .dynstr + AddressAlign: 0x8 + Dependencies: + - Version: 1 + File: libc.so.6 + Entries: + - Name: GLIBC_2.2.5 + Hash: 157882997 + Flags: 0 + Other: 2 + - Name: .rela.dyn + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Address: 0x468 + Link: .dynsym + AddressAlign: 0x8 + Relocations: + - Offset: 0x3E10 + Type: R_X86_64_RELATIVE + Addend: 4368 + - Offset: 0x3E18 + Type: R_X86_64_RELATIVE + Addend: 4304 + - Offset: 0x4020 + Type: R_X86_64_RELATIVE + Addend: 16416 + - Offset: 0x3FE0 + Symbol: _ITM_deregisterTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FE8 + Symbol: __gmon_start__ + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF0 + Symbol: _ITM_registerTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF8 + Symbol: __cxa_finalize + Type: R_X86_64_GLOB_DAT + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x510 + Link: .dynsym + AddressAlign: 0x8 + Info: .got.plt + Relocations: + - Offset: 0x4018 + Symbol: puts + Type: R_X86_64_JUMP_SLOT + - Name: .init + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x4 + Offset: 0x1000 + Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1020 + AddressAlign: 0x10 + EntSize: 0x10 + Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90 + - Name: .plt.got + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1040 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25AD2F00000F1F440000 + - Name: .plt.sec + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1050 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25BD2F00000F1F440000 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1060 + AddressAlign: 0x10 + Content: 488D3DC12F0000488D05BA2F00004839F87415488B05662F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D912F0000488D358A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05352F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D4D2F000000752B5548833D122F0000004889E5740C488B3D2E2F0000E849FFFFFFE864FFFFFFC605252F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5488D05D80E00004889C7E820FFFFFF905DC3 + - Name: .fini + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1134 + AddressAlign: 0x4 + Content: F30F1EFA4883EC084883C408C3 + - Name: .rodata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + AddressAlign: 0x1 + Offset: 0x2000 + Content: 48656C6C6F2066726F6D204100 + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2010 + AddressAlign: 0x4 + Content: 011B033B2C0000000400000010F0FFFF4800000030F0FFFF7000000040F0FFFF8800000009F1FFFFA0000000 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2040 + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000C0EFFFFF20000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000B8EFFFFF100000000000000000000000140000005C000000B0EFFFFF1000000000000000000000001C0000007400000061F0FFFF1A00000000450E108602430D06510C070800000000000000 + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E10 + AddressAlign: 0x8 + EntSize: 0x8 + Offset: 0x2E10 + Content: '1011000000000000' + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E18 + AddressAlign: 0x8 + EntSize: 0x8 + Content: D010000000000000 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E20 + Link: .dynstr + AddressAlign: 0x8 + Entries: + - Tag: DT_NEEDED + Value: 0x5F + - Tag: DT_INIT + Value: 0x1000 + - Tag: DT_FINI + Value: 0x1134 + - Tag: DT_INIT_ARRAY + Value: 0x3E10 + - Tag: DT_INIT_ARRAYSZ + Value: 0x8 + - Tag: DT_FINI_ARRAY + Value: 0x3E18 + - Tag: DT_FINI_ARRAYSZ + Value: 0x8 + - Tag: DT_GNU_HASH + Value: 0x2F0 + - Tag: DT_STRTAB + Value: 0x3C0 + - Tag: DT_SYMTAB + Value: 0x318 + - Tag: DT_STRSZ + Value: 0x75 + - Tag: DT_SYMENT + Value: 0x18 + - Tag: DT_PLTGOT + Value: 0x4000 + - Tag: DT_PLTRELSZ + Value: 0x18 + - Tag: DT_PLTREL + Value: 0x7 + - Tag: DT_JMPREL + Value: 0x510 + - Tag: DT_RELA + Value: 0x468 + - Tag: DT_RELASZ + Value: 0xA8 + - Tag: DT_RELAENT + Value: 0x18 + - Tag: DT_VERNEED + Value: 0x448 + - Tag: DT_VERNEEDNUM + Value: 0x1 + - Tag: DT_VERSYM + Value: 0x436 + - Tag: DT_RELACOUNT + Value: 0x3 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3FE0 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '0000000000000000000000000000000000000000000000000000000000000000' + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4000 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '203E000000000000000000000000000000000000000000003010000000000000' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4020 + AddressAlign: 0x8 + Content: '2040000000000000' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4028 + AddressAlign: 0x1 + Size: 0x8 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000 +Symbols: + - Name: crtstuff.c + Type: STT_FILE + Index: SHN_ABS + - Name: deregister_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1060 + - Name: register_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1090 + - Name: __do_global_dtors_aux + Type: STT_FUNC + Section: .text + Value: 0x10D0 + - Name: completed.0 + Type: STT_OBJECT + Section: .bss + Value: 0x4028 + Size: 0x1 + - Name: __do_global_dtors_aux_fini_array_entry + Type: STT_OBJECT + Section: .fini_array + Value: 0x3E18 + - Name: frame_dummy + Type: STT_FUNC + Section: .text + Value: 0x1110 + - Name: __frame_dummy_init_array_entry + Type: STT_OBJECT + Section: .init_array + Value: 0x3E10 + - Name: libA.c + Type: STT_FILE + Index: SHN_ABS + - Name: 'crtstuff.c (1)' + Type: STT_FILE + Index: SHN_ABS + - Name: __FRAME_END__ + Type: STT_OBJECT + Section: .eh_frame + Value: 0x20D0 + - Type: STT_FILE + Index: SHN_ABS + - Name: _fini + Type: STT_FUNC + Section: .fini + Value: 0x1134 + - Name: __dso_handle + Type: STT_OBJECT + Section: .data + Value: 0x4020 + - Name: _DYNAMIC + Type: STT_OBJECT + Section: .dynamic + Value: 0x3E20 + - Name: __GNU_EH_FRAME_HDR + Section: .eh_frame_hdr + Value: 0x2010 + - Name: __TMC_END__ + Type: STT_OBJECT + Section: .data + Value: 0x4028 + - Name: _GLOBAL_OFFSET_TABLE_ + Type: STT_OBJECT + Section: .got.plt + Value: 0x4000 + - Name: _init + Type: STT_FUNC + Section: .init + Value: 0x1000 + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: 'puts@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: sayA + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1119 + Size: 0x1A + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: '__cxa_finalize@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_WEAK +DynamicSymbols: + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: puts + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: __cxa_finalize + Type: STT_FUNC + Binding: STB_WEAK + - Name: sayA + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1119 + Size: 0x1A +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml new file mode 100644 index 0000000..2e851a90 --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml @@ -0,0 +1,723 @@ +--- !fat-mach-o +FatHeader: + magic: 0xCAFEBABE + nfat_arch: 3 +FatArchs: + - cputype: 0x1000007 + cpusubtype: 0x3 + offset: 0x1000 + size: 8376 + align: 12 + - cputype: 0x100000C + cpusubtype: 0x0 + offset: 0x4000 + size: 33376 + align: 14 + - cputype: 0x100000C + cpusubtype: 0x80000002 + offset: 0x10000 + size: 33376 + align: 14 +Slices: + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x6 + ncmds: 14 + sizeofcmds: 960 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0xF80 + size: 20 + offset: 0xF80 + align: 4 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 554889E5488D3D0F000000B000E8020000005DC3 + - sectname: __stubs + segname: __TEXT + addr: 0xF94 + size: 6 + offset: 0xF94 + align: 1 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x6 + reserved3: 0x0 + content: FF2566000000 + - sectname: __cstring + segname: __TEXT + addr: 0xF9A + size: 14 + offset: 0xF9A + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D20410A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0xFA8 + size: 88 + offset: 0xFA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000800F00004000000040000000940F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 4096 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x1000 + size: 8 + offset: 0x1000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 184 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libA.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 8192 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 8288 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8320 + nsyms: 2 + stroff: 8360 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 8352 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: ADFFA141-C3EE-37CD-B1E7-906D69F81BCB + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 8312 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 8320 + datasize: 0 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayA + Flags: 0x0 + Address: 0xF80 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 3968 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayA + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0xF80 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 976 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F70 + size: 28 + offset: 0x3F70 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6 + - sectname: __stubs + segname: __TEXT + addr: 0x3F8C + size: 12 + offset: 0x3F8C + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0xC + reserved3: 0x0 + content: 100000B0100240F900021FD6 + - sectname: __cstring + segname: __TEXT + addr: 0x3F98 + size: 14 + offset: 0x3F98 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D20410A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000703F000040000000400000008C3F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x4000 + size: 8 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 608 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libA.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32864 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32896 + nsyms: 2 + stroff: 32936 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32928 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: C45227E0-C6C0-3137-969B-36AABF9D5487 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32888 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32896 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 32960 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayA + Flags: 0x0 + Address: 0x3F70 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16240 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayA + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0x3F70 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x80000002 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 976 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F68 + size: 32 + offset: 0x3F68 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 7F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6 + - sectname: __auth_stubs + segname: __TEXT + addr: 0x3F88 + size: 16 + offset: 0x3F88 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x10 + reserved3: 0x0 + content: 110000B031020091300240F9110A1FD7 + - sectname: __cstring + segname: __TEXT + addr: 0x3F98 + size: 14 + offset: 0x3F98 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D20410A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000883F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __auth_got + segname: __DATA_CONST + addr: 0x4000 + size: 8 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: 00000000000001C0 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 608 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libA.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32864 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32896 + nsyms: 2 + stroff: 32936 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32928 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: C9DC00C2-E721-365C-9C2D-E9FDB7C838BB + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32888 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32896 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 32960 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayA + Flags: 0x0 + Address: 0x3F68 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16232 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayA + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0x3F68 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml new file mode 100644 index 0000000..fe4393e --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml @@ -0,0 +1,460 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .rela.plt + Align: 0x1000 + Offset: 0x0 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .init + LastSec: .fini + VAddr: 0x1000 + Align: 0x1000 + Offset: 0x1000 + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .rodata + LastSec: .eh_frame + VAddr: 0x2000 + Align: 0x1000 + Offset: 0x2000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .init_array + LastSec: .bss + VAddr: 0x3E10 + Align: 0x1000 + Offset: 0x2E10 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .dynamic + VAddr: 0x3E20 + Align: 0x8 + Offset: 0x2E20 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.build-id + LastSec: .note.gnu.build-id + VAddr: 0x2C8 + Align: 0x4 + Offset: 0x2C8 + - Type: PT_GNU_PROPERTY + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + VAddr: 0x2010 + Align: 0x4 + Offset: 0x2010 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x10 + Offset: 0x0 + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + FirstSec: .init_array + LastSec: .got + VAddr: 0x3E10 + Offset: 0x2E10 +Sections: + - Name: .note.gnu.property + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2A8 + AddressAlign: 0x8 + Notes: + - Name: GNU + Desc: 020000C0040000000300000000000000 + Type: NT_GNU_PROPERTY_TYPE_0 + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2C8 + AddressAlign: 0x4 + Notes: + - Name: GNU + Desc: 6337F7C1BF21A1DE17630C55602EB4CAC50435BB + Type: NT_PRPSINFO + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x2F0 + Link: .dynsym + AddressAlign: 0x8 + Header: + SymNdx: 0x6 + Shift2: 0x6 + BloomFilter: [ 0x400000100000 ] + HashBuckets: [ 0x6, 0x0 ] + HashValues: [ 0x7C9DCB95 ] + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x318 + Link: .dynstr + AddressAlign: 0x8 + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x3C0 + AddressAlign: 0x1 + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x436 + Link: .dynsym + AddressAlign: 0x2 + Entries: [ 0, 1, 2, 1, 1, 2, 1 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x448 + Link: .dynstr + AddressAlign: 0x8 + Dependencies: + - Version: 1 + File: libc.so.6 + Entries: + - Name: GLIBC_2.2.5 + Hash: 157882997 + Flags: 0 + Other: 2 + - Name: .rela.dyn + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Address: 0x468 + Link: .dynsym + AddressAlign: 0x8 + Relocations: + - Offset: 0x3E10 + Type: R_X86_64_RELATIVE + Addend: 4368 + - Offset: 0x3E18 + Type: R_X86_64_RELATIVE + Addend: 4304 + - Offset: 0x4020 + Type: R_X86_64_RELATIVE + Addend: 16416 + - Offset: 0x3FE0 + Symbol: _ITM_deregisterTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FE8 + Symbol: __gmon_start__ + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF0 + Symbol: _ITM_registerTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF8 + Symbol: __cxa_finalize + Type: R_X86_64_GLOB_DAT + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x510 + Link: .dynsym + AddressAlign: 0x8 + Info: .got.plt + Relocations: + - Offset: 0x4018 + Symbol: puts + Type: R_X86_64_JUMP_SLOT + - Name: .init + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x4 + Offset: 0x1000 + Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1020 + AddressAlign: 0x10 + EntSize: 0x10 + Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90 + - Name: .plt.got + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1040 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25AD2F00000F1F440000 + - Name: .plt.sec + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1050 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25BD2F00000F1F440000 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1060 + AddressAlign: 0x10 + Content: 488D3DC12F0000488D05BA2F00004839F87415488B05662F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D912F0000488D358A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05352F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D4D2F000000752B5548833D122F0000004889E5740C488B3D2E2F0000E849FFFFFFE864FFFFFFC605252F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5488D05D80E00004889C7E820FFFFFF905DC3 + - Name: .fini + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1134 + AddressAlign: 0x4 + Content: F30F1EFA4883EC084883C408C3 + - Name: .rodata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + AddressAlign: 0x1 + Offset: 0x2000 + Content: 48656C6C6F2066726F6D204200 + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2010 + AddressAlign: 0x4 + Content: 011B033B2C0000000400000010F0FFFF4800000030F0FFFF7000000040F0FFFF8800000009F1FFFFA0000000 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2040 + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000C0EFFFFF20000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000B8EFFFFF100000000000000000000000140000005C000000B0EFFFFF1000000000000000000000001C0000007400000061F0FFFF1A00000000450E108602430D06510C070800000000000000 + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E10 + AddressAlign: 0x8 + EntSize: 0x8 + Offset: 0x2E10 + Content: '1011000000000000' + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E18 + AddressAlign: 0x8 + EntSize: 0x8 + Content: D010000000000000 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E20 + Link: .dynstr + AddressAlign: 0x8 + Entries: + - Tag: DT_NEEDED + Value: 0x5F + - Tag: DT_INIT + Value: 0x1000 + - Tag: DT_FINI + Value: 0x1134 + - Tag: DT_INIT_ARRAY + Value: 0x3E10 + - Tag: DT_INIT_ARRAYSZ + Value: 0x8 + - Tag: DT_FINI_ARRAY + Value: 0x3E18 + - Tag: DT_FINI_ARRAYSZ + Value: 0x8 + - Tag: DT_GNU_HASH + Value: 0x2F0 + - Tag: DT_STRTAB + Value: 0x3C0 + - Tag: DT_SYMTAB + Value: 0x318 + - Tag: DT_STRSZ + Value: 0x75 + - Tag: DT_SYMENT + Value: 0x18 + - Tag: DT_PLTGOT + Value: 0x4000 + - Tag: DT_PLTRELSZ + Value: 0x18 + - Tag: DT_PLTREL + Value: 0x7 + - Tag: DT_JMPREL + Value: 0x510 + - Tag: DT_RELA + Value: 0x468 + - Tag: DT_RELASZ + Value: 0xA8 + - Tag: DT_RELAENT + Value: 0x18 + - Tag: DT_VERNEED + Value: 0x448 + - Tag: DT_VERNEEDNUM + Value: 0x1 + - Tag: DT_VERSYM + Value: 0x436 + - Tag: DT_RELACOUNT + Value: 0x3 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3FE0 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '0000000000000000000000000000000000000000000000000000000000000000' + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4000 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '203E000000000000000000000000000000000000000000003010000000000000' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4020 + AddressAlign: 0x8 + Content: '2040000000000000' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4028 + AddressAlign: 0x1 + Size: 0x8 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000 +Symbols: + - Name: crtstuff.c + Type: STT_FILE + Index: SHN_ABS + - Name: deregister_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1060 + - Name: register_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1090 + - Name: __do_global_dtors_aux + Type: STT_FUNC + Section: .text + Value: 0x10D0 + - Name: completed.0 + Type: STT_OBJECT + Section: .bss + Value: 0x4028 + Size: 0x1 + - Name: __do_global_dtors_aux_fini_array_entry + Type: STT_OBJECT + Section: .fini_array + Value: 0x3E18 + - Name: frame_dummy + Type: STT_FUNC + Section: .text + Value: 0x1110 + - Name: __frame_dummy_init_array_entry + Type: STT_OBJECT + Section: .init_array + Value: 0x3E10 + - Name: libB.c + Type: STT_FILE + Index: SHN_ABS + - Name: 'crtstuff.c (1)' + Type: STT_FILE + Index: SHN_ABS + - Name: __FRAME_END__ + Type: STT_OBJECT + Section: .eh_frame + Value: 0x20D0 + - Type: STT_FILE + Index: SHN_ABS + - Name: _fini + Type: STT_FUNC + Section: .fini + Value: 0x1134 + - Name: __dso_handle + Type: STT_OBJECT + Section: .data + Value: 0x4020 + - Name: _DYNAMIC + Type: STT_OBJECT + Section: .dynamic + Value: 0x3E20 + - Name: __GNU_EH_FRAME_HDR + Section: .eh_frame_hdr + Value: 0x2010 + - Name: __TMC_END__ + Type: STT_OBJECT + Section: .data + Value: 0x4028 + - Name: _GLOBAL_OFFSET_TABLE_ + Type: STT_OBJECT + Section: .got.plt + Value: 0x4000 + - Name: _init + Type: STT_FUNC + Section: .init + Value: 0x1000 + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: 'puts@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: sayB + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1119 + Size: 0x1A + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: '__cxa_finalize@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_WEAK +DynamicSymbols: + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: puts + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: __cxa_finalize + Type: STT_FUNC + Binding: STB_WEAK + - Name: sayB + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1119 + Size: 0x1A +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml new file mode 100644 index 0000000..3d57c4f --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml @@ -0,0 +1,723 @@ +--- !fat-mach-o +FatHeader: + magic: 0xCAFEBABE + nfat_arch: 3 +FatArchs: + - cputype: 0x1000007 + cpusubtype: 0x3 + offset: 0x1000 + size: 8376 + align: 12 + - cputype: 0x100000C + cpusubtype: 0x0 + offset: 0x4000 + size: 33376 + align: 14 + - cputype: 0x100000C + cpusubtype: 0x80000002 + offset: 0x10000 + size: 33376 + align: 14 +Slices: + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x6 + ncmds: 14 + sizeofcmds: 960 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0xF80 + size: 20 + offset: 0xF80 + align: 4 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 554889E5488D3D0F000000B000E8020000005DC3 + - sectname: __stubs + segname: __TEXT + addr: 0xF94 + size: 6 + offset: 0xF94 + align: 1 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x6 + reserved3: 0x0 + content: FF2566000000 + - sectname: __cstring + segname: __TEXT + addr: 0xF9A + size: 14 + offset: 0xF9A + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D20420A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0xFA8 + size: 88 + offset: 0xFA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000800F00004000000040000000940F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 4096 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x1000 + size: 8 + offset: 0x1000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 184 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libB.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 8192 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 8288 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8320 + nsyms: 2 + stroff: 8360 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 8352 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 88B60B3C-13D3-3D7E-AEED-5F3E991FDF08 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 8312 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 8320 + datasize: 0 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayB + Flags: 0x0 + Address: 0xF80 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 3968 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayB + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0xF80 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 976 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F70 + size: 28 + offset: 0x3F70 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6 + - sectname: __stubs + segname: __TEXT + addr: 0x3F8C + size: 12 + offset: 0x3F8C + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0xC + reserved3: 0x0 + content: 100000B0100240F900021FD6 + - sectname: __cstring + segname: __TEXT + addr: 0x3F98 + size: 14 + offset: 0x3F98 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D20420A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000703F000040000000400000008C3F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x4000 + size: 8 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 608 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libB.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32864 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32896 + nsyms: 2 + stroff: 32936 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32928 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 90C3787A-22E1-35AE-9284-97A4842F88AF + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32888 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32896 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 32960 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayB + Flags: 0x0 + Address: 0x3F70 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16240 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayB + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0x3F70 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x80000002 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 976 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F68 + size: 32 + offset: 0x3F68 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 7F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6 + - sectname: __auth_stubs + segname: __TEXT + addr: 0x3F88 + size: 16 + offset: 0x3F88 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x10 + reserved3: 0x0 + content: 110000B031020091300240F9110A1FD7 + - sectname: __cstring + segname: __TEXT + addr: 0x3F98 + size: 14 + offset: 0x3F98 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D20420A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000883F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __auth_got + segname: __DATA_CONST + addr: 0x4000 + size: 8 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: 00000000000001C0 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 608 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libB.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32864 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32896 + nsyms: 2 + stroff: 32936 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32928 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 76B41B3A-00EC-388B-A432-478A96772CC4 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32888 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32896 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 32960 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayB + Flags: 0x0 + Address: 0x3F68 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16232 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayB + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0x3F68 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml new file mode 100644 index 0000000..3fabf9a --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml @@ -0,0 +1,450 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .rela.plt + Align: 0x1000 + Offset: 0x0 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .init + LastSec: .fini + VAddr: 0x1000 + Align: 0x1000 + Offset: 0x1000 + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame + VAddr: 0x2000 + Align: 0x1000 + Offset: 0x2000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .init_array + LastSec: .bss + VAddr: 0x3E10 + Align: 0x1000 + Offset: 0x2E10 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .dynamic + VAddr: 0x3E20 + Align: 0x8 + Offset: 0x2E20 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.build-id + LastSec: .note.gnu.build-id + VAddr: 0x2C8 + Align: 0x4 + Offset: 0x2C8 + - Type: PT_GNU_PROPERTY + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + VAddr: 0x2000 + Align: 0x4 + Offset: 0x2000 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x10 + Offset: 0x0 + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + FirstSec: .init_array + LastSec: .got + VAddr: 0x3E10 + Offset: 0x2E10 +Sections: + - Name: .note.gnu.property + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2A8 + AddressAlign: 0x8 + Notes: + - Name: GNU + Desc: 020000C0040000000300000000000000 + Type: NT_GNU_PROPERTY_TYPE_0 + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2C8 + AddressAlign: 0x4 + Notes: + - Name: GNU + Desc: 0318D63E46BF31CEFF90D5C7F0475D9F78676EC8 + Type: NT_PRPSINFO + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x2F0 + Link: .dynsym + AddressAlign: 0x8 + Header: + SymNdx: 0x8 + Shift2: 0x6 + BloomFilter: [ 0x400000200000 ] + HashBuckets: [ 0x0, 0x8 ] + HashValues: [ 0x7C9DCB95 ] + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x318 + Link: .dynstr + AddressAlign: 0x8 + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x3F0 + AddressAlign: 0x1 + Content: "6C6962412E736F006C6962422E736F006C69625A2E736F00244F524947494E2F2E2E2F413A244F524947494E2F2E2E2F423A244F524947494E2F2E2E2F5A" + - Name: .rela.dyn + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Address: 0x498 + Link: .dynsym + AddressAlign: 0x8 + Relocations: + - Offset: 0x3E10 + Type: R_X86_64_RELATIVE + Addend: 4432 + - Offset: 0x3E18 + Type: R_X86_64_RELATIVE + Addend: 4368 + - Offset: 0x4030 + Type: R_X86_64_RELATIVE + Addend: 16432 + - Offset: 0x3FE0 + Symbol: __cxa_finalize + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FE8 + Symbol: _ITM_registerTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF0 + Symbol: _ITM_deregisterTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF8 + Symbol: __gmon_start__ + Type: R_X86_64_GLOB_DAT + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x540 + Link: .dynsym + AddressAlign: 0x8 + Info: .got.plt + Relocations: + - Offset: 0x4018 + Symbol: sayA + Type: R_X86_64_JUMP_SLOT + - Offset: 0x4020 + Symbol: sayB + Type: R_X86_64_JUMP_SLOT + - Offset: 0x4028 + Symbol: sayZ + Type: R_X86_64_JUMP_SLOT + - Name: .init + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x4 + Offset: 0x1000 + Content: F30F1EFA4883EC08488B05E92F00004885C07402FFD04883C408C3 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1020 + AddressAlign: 0x10 + EntSize: 0x10 + Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90F30F1EFA6801000000F2E9D1FFFFFF90F30F1EFA6802000000F2E9C1FFFFFF90 + - Name: .plt.got + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1060 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25752F00000F1F440000 + - Name: .plt.sec + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1070 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF259D2F00000F1F440000F30F1EFAF2FF25952F00000F1F440000F30F1EFAF2FF258D2F00000F1F440000 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x10A0 + AddressAlign: 0x10 + Content: 488D3D912F0000488D058A2F00004839F87415488B05362F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D612F0000488D355A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05ED2E00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D1D2F000000752B5548833DBA2E0000004889E5740C488B3DFE2E0000E829FFFFFFE864FFFFFFC605F52E0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5B800000000E805FFFFFFB800000000E80BFFFFFFB800000000E811FFFFFF905DC3 + - Name: .fini + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1184 + AddressAlign: 0x4 + Content: F30F1EFA4883EC084883C408C3 + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + AddressAlign: 0x4 + Offset: 0x2000 + Content: 011B033B2C0000000400000020F0FFFF4800000060F0FFFF7000000070F0FFFF8800000059F1FFFFA0000000 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2030 + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000D0EFFFFF40000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000E8EFFFFF100000000000000000000000140000005C000000E0EFFFFF3000000000000000000000001C00000074000000B1F0FFFF2900000000450E108602430D06600C070800000000000000 + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E10 + AddressAlign: 0x8 + EntSize: 0x8 + Offset: 0x2E10 + Content: '5011000000000000' + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E18 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '1011000000000000' + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E20 + Link: .dynstr + AddressAlign: 0x8 + Entries: + - Tag: DT_NEEDED + Value: 0x0 + - Tag: DT_NEEDED + Value: 0x8 + - Tag: DT_NEEDED + Value: 0x10 + - Tag: DT_RUNPATH + Value: 0x18 + - Tag: DT_INIT + Value: 0x1000 + - Tag: DT_FINI + Value: 0x1184 + - Tag: DT_INIT_ARRAY + Value: 0x3E10 + - Tag: DT_INIT_ARRAYSZ + Value: 0x8 + - Tag: DT_FINI_ARRAY + Value: 0x3E18 + - Tag: DT_FINI_ARRAYSZ + Value: 0x8 + - Tag: DT_GNU_HASH + Value: 0x2F0 + - Tag: DT_STRTAB + Value: 0x3F0 + - Tag: DT_SYMTAB + Value: 0x318 + - Tag: DT_STRSZ + Value: 0xA8 + - Tag: DT_SYMENT + Value: 0x18 + - Tag: DT_PLTGOT + Value: 0x4000 + - Tag: DT_PLTRELSZ + Value: 0x48 + - Tag: DT_PLTREL + Value: 0x7 + - Tag: DT_JMPREL + Value: 0x540 + - Tag: DT_RELA + Value: 0x498 + - Tag: DT_RELASZ + Value: 0xA8 + - Tag: DT_RELAENT + Value: 0x18 + - Tag: DT_RELACOUNT + Value: 0x3 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3FE0 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '0000000000000000000000000000000000000000000000000000000000000000' + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4000 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '203E00000000000000000000000000000000000000000000301000000000000040100000000000005010000000000000' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4030 + AddressAlign: 0x8 + Content: '3040000000000000' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4038 + AddressAlign: 0x1 + Size: 0x8 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000 +Symbols: + - Name: crtstuff.c + Type: STT_FILE + Index: SHN_ABS + - Name: deregister_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x10A0 + - Name: register_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x10D0 + - Name: __do_global_dtors_aux + Type: STT_FUNC + Section: .text + Value: 0x1110 + - Name: completed.0 + Type: STT_OBJECT + Section: .bss + Value: 0x4038 + Size: 0x1 + - Name: __do_global_dtors_aux_fini_array_entry + Type: STT_OBJECT + Section: .fini_array + Value: 0x3E18 + - Name: frame_dummy + Type: STT_FUNC + Section: .text + Value: 0x1150 + - Name: __frame_dummy_init_array_entry + Type: STT_OBJECT + Section: .init_array + Value: 0x3E10 + - Name: libC.c + Type: STT_FILE + Index: SHN_ABS + - Name: 'crtstuff.c (1)' + Type: STT_FILE + Index: SHN_ABS + - Name: __FRAME_END__ + Type: STT_OBJECT + Section: .eh_frame + Value: 0x20C0 + - Type: STT_FILE + Index: SHN_ABS + - Name: _DYNAMIC + Type: STT_OBJECT + Section: .dynamic + Value: 0x3E20 + - Name: __TMC_END__ + Type: STT_OBJECT + Section: .data + Value: 0x4038 + - Name: __dso_handle + Type: STT_OBJECT + Section: .data + Value: 0x4030 + - Name: _init + Type: STT_FUNC + Section: .init + Value: 0x1000 + - Name: __GNU_EH_FRAME_HDR + Section: .eh_frame_hdr + Value: 0x2000 + - Name: _fini + Type: STT_FUNC + Section: .fini + Value: 0x1184 + - Name: _GLOBAL_OFFSET_TABLE_ + Type: STT_OBJECT + Section: .got.plt + Value: 0x4000 + - Name: __cxa_finalize + Binding: STB_WEAK + - Name: sayC + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1159 + Size: 0x29 + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: sayA + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: sayB + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: sayZ + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK +DynamicSymbols: + - Name: __cxa_finalize + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: sayA + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: sayB + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: sayZ + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: sayC + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1159 + Size: 0x29 +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml new file mode 100644 index 0000000..ba33483 --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml @@ -0,0 +1,870 @@ +--- !fat-mach-o +FatHeader: + magic: 0xCAFEBABE + nfat_arch: 3 +FatArchs: + - cputype: 0x1000007 + cpusubtype: 0x3 + offset: 0x1000 + size: 8456 + align: 12 + - cputype: 0x100000C + cpusubtype: 0x0 + offset: 0x4000 + size: 33456 + align: 14 + - cputype: 0x100000C + cpusubtype: 0x80000002 + offset: 0x10000 + size: 33456 + align: 14 +Slices: + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x6 + ncmds: 20 + sizeofcmds: 1120 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __TEXT + vmaddr: 0 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 5 + initprot: 5 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0xF70 + size: 27 + offset: 0xF70 + align: 4 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 554889E5B000E811000000B000E810000000B000E80F0000005DC3 + - sectname: __stubs + segname: __TEXT + addr: 0xF8C + size: 18 + offset: 0xF8C + align: 1 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x6 + reserved3: 0x0 + content: FF256E000000FF2570000000FF2572000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0xFA0 + size: 88 + offset: 0xFA0 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000700F000040000000400000008B0F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 4096 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x1000 + size: 24 + offset: 0x1000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x3 + reserved2: 0x0 + reserved3: 0x0 + content: '000000000000108001000000000010800200000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 264 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libC.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 8192 + datasize: 112 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 8304 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8336 + nsyms: 4 + stroff: 8424 + strsize: 32 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 3 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 8400 + nindirectsyms: 6 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 2AA1F9E9-F250-366F-B382-51A91DE06BED + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libA.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libB.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libZ.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../A' + ZeroPadBytes: 3 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../B' + ZeroPadBytes: 3 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../Z' + ZeroPadBytes: 3 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 8328 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 8336 + datasize: 0 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayC + Flags: 0x0 + Address: 0xF70 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 3952 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 14 + n_type: 0x1 + n_sect: 0 + n_desc: 512 + n_value: 0 + - n_strx: 20 + n_type: 0x1 + n_sect: 0 + n_desc: 768 + n_value: 0 + StringTable: + - ' ' + - _sayC + - _sayA + - _sayB + - _sayZ + - '' + - '' + - '' + - '' + - '' + - '' + IndirectSymbols: [ 0x1, 0x2, 0x3, 0x1, 0x2, 0x3 ] + FunctionStarts: [ 0xF70 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x2, 0xE, 0x0, 0x0, 0x3, 0x1A, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x73, 0x61, 0x79, + 0x41, 0x0, 0x5F, 0x73, 0x61, 0x79, 0x42, 0x0, + 0x5F, 0x73, 0x61, 0x79, 0x5A, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x6 + ncmds: 21 + sizeofcmds: 1136 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F68 + size: 28 + offset: 0x3F68 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: FD7BBFA9FD030091050000940700009409000094FD7BC1A8C0035FD6 + - sectname: __stubs + segname: __TEXT + addr: 0x3F84 + size: 36 + offset: 0x3F84 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0xC + reserved3: 0x0 + content: 100000B0100240F900021FD6100000B0100640F900021FD6100000B0100A40F900021FD6 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000843F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x4000 + size: 24 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x3 + reserved2: 0x0 + reserved3: 0x0 + content: '000000000000108001000000000010800200000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 688 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libC.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 112 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32880 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32912 + nsyms: 4 + stroff: 33000 + strsize: 32 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 3 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32976 + nindirectsyms: 6 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 02B69690-925D-35EE-A8AB-6D99813D2A16 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libA.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libB.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libZ.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../A' + ZeroPadBytes: 3 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../B' + ZeroPadBytes: 3 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../Z' + ZeroPadBytes: 3 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32904 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32912 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 33040 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayC + Flags: 0x0 + Address: 0x3F68 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16232 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 14 + n_type: 0x1 + n_sect: 0 + n_desc: 512 + n_value: 0 + - n_strx: 20 + n_type: 0x1 + n_sect: 0 + n_desc: 768 + n_value: 0 + StringTable: + - ' ' + - _sayC + - _sayA + - _sayB + - _sayZ + - '' + - '' + - '' + - '' + - '' + - '' + IndirectSymbols: [ 0x1, 0x2, 0x3, 0x1, 0x2, 0x3 ] + FunctionStarts: [ 0x3F68 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x2, 0xE, 0x0, 0x0, 0x3, 0x1A, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x73, 0x61, 0x79, + 0x41, 0x0, 0x5F, 0x73, 0x61, 0x79, 0x42, 0x0, + 0x5F, 0x73, 0x61, 0x79, 0x5A, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x80000002 + filetype: 0x6 + ncmds: 21 + sizeofcmds: 1136 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F58 + size: 32 + offset: 0x3F58 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 7F2303D5FD7BBFA9FD03009105000094080000940B000094FD7BC1A8FF0F5FD6 + - sectname: __auth_stubs + segname: __TEXT + addr: 0x3F78 + size: 48 + offset: 0x3F78 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x10 + reserved3: 0x0 + content: 110000B031020091300240F9110A1FD7110000B031220091300240F9110A1FD7110000B031420091300240F9110A1FD7 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000583F00004000000040000000783F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __auth_got + segname: __DATA_CONST + addr: 0x4000 + size: 24 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x3 + reserved2: 0x0 + reserved3: 0x0 + content: 00000000000009C001000000000009C002000000000001C0 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 688 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libC.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 112 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32880 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32912 + nsyms: 4 + stroff: 33000 + strsize: 32 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 3 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32976 + nindirectsyms: 6 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: F54076AA-8888-3DED-8BDF-BC7FB3E6FE8A + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libA.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libB.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libZ.dylib' + ZeroPadBytes: 7 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../A' + ZeroPadBytes: 3 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../B' + ZeroPadBytes: 3 + - cmd: LC_RPATH + cmdsize: 32 + path: 12 + Content: '@loader_path/../Z' + ZeroPadBytes: 3 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32904 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32912 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 33040 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayC + Flags: 0x0 + Address: 0x3F58 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16216 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 14 + n_type: 0x1 + n_sect: 0 + n_desc: 512 + n_value: 0 + - n_strx: 20 + n_type: 0x1 + n_sect: 0 + n_desc: 768 + n_value: 0 + StringTable: + - ' ' + - _sayC + - _sayA + - _sayB + - _sayZ + - '' + - '' + - '' + - '' + - '' + - '' + IndirectSymbols: [ 0x1, 0x2, 0x3, 0x1, 0x2, 0x3 ] + FunctionStarts: [ 0x3F58 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x2, 0xE, 0x0, 0x0, 0x3, 0x1A, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x73, 0x61, 0x79, + 0x41, 0x0, 0x5F, 0x73, 0x61, 0x79, 0x42, 0x0, + 0x5F, 0x73, 0x61, 0x79, 0x5A, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0 ] +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml new file mode 100644 index 0000000..5561f29 --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml @@ -0,0 +1,460 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .rela.plt + Align: 0x1000 + Offset: 0x0 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .init + LastSec: .fini + VAddr: 0x1000 + Align: 0x1000 + Offset: 0x1000 + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .rodata + LastSec: .eh_frame + VAddr: 0x2000 + Align: 0x1000 + Offset: 0x2000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .init_array + LastSec: .bss + VAddr: 0x3E10 + Align: 0x1000 + Offset: 0x2E10 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .dynamic + VAddr: 0x3E20 + Align: 0x8 + Offset: 0x2E20 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_NOTE + Flags: [ PF_R ] + FirstSec: .note.gnu.build-id + LastSec: .note.gnu.build-id + VAddr: 0x2C8 + Align: 0x4 + Offset: 0x2C8 + - Type: PT_GNU_PROPERTY + Flags: [ PF_R ] + FirstSec: .note.gnu.property + LastSec: .note.gnu.property + VAddr: 0x2A8 + Align: 0x8 + Offset: 0x2A8 + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + VAddr: 0x2010 + Align: 0x4 + Offset: 0x2010 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x10 + Offset: 0x0 + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + FirstSec: .init_array + LastSec: .got + VAddr: 0x3E10 + Offset: 0x2E10 +Sections: + - Name: .note.gnu.property + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2A8 + AddressAlign: 0x8 + Notes: + - Name: GNU + Desc: 020000C0040000000300000000000000 + Type: NT_GNU_PROPERTY_TYPE_0 + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x2C8 + AddressAlign: 0x4 + Notes: + - Name: GNU + Desc: 640A4A3AC0DF6BA3DAC3B51CCD727245117E0B30 + Type: NT_PRPSINFO + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x2F0 + Link: .dynsym + AddressAlign: 0x8 + Header: + SymNdx: 0x6 + Shift2: 0x6 + BloomFilter: [ 0x500000000000 ] + HashBuckets: [ 0x6, 0x0 ] + HashValues: [ 0x7C9DCBAD ] + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x318 + Link: .dynstr + AddressAlign: 0x8 + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x3C0 + AddressAlign: 0x1 + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x436 + Link: .dynsym + AddressAlign: 0x2 + Entries: [ 0, 1, 2, 1, 1, 2, 1 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x448 + Link: .dynstr + AddressAlign: 0x8 + Dependencies: + - Version: 1 + File: libc.so.6 + Entries: + - Name: GLIBC_2.2.5 + Hash: 157882997 + Flags: 0 + Other: 2 + - Name: .rela.dyn + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Address: 0x468 + Link: .dynsym + AddressAlign: 0x8 + Relocations: + - Offset: 0x3E10 + Type: R_X86_64_RELATIVE + Addend: 4368 + - Offset: 0x3E18 + Type: R_X86_64_RELATIVE + Addend: 4304 + - Offset: 0x4020 + Type: R_X86_64_RELATIVE + Addend: 16416 + - Offset: 0x3FE0 + Symbol: _ITM_deregisterTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FE8 + Symbol: __gmon_start__ + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF0 + Symbol: _ITM_registerTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x3FF8 + Symbol: __cxa_finalize + Type: R_X86_64_GLOB_DAT + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x510 + Link: .dynsym + AddressAlign: 0x8 + Info: .got.plt + Relocations: + - Offset: 0x4018 + Symbol: puts + Type: R_X86_64_JUMP_SLOT + - Name: .init + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x4 + Offset: 0x1000 + Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1020 + AddressAlign: 0x10 + EntSize: 0x10 + Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90 + - Name: .plt.got + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1040 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25AD2F00000F1F440000 + - Name: .plt.sec + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1050 + AddressAlign: 0x10 + EntSize: 0x10 + Content: F30F1EFAF2FF25BD2F00000F1F440000 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1060 + AddressAlign: 0x10 + Content: 488D3DC12F0000488D05BA2F00004839F87415488B05662F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D912F0000488D358A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05352F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D4D2F000000752B5548833D122F0000004889E5740C488B3D2E2F0000E849FFFFFFE864FFFFFFC605252F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5488D05D80E00004889C7E820FFFFFF905DC3 + - Name: .fini + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1134 + AddressAlign: 0x4 + Content: F30F1EFA4883EC084883C408C3 + - Name: .rodata + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + AddressAlign: 0x1 + Offset: 0x2000 + Content: 48656C6C6F2066726F6D205A00 + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2010 + AddressAlign: 0x4 + Content: 011B033B2C0000000400000010F0FFFF4800000030F0FFFF7000000040F0FFFF8800000009F1FFFFA0000000 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2040 + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000C0EFFFFF20000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000B8EFFFFF100000000000000000000000140000005C000000B0EFFFFF1000000000000000000000001C0000007400000061F0FFFF1A00000000450E108602430D06510C070800000000000000 + - Name: .init_array + Type: SHT_INIT_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E10 + AddressAlign: 0x8 + EntSize: 0x8 + Offset: 0x2E10 + Content: '1011000000000000' + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E18 + AddressAlign: 0x8 + EntSize: 0x8 + Content: D010000000000000 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3E20 + Link: .dynstr + AddressAlign: 0x8 + Entries: + - Tag: DT_NEEDED + Value: 0x5F + - Tag: DT_INIT + Value: 0x1000 + - Tag: DT_FINI + Value: 0x1134 + - Tag: DT_INIT_ARRAY + Value: 0x3E10 + - Tag: DT_INIT_ARRAYSZ + Value: 0x8 + - Tag: DT_FINI_ARRAY + Value: 0x3E18 + - Tag: DT_FINI_ARRAYSZ + Value: 0x8 + - Tag: DT_GNU_HASH + Value: 0x2F0 + - Tag: DT_STRTAB + Value: 0x3C0 + - Tag: DT_SYMTAB + Value: 0x318 + - Tag: DT_STRSZ + Value: 0x75 + - Tag: DT_SYMENT + Value: 0x18 + - Tag: DT_PLTGOT + Value: 0x4000 + - Tag: DT_PLTRELSZ + Value: 0x18 + - Tag: DT_PLTREL + Value: 0x7 + - Tag: DT_JMPREL + Value: 0x510 + - Tag: DT_RELA + Value: 0x468 + - Tag: DT_RELASZ + Value: 0xA8 + - Tag: DT_RELAENT + Value: 0x18 + - Tag: DT_VERNEED + Value: 0x448 + - Tag: DT_VERNEEDNUM + Value: 0x1 + - Tag: DT_VERSYM + Value: 0x436 + - Tag: DT_RELACOUNT + Value: 0x3 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Tag: DT_NULL + Value: 0x0 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3FE0 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '0000000000000000000000000000000000000000000000000000000000000000' + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4000 + AddressAlign: 0x8 + EntSize: 0x8 + Content: '203E000000000000000000000000000000000000000000003010000000000000' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4020 + AddressAlign: 0x8 + Content: '2040000000000000' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x4028 + AddressAlign: 0x1 + Size: 0x8 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000 +Symbols: + - Name: crtstuff.c + Type: STT_FILE + Index: SHN_ABS + - Name: deregister_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1060 + - Name: register_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1090 + - Name: __do_global_dtors_aux + Type: STT_FUNC + Section: .text + Value: 0x10D0 + - Name: completed.0 + Type: STT_OBJECT + Section: .bss + Value: 0x4028 + Size: 0x1 + - Name: __do_global_dtors_aux_fini_array_entry + Type: STT_OBJECT + Section: .fini_array + Value: 0x3E18 + - Name: frame_dummy + Type: STT_FUNC + Section: .text + Value: 0x1110 + - Name: __frame_dummy_init_array_entry + Type: STT_OBJECT + Section: .init_array + Value: 0x3E10 + - Name: libZ.c + Type: STT_FILE + Index: SHN_ABS + - Name: 'crtstuff.c (1)' + Type: STT_FILE + Index: SHN_ABS + - Name: __FRAME_END__ + Type: STT_OBJECT + Section: .eh_frame + Value: 0x20D0 + - Type: STT_FILE + Index: SHN_ABS + - Name: _fini + Type: STT_FUNC + Section: .fini + Value: 0x1134 + - Name: __dso_handle + Type: STT_OBJECT + Section: .data + Value: 0x4020 + - Name: _DYNAMIC + Type: STT_OBJECT + Section: .dynamic + Value: 0x3E20 + - Name: __GNU_EH_FRAME_HDR + Section: .eh_frame_hdr + Value: 0x2010 + - Name: __TMC_END__ + Type: STT_OBJECT + Section: .data + Value: 0x4028 + - Name: _GLOBAL_OFFSET_TABLE_ + Type: STT_OBJECT + Section: .got.plt + Value: 0x4000 + - Name: _init + Type: STT_FUNC + Section: .init + Value: 0x1000 + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: 'puts@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: sayZ + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1119 + Size: 0x1A + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: '__cxa_finalize@GLIBC_2.2.5' + Type: STT_FUNC + Binding: STB_WEAK +DynamicSymbols: + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: puts + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: __cxa_finalize + Type: STT_FUNC + Binding: STB_WEAK + - Name: sayZ + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1119 + Size: 0x1A +... diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml new file mode 100644 index 0000000..c0c1826 --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml @@ -0,0 +1,723 @@ +--- !fat-mach-o +FatHeader: + magic: 0xCAFEBABE + nfat_arch: 3 +FatArchs: + - cputype: 0x1000007 + cpusubtype: 0x3 + offset: 0x1000 + size: 8376 + align: 12 + - cputype: 0x100000C + cpusubtype: 0x0 + offset: 0x4000 + size: 33376 + align: 14 + - cputype: 0x100000C + cpusubtype: 0x80000002 + offset: 0x10000 + size: 33376 + align: 14 +Slices: + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x6 + ncmds: 14 + sizeofcmds: 960 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0xF80 + size: 20 + offset: 0xF80 + align: 4 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 554889E5488D3D0F000000B000E8020000005DC3 + - sectname: __stubs + segname: __TEXT + addr: 0xF94 + size: 6 + offset: 0xF94 + align: 1 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x6 + reserved3: 0x0 + content: FF2566000000 + - sectname: __cstring + segname: __TEXT + addr: 0xF9A + size: 14 + offset: 0xF9A + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D205A0A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0xFA8 + size: 88 + offset: 0xFA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000800F00004000000040000000940F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 4096 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x1000 + size: 8 + offset: 0x1000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 184 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libZ.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 8192 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 8288 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8320 + nsyms: 2 + stroff: 8360 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 8352 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 399E203C-FF9A-3B80-872C-85F3A759A78B + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 8312 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 8320 + datasize: 0 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayZ + Flags: 0x0 + Address: 0xF80 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 3968 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayZ + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0xF80 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 976 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F70 + size: 28 + offset: 0x3F70 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6 + - sectname: __stubs + segname: __TEXT + addr: 0x3F8C + size: 12 + offset: 0x3F8C + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0xC + reserved3: 0x0 + content: 100000B0100240F900021FD6 + - sectname: __cstring + segname: __TEXT + addr: 0x3F98 + size: 14 + offset: 0x3F98 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D205A0A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000703F000040000000400000008C3F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __got + segname: __DATA_CONST + addr: 0x4000 + size: 8 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000080' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 608 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libZ.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32864 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32896 + nsyms: 2 + stroff: 32936 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32928 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 6E8E78AF-EDB2-3830-BE1E-013390302CC5 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32888 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32896 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 32960 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayZ + Flags: 0x0 + Address: 0x3F70 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16240 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayZ + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0x3F70 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] + - !mach-o + FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x80000002 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 976 + flags: 0x100085 + reserved: 0x0 + LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 392 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 4 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x3F68 + size: 32 + offset: 0x3F68 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 7F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6 + - sectname: __auth_stubs + segname: __TEXT + addr: 0x3F88 + size: 16 + offset: 0x3F88 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x0 + reserved2: 0x10 + reserved3: 0x0 + content: 110000B031020091300240F9110A1FD7 + - sectname: __cstring + segname: __TEXT + addr: 0x3F98 + size: 14 + offset: 0x3F98 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48656C6C6F2066726F6D205A0A00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x3FA8 + size: 88 + offset: 0x3FA8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000883F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __auth_got + segname: __DATA_CONST + addr: 0x4000 + size: 8 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6 + reserved1: 0x1 + reserved2: 0x0 + reserved3: 0x0 + content: 00000000000001C0 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 608 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + Content: '@rpath/libZ.dylib' + ZeroPadBytes: 7 + - cmd: LC_DYLD_CHAINED_FIXUPS + cmdsize: 16 + dataoff: 32768 + datasize: 96 + - cmd: LC_DYLD_EXPORTS_TRIE + cmdsize: 16 + dataoff: 32864 + datasize: 24 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 32896 + nsyms: 2 + stroff: 32936 + strsize: 16 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 1 + iundefsym: 1 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 32928 + nindirectsyms: 2 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: E74F368D-238F-31FA-BF40-FA2964FED986 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 983040 + sdk: 983552 + ntools: 1 + Tools: + - tool: 3 + version: 73074435 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 88539136 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 32888 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 32896 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 32960 + datasize: 416 + LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 13 + Name: _sayZ + Flags: 0x0 + Address: 0x3F68 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 16232 + - n_strx: 8 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _sayZ + - _printf + IndirectSymbols: [ 0x1, 0x1 ] + FunctionStarts: [ 0x3F68 ] + ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72, + 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 ] +... diff --git a/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp new file mode 100644 index 0000000..441344b --- /dev/null +++ b/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp @@ -0,0 +1,762 @@ +//===- LibraryResolverTest.cpp - Unit tests for LibraryResolver -===// +// +// 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/TargetProcess/LibraryResolver.h" +#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" +#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h" +#include "llvm/ObjectYAML/MachOYAML.h" +#include "llvm/ObjectYAML/yaml2obj.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/YAMLParser.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" + +#include "llvm/Testing/Support/SupportHelpers.h" + +#include "gtest/gtest.h" + +#include <algorithm> +#include <string> +#include <vector> + +using namespace llvm; +using namespace llvm::orc; + +#if defined(__APPLE__) || defined(__linux__) +// TODO: Add COFF (Windows) support for these tests. +// this facility also works correctly on Windows (COFF), +// so we should eventually enable and run these tests for that platform as well. +namespace { + +#if defined(__APPLE__) +constexpr const char *ext = ".dylib"; +#elif defined(_WIN32) +constexpr const char *ext = ".dll"; +#else +constexpr const char *ext = ".so"; +#endif + +bool EnvReady = false; + +Triple getTargetTriple() { + auto JTMB = JITTargetMachineBuilder::detectHost(); + if (!JTMB) { + consumeError(JTMB.takeError()); + return Triple(); + } + return JTMB->getTargetTriple(); +} + +static bool CheckHostSupport() { + auto Triple = getTargetTriple(); + // TODO: Extend support to COFF (Windows) once test setup and YAML conversion + // are verified. + if (!Triple.isOSBinFormatMachO() && + !(Triple.isOSBinFormatELF() && Triple.getArch() == Triple::x86_64)) + return false; + + return true; +} + +std::string getYamlFilePlatformExt() { + auto Triple = getTargetTriple(); + if (Triple.isOSBinFormatMachO()) + return "_macho"; + else if (Triple.isOSBinFormatELF()) + return "_linux"; + + return ""; +} + +unsigned getYamlDocNum() { + // auto Triple = getTargetTriple(); + // if (Triple.isOSBinFormatELF()) + // return 1; + + return 1; +} + +class LibraryTestEnvironment : public ::testing::Environment { + std::vector<std::string> CreatedDylibsDir; + std::vector<std::string> CreatedDylibs; + SmallVector<char, 128> DirPath; + +public: + void SetUp() override { + if (!CheckHostSupport()) { + EnvReady = false; + return; + } + + StringRef ThisFile = __FILE__; + SmallVector<char, 128> InputDirPath(ThisFile.begin(), ThisFile.end()); + sys::path::remove_filename(InputDirPath); + sys::path::append(InputDirPath, "Inputs"); + if (!sys::fs::exists(InputDirPath)) + return; + + SmallString<512> ExecPath(sys::fs::getMainExecutable(nullptr, nullptr)); + sys::path::remove_filename(ExecPath); + SmallString<128> UniqueDir(ExecPath); + std::error_code EC = sys::fs::createUniqueDirectory(UniqueDir, DirPath); + + if (EC) + return; + + // given yamlPath + DylibPath, validate + convert + auto processYamlToDylib = [&](const SmallVector<char, 128> &YamlPath, + const SmallVector<char, 128> &DylibPath, + unsigned DocNum) -> bool { + if (!sys::fs::exists(YamlPath)) { + errs() << "YAML file missing: " + << StringRef(YamlPath.data(), YamlPath.size()) << "\n"; + EnvReady = false; + return false; + } + + auto BufOrErr = MemoryBuffer::getFile(YamlPath); + if (!BufOrErr) { + errs() << "Failed to read " + << StringRef(YamlPath.data(), YamlPath.size()) << ": " + << BufOrErr.getError().message() << "\n"; + EnvReady = false; + return false; + } + + yaml::Input yin(BufOrErr->get()->getBuffer()); + std::error_code EC; + raw_fd_ostream outFile(StringRef(DylibPath.data(), DylibPath.size()), EC, + sys::fs::OF_None); + + if (EC) { + errs() << "Failed to open " + << StringRef(DylibPath.data(), DylibPath.size()) + << " for writing: " << EC.message() << "\n"; + EnvReady = false; + return false; + } + + if (!yaml::convertYAML( + yin, outFile, + [](const Twine &M) { + // Handle or ignore errors here + errs() << "Yaml Error :" << M << "\n"; + }, + DocNum)) { + errs() << "Failed to convert " + << StringRef(YamlPath.data(), YamlPath.size()) << " to " + << StringRef(DylibPath.data(), DylibPath.size()) << "\n"; + EnvReady = false; + return false; + } + + CreatedDylibsDir.push_back(std::string(sys::path::parent_path( + StringRef(DylibPath.data(), DylibPath.size())))); + CreatedDylibs.push_back(std::string(DylibPath.begin(), DylibPath.end())); + return true; + }; + + std::vector<const char *> LibDirs = {"Z", "A", "B", "C"}; + + unsigned DocNum = getYamlDocNum(); + std::string YamlPltExt = getYamlFilePlatformExt(); + for (const auto &LibdirName : LibDirs) { + // YAML path + SmallVector<char, 128> YamlPath(InputDirPath.begin(), InputDirPath.end()); + SmallVector<char, 128> YamlFileName; + YamlFileName.append(LibdirName, LibdirName + strlen(LibdirName)); + YamlFileName.append(YamlPltExt.begin(), YamlPltExt.end()); + sys::path::append(YamlPath, LibdirName, YamlFileName); + sys::path::replace_extension(YamlPath, ".yaml"); + + // dylib path + SmallVector<char, 128> DylibPath(DirPath.begin(), DirPath.end()); + SmallVector<char, 128> DylibFileName; + StringRef prefix("lib"); + DylibFileName.append(prefix.begin(), prefix.end()); + DylibFileName.append(LibdirName, LibdirName + strlen(LibdirName)); + + sys::path::append(DylibPath, LibdirName); + if (!sys::fs::exists(DylibPath)) { + auto EC = sys::fs::create_directory(DylibPath); + if (EC) + return; + } + sys::path::append(DylibPath, DylibFileName); + sys::path::replace_extension(DylibPath, ext); + if (!processYamlToDylib(YamlPath, DylibPath, DocNum)) + return; + } + + EnvReady = true; + } + + void TearDown() override { sys::fs::remove_directories(DirPath); } + + std::string getBaseDir() const { + return std::string(DirPath.begin(), DirPath.end()); + } + + std::vector<std::string> getDylibPaths() const { return CreatedDylibs; } +}; + +static LibraryTestEnvironment *GlobalEnv = + static_cast<LibraryTestEnvironment *>( + ::testing::AddGlobalTestEnvironment(new LibraryTestEnvironment())); + +inline std::string libPath(const std::string &BaseDir, + const std::string &name) { +#if defined(__APPLE__) + return BaseDir + "/" + name + ".dylib"; +#elif defined(_WIN32) + return BaseDir + "/" + name + ".dll"; +#else + return BaseDir + "/" + name + ".so"; +#endif +} + +inline std::string withext(const std::string &lib) { + SmallString<128> P(lib); + sys::path::replace_extension(P, ext); + return P.str().str(); +} + +inline std::string platformSymbolName(const std::string &name) { +#if defined(__APPLE__) + return "_" + name; // macOS prepends underscore +#else + return name; +#endif +} + +struct TestLibrary { + std::string path; + std::vector<std::string> Syms; +}; + +class LibraryResolverIT : public ::testing::Test { +protected: + std::string BaseDir; + std::unordered_map<std::string, TestLibrary> libs; + + void addLib(const std::string &name) { + SmallString<512> path; + std::error_code EC = + sys::fs::real_path(libPath(BaseDir, name + "/lib" + name), path); + if (EC || path.empty() || !sys::fs::exists(path)) + GTEST_SKIP(); + libs[name] = {path.str().str(), {platformSymbolName("say" + name)}}; + } + + void SetUp() override { + if (!EnvReady || GlobalEnv == nullptr) + GTEST_SKIP() << "Skipping test: environment setup failed."; + + { + SmallString<512> path; + std::error_code EC = sys::fs::real_path(GlobalEnv->getBaseDir(), path); + if (path.empty() || EC) + GTEST_SKIP() << "Base directory resolution failed: " << EC.message(); + BaseDir = path.str().str(); + } + + for (const auto &P : GlobalEnv->getDylibPaths()) { + if (!sys::fs::exists(P)) + GTEST_SKIP() << "Missing dylib path: " << P; + } + + const std::vector<std::string> libNames = {"A", "B", "C", "Z"}; + for (const auto &name : libNames) + addLib(name); + + if (!EnvReady) + GTEST_SKIP() << "Skipping test: environment setup failed."; + } + + const std::vector<std::string> &sym(const std::string &key) { + return libs[key].Syms; + } + const std::string &lib(const std::string &key) { return libs[key].path; } + const std::string libdir(const std::string &key) { + SmallString<512> P(libs[key].path); + sys::path::remove_filename(P); + return P.str().str(); + } + const std::string libname(const std::string &key) { + return sys::path::filename(libs[key].path).str(); + } +}; + +// Helper: allow either "sayA" or "_sayA" depending on how your +// SymbolEnumerator reports. +static bool matchesEitherUnderscore(const std::string &got, + const std::string &bare) { + return got == bare || got == ("_" + bare); +} + +// Helper: normalize path ending check (we only care that it resolved to the +// right dylib) +static bool endsWith(const std::string &s, const std::string &suffix) { + if (s.size() < suffix.size()) + return false; + return std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); +} + +TEST_F(LibraryResolverIT, EnumerateSymbols_ExportsOnly_DefaultFlags) { + const std::string libC = lib("C"); + SymbolEnumeratorOptions Opts = SymbolEnumeratorOptions::defaultOptions(); + + std::vector<std::string> seen; + auto onEach = [&](llvm::StringRef sym) -> EnumerateResult { + seen.emplace_back(sym.str()); + return EnumerateResult::Continue; + }; + + ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libC, onEach, Opts)); + + // sayC is exported, others are undefined → only sayC expected + EXPECT_TRUE(any_of(seen, [&](const std::string &s) { + return matchesEitherUnderscore(s, "sayC"); + })); + EXPECT_FALSE(any_of(seen, [&](const std::string &s) { + return matchesEitherUnderscore(s, "sayA"); + })); + EXPECT_FALSE(any_of(seen, [&](const std::string &s) { + return matchesEitherUnderscore(s, "sayB"); + })); +} + +TEST_F(LibraryResolverIT, EnumerateSymbols_IncludesUndefineds) { + const std::string libC = lib("C"); + + SymbolEnumeratorOptions Opts; + Opts.FilterFlags = + SymbolEnumeratorOptions::IgnoreWeak | + SymbolEnumeratorOptions::IgnoreIndirect; // no IgnoreUndefined + + std::vector<std::string> seen; + auto onEach = [&](llvm::StringRef sym) -> EnumerateResult { + seen.emplace_back(sym.str()); + return EnumerateResult::Continue; + }; + + ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libC, onEach, Opts)); + + // Now we should see both sayC (export) and the undefined refs sayA, sayB, + // sayZ + EXPECT_TRUE(any_of(seen, [&](const std::string &s) { + return matchesEitherUnderscore(s, "sayC"); + })); + EXPECT_TRUE(any_of(seen, [&](const std::string &s) { + return matchesEitherUnderscore(s, "sayA"); + })); + EXPECT_TRUE(any_of(seen, [&](const std::string &s) { + return matchesEitherUnderscore(s, "sayB"); + })); +} + +// Full resolution via LibraryResolutionDriver/LibraryResolver --- +TEST_F(LibraryResolverIT, DriverResolvesSymbolsToCorrectLibraries) { + // Create the resolver from real base paths (our fixtures dir) + auto Stup = LibraryResolver::Setup::create({BaseDir}); + + // Full system behavior: no mocks + auto Driver = LibraryResolutionDriver::create(Stup); + ASSERT_NE(Driver, nullptr); + + // Tell the Driver about the scan path kinds (User/System) as your + // production code expects. + Driver->addScanPath(libdir("A"), PathType::User); + Driver->addScanPath(libdir("B"), PathType::User); + Driver->addScanPath(libdir("Z"), PathType::User); + + // Symbols to resolve (bare names; class handles underscore differences + // internally) + std::vector<std::string> Syms = {platformSymbolName("sayA"), + platformSymbolName("sayB"), + platformSymbolName("sayZ")}; + + bool CallbackRan = false; + Driver->resolveSymbols(Syms, [&](SymbolQuery &Q) { + CallbackRan = true; + + // sayA should resolve to A.dylib + { + auto lib = Q.getResolvedLib(platformSymbolName("sayA")); + ASSERT_TRUE(lib.has_value()) << "sayA should be resolved"; + EXPECT_TRUE(endsWith(lib->str(), libname("A"))) + << "sayA resolved to: " << lib->str(); + } + + // sayB should resolve to B.dylib + { + auto lib = Q.getResolvedLib(platformSymbolName("sayB")); + ASSERT_TRUE(lib.has_value()) << "sayB should be resolved"; + EXPECT_TRUE(endsWith(lib->str(), libname("B"))) + << "sayB resolved to: " << lib->str(); + } + + // sayZ should resolve to B.dylib + { + auto lib = Q.getResolvedLib(platformSymbolName("sayZ")); + ASSERT_TRUE(lib.has_value()) << "sayZ should be resolved"; + EXPECT_TRUE(endsWith(lib->str(), libname("Z"))) + << "sayZ resolved to: " << lib->str(); + } + + EXPECT_TRUE(Q.allResolved()); + }); + + EXPECT_TRUE(CallbackRan); +} + +// stress SymbolQuery with the real resolve flow +// And resolve libC dependency libA, libB, libZ --- +TEST_F(LibraryResolverIT, ResolveManySymbols) { + auto Stup = LibraryResolver::Setup::create({BaseDir}); + auto Driver = LibraryResolutionDriver::create(Stup); + ASSERT_NE(Driver, nullptr); + Driver->addScanPath(libdir("C"), PathType::User); + + // Many duplicates to provoke concurrent updates inside SymbolQuery + std::vector<std::string> Syms = { + platformSymbolName("sayA"), platformSymbolName("sayB"), + platformSymbolName("sayA"), platformSymbolName("sayB"), + platformSymbolName("sayZ"), platformSymbolName("sayZ"), + platformSymbolName("sayZ"), platformSymbolName("sayZ"), + platformSymbolName("sayA"), platformSymbolName("sayB"), + platformSymbolName("sayA"), platformSymbolName("sayB")}; + + bool CallbackRan = false; + Driver->resolveSymbols(Syms, [&](SymbolQuery &Q) { + CallbackRan = true; + EXPECT_TRUE(Q.isResolved(platformSymbolName("sayA"))); + EXPECT_TRUE(Q.isResolved(platformSymbolName("sayB"))); + EXPECT_TRUE(Q.isResolved(platformSymbolName("sayZ"))); + + auto A = Q.getResolvedLib(platformSymbolName("sayA")); + auto B = Q.getResolvedLib(platformSymbolName("sayB")); + auto Z = Q.getResolvedLib(platformSymbolName("sayZ")); + ASSERT_TRUE(A.has_value()); + ASSERT_TRUE(B.has_value()); + ASSERT_TRUE(Z.has_value()); + EXPECT_TRUE(endsWith(A->str(), libname("A"))); + EXPECT_TRUE(endsWith(B->str(), libname("B"))); + EXPECT_TRUE(endsWith(Z->str(), libname("Z"))); + EXPECT_TRUE(Q.allResolved()); + }); + + EXPECT_TRUE(CallbackRan); +} + +TEST_F(LibraryResolverIT, ScanAndResolveDependencyGraph) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + LibraryScanHelper ScanH({}, LibPathCache, PResolver); + + ScanH.addBasePath(libdir("C"), PathType::User); + + LibraryManager LibMgr; + LibraryScanner Scanner(ScanH, LibMgr); + + Scanner.scanNext(PathType::User, 0); + + size_t numLibs = 0; + LibMgr.forEachLibrary([&](const LibraryInfo &L) { + numLibs++; + return true; + }); + + EXPECT_GT(numLibs, 0u) << "Expected at least one library scanned"; + + // Validate that each scanned library path is resolvable + std::error_code EC; + LibMgr.forEachLibrary([&](const LibraryInfo &L) { + auto R = PResolver->resolve(L.getFullPath(), EC); + EXPECT_TRUE(R.has_value()); + EXPECT_FALSE(EC); + return true; + }); +} + +TEST_F(LibraryResolverIT, ScanEmptyPath) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + LibraryScanHelper ScanH({}, LibPathCache, PResolver); + + ScanH.addBasePath("/tmp/empty", PathType::User); + + LibraryManager LibMgr; + LibraryScanner Scanner(ScanH, LibMgr); + + Scanner.scanNext(PathType::User, 0); + + size_t count = 0; + LibMgr.forEachLibrary([&](const LibraryInfo &) { + count++; + return true; + }); + EXPECT_EQ(count, 0u); +} + +TEST_F(LibraryResolverIT, PathResolverResolvesKnownPaths) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + std::error_code EC; + auto Missing = PResolver->resolve("temp/foo/bar", EC); + EXPECT_FALSE(Missing.has_value()) << "Unexpectedly resolved a bogus path"; + EXPECT_TRUE(EC) << "Expected error resolving path"; + + auto DirPath = PResolver->resolve(BaseDir, EC); + ASSERT_TRUE(DirPath.has_value()); + EXPECT_FALSE(EC) << "Expected no error resolving path"; + EXPECT_EQ(*DirPath, BaseDir); + + auto DylibPath = PResolver->resolve(lib("C"), EC); + ASSERT_TRUE(DylibPath.has_value()); + EXPECT_FALSE(EC) << "Expected no error resolving path"; + EXPECT_EQ(*DylibPath, lib("C")); +} + +TEST_F(LibraryResolverIT, PathResolverNormalizesDotAndDotDot) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + std::error_code EC; + + // e.g. BaseDir + "/./C/../C/C.dylib" → BaseDir + "/C.dylib" + std::string Messy = BaseDir + "/C/./../C/./libC" + ext; + auto Resolved = PResolver->resolve(Messy, EC); + ASSERT_TRUE(Resolved.has_value()); + EXPECT_FALSE(EC); + EXPECT_EQ(*Resolved, lib("C")) << "Expected realpath to collapse . and .."; +} + +#if !defined(_WIN32) +TEST_F(LibraryResolverIT, PathResolverFollowsSymlinks) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + std::error_code EC; + + // Create a symlink temp -> BaseDir (only if filesystem allows it) + std::string linkName = BaseDir + withext("/link_to_C"); + std::string target = lib("C"); + if (::symlink(target.c_str(), linkName.c_str()) != 0) + GTEST_SKIP() << "Failed to create symlink: " << strerror(errno); + + auto resolved = PResolver->resolve(linkName, EC); + ASSERT_TRUE(resolved.has_value()); + EXPECT_FALSE(EC); + EXPECT_EQ(*resolved, target); + + (void)::unlink(linkName.c_str()); // cleanup +} + +TEST_F(LibraryResolverIT, PathResolverCachesResults) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + SmallString<128> TmpDylib; + std::error_code EC; + EC = sys::fs::createUniqueFile(withext("A-copy"), TmpDylib); + if (EC) + GTEST_SKIP() << "Failed to create temp dylib" << EC.message(); + + EC = sys::fs::copy_file(lib("A"), TmpDylib); + if (EC) + GTEST_SKIP() << "Failed to copy libA: " << EC.message(); + EC.clear(); + + // First resolve -> should populate LibPathCache + auto first = PResolver->resolve(TmpDylib, EC); + ASSERT_TRUE(first.has_value()); + + // Forcefully remove the file from disk + (void)::unlink(TmpDylib.c_str()); + + // Second resolve -> should still succeed from LibPathCache + auto second = PResolver->resolve(TmpDylib, EC); + EXPECT_TRUE(second.has_value()); + EXPECT_EQ(*second, *first); +} +#endif + +TEST_F(LibraryResolverIT, LoaderPathSubstitutionAndResolve) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + DylibSubstitutor substitutor; + substitutor.configure(libdir("C")); +#if defined(__APPLE__) + // Substitute @loader_path with BaseDir + std::string substituted = + substitutor.substitute(withext("@loader_path/libC")); +#elif defined(__linux__) + // Substitute $origin with BaseDir + std::string substituted = substitutor.substitute(withext("$ORIGIN/libC")); +#endif + ASSERT_FALSE(substituted.empty()); + EXPECT_EQ(substituted, lib("C")); + + // Now try resolving the substituted path + std::error_code EC; + auto resolved = PResolver->resolve(substituted, EC); + ASSERT_TRUE(resolved.has_value()) << "Expected to resolve substituted dylib"; + EXPECT_EQ(*resolved, lib("C")); + EXPECT_FALSE(EC) << "Expected no error resolving substituted dylib"; +} + +TEST_F(LibraryResolverIT, ResolveFromUsrOrSystemPaths) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + DylibPathValidator validator(*PResolver); + + std::vector<std::string> Paths = {"/foo/bar/", "temp/foo", libdir("C"), + libdir("A"), libdir("B"), libdir("Z")}; + + SmallVector<StringRef> P(Paths.begin(), Paths.end()); + + DylibResolver Resolver(validator); + Resolver.configure("", {{P, SearchPathType::UsrOrSys}}); + + // Check "C" + auto ValOptC = Resolver.resolve("libC", true); + EXPECT_TRUE(ValOptC.has_value()); + EXPECT_EQ(*ValOptC, lib("C")); + + auto ValOptCdylib = Resolver.resolve(withext("libC")); + EXPECT_TRUE(ValOptCdylib.has_value()); + EXPECT_EQ(*ValOptCdylib, lib("C")); + + // Check "A" + auto ValOptA = Resolver.resolve("libA", true); + EXPECT_TRUE(ValOptA.has_value()); + EXPECT_EQ(*ValOptA, lib("A")); + + auto ValOptAdylib = Resolver.resolve(withext("libA")); + EXPECT_TRUE(ValOptAdylib.has_value()); + EXPECT_EQ(*ValOptAdylib, lib("A")); + + // Check "B" + auto ValOptB = Resolver.resolve("libB", true); + EXPECT_TRUE(ValOptB.has_value()); + EXPECT_EQ(*ValOptB, lib("B")); + + auto ValOptBdylib = Resolver.resolve(withext("libB")); + EXPECT_TRUE(ValOptBdylib.has_value()); + EXPECT_EQ(*ValOptBdylib, lib("B")); + + // Check "Z" + auto ValOptZ = Resolver.resolve("libZ", true); + EXPECT_TRUE(ValOptZ.has_value()); + EXPECT_EQ(*ValOptZ, lib("Z")); + + auto ValOptZdylib = Resolver.resolve(withext("libZ")); + EXPECT_TRUE(ValOptZdylib.has_value()); + EXPECT_EQ(*ValOptZdylib, lib("Z")); +} + +#if defined(__APPLE__) +TEST_F(LibraryResolverIT, ResolveViaLoaderPathAndRPathSubstitution) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + DylibPathValidator validator(*PResolver); + + std::vector<std::string> Paths = {"@loader_path/../A", "@loader_path/../B", + "@loader_path/../C", "@loader_path/../Z"}; + + SmallVector<StringRef> P(Paths.begin(), Paths.end()); + + DylibResolver Resolver(validator); + + // Use only RPath config + Resolver.configure(lib("C"), {{P, SearchPathType::RPath}}); + + // --- Check A --- + auto ValOptA = Resolver.resolve("@rpath/libA", true); + EXPECT_TRUE(ValOptA.has_value()); + EXPECT_EQ(*ValOptA, lib("A")); + + auto ValOptAdylib = Resolver.resolve(withext("@rpath/libA")); + EXPECT_TRUE(ValOptAdylib.has_value()); + EXPECT_EQ(*ValOptAdylib, lib("A")); + + // --- Check B --- + auto ValOptB = Resolver.resolve("@rpath/libB", true); + EXPECT_TRUE(ValOptB.has_value()); + EXPECT_EQ(*ValOptB, lib("B")); + + auto ValOptBdylib = Resolver.resolve(withext("@rpath/libB")); + EXPECT_TRUE(ValOptBdylib.has_value()); + EXPECT_EQ(*ValOptBdylib, lib("B")); + + // --- Check Z --- + auto ValOptZ = Resolver.resolve("@rpath/libZ", true); + EXPECT_TRUE(ValOptZ.has_value()); + EXPECT_EQ(*ValOptZ, lib("Z")); + + auto ValOptZdylib = Resolver.resolve(withext("@rpath/libZ")); + EXPECT_TRUE(ValOptZdylib.has_value()); + EXPECT_EQ(*ValOptZdylib, lib("Z")); +} +#endif + +#if defined(__linux__) +TEST_F(LibraryResolverIT, ResolveViaOriginAndRPathSubstitution) { + auto LibPathCache = std::make_shared<LibraryPathCache>(); + auto PResolver = std::make_shared<PathResolver>(LibPathCache); + + DylibPathValidator validator(*PResolver); + + // On Linux, $ORIGIN works like @loader_path + std::vector<std::string> Paths = {"$ORIGIN/../A", "$ORIGIN/../B", + "$ORIGIN/../C", "$ORIGIN/../Z"}; + + SmallVector<StringRef> P(Paths.begin(), Paths.end()); + + DylibResolver Resolver(validator); + + // Use only RPath config + Resolver.configure(lib("C"), {{P, SearchPathType::RunPath}}); + + // --- Check A --- + auto ValOptA = Resolver.resolve("libA", true); + EXPECT_TRUE(ValOptA.has_value()); + EXPECT_EQ(*ValOptA, lib("A")); + + auto valOptASO = Resolver.resolve(withext("libA")); + EXPECT_TRUE(valOptASO.has_value()); + EXPECT_EQ(*valOptASO, lib("A")); + + // --- Check B --- + auto ValOptB = Resolver.resolve("libB", true); + EXPECT_TRUE(ValOptB.has_value()); + EXPECT_EQ(*ValOptB, lib("B")); + + auto valOptBSO = Resolver.resolve(withext("libB")); + EXPECT_TRUE(valOptBSO.has_value()); + EXPECT_EQ(*valOptBSO, lib("B")); + + // --- Check Z --- + auto ValOptZ = Resolver.resolve("libZ", true); + EXPECT_TRUE(ValOptZ.has_value()); + EXPECT_EQ(*ValOptZ, lib("Z")); + + auto valOptZSO = Resolver.resolve(withext("libZ")); + EXPECT_TRUE(valOptZSO.has_value()); + EXPECT_EQ(*valOptZSO, lib("Z")); +} +#endif +} // namespace +#endif // defined(__APPLE__) diff --git a/llvm/unittests/ExecutionEngine/Orc/MapperJITLinkMemoryManagerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/MapperJITLinkMemoryManagerTest.cpp index a5269f7..566fdb8 100644 --- a/llvm/unittests/ExecutionEngine/Orc/MapperJITLinkMemoryManagerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/MapperJITLinkMemoryManagerTest.cpp @@ -13,8 +13,6 @@ #include "llvm/ExecutionEngine/Orc/MemoryMapper.h" #include "llvm/Testing/Support/Error.h" -#include <vector> - using namespace llvm; using namespace llvm::jitlink; using namespace llvm::orc; 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/SimpleExecutorMemoryManagerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/SimpleExecutorMemoryManagerTest.cpp index 9c6f19c..005c67b 100644 --- a/llvm/unittests/ExecutionEngine/Orc/SimpleExecutorMemoryManagerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/SimpleExecutorMemoryManagerTest.cpp @@ -11,7 +11,6 @@ #include "gtest/gtest.h" #include <limits> -#include <vector> using namespace llvm; using namespace llvm::orc; 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 a8706ce..23c3c4d 100644 --- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp +++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp @@ -88,6 +88,7 @@ using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>; using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>; using DynamicAllocators = tomp::clause::DynamicAllocatorsT<TypeTy, IdTy, ExprTy>; +using DynGroupprivate = tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy>; using Enter = tomp::clause::EnterT<TypeTy, IdTy, ExprTy>; using Exclusive = tomp::clause::ExclusiveT<TypeTy, IdTy, ExprTy>; using Fail = tomp::clause::FailT<TypeTy, IdTy, ExprTy>; @@ -276,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 { @@ -1108,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/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index 972dac8..1142c55 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -2657,4 +2657,31 @@ TEST_F(PatternMatchTest, ShiftOrSelf) { EXPECT_EQ(ShAmtC, 0U); } +TEST_F(PatternMatchTest, CommutativeDeferredIntrinsicMatch) { + Value *X = ConstantFP::get(IRB.getDoubleTy(), 1.0); + Value *Y = ConstantFP::get(IRB.getDoubleTy(), 2.0); + + auto CheckMatch = [X, Y](Value *Pattern) { + Value *tX = nullptr, *tY = nullptr; + EXPECT_TRUE( + match(Pattern, m_c_Intrinsic<Intrinsic::minimum>( + m_Value(tX), m_c_Intrinsic<Intrinsic::minimum>( + m_Deferred(tX), m_Value(tY))))); + EXPECT_EQ(tX, X); + EXPECT_EQ(tY, Y); + }; + CheckMatch(IRB.CreateBinaryIntrinsic( + Intrinsic::minimum, X, + IRB.CreateBinaryIntrinsic(Intrinsic::minimum, X, Y))); + CheckMatch(IRB.CreateBinaryIntrinsic( + Intrinsic::minimum, X, + IRB.CreateBinaryIntrinsic(Intrinsic::minimum, Y, X))); + CheckMatch(IRB.CreateBinaryIntrinsic( + Intrinsic::minimum, IRB.CreateBinaryIntrinsic(Intrinsic::minimum, X, Y), + X)); + CheckMatch(IRB.CreateBinaryIntrinsic( + Intrinsic::minimum, IRB.CreateBinaryIntrinsic(Intrinsic::minimum, Y, X), + X)); +} + } // anonymous namespace. diff --git a/llvm/unittests/IR/VFABIDemanglerTest.cpp b/llvm/unittests/IR/VFABIDemanglerTest.cpp index e30e0f8..7d94613 100644 --- a/llvm/unittests/IR/VFABIDemanglerTest.cpp +++ b/llvm/unittests/IR/VFABIDemanglerTest.cpp @@ -15,7 +15,6 @@ #include "llvm/IR/Module.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" -#include <optional> using namespace llvm; 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/MC/SystemZ/SystemZMCDisassemblerTest.cpp b/llvm/unittests/MC/SystemZ/SystemZMCDisassemblerTest.cpp index 87fad37..25c22d1 100644 --- a/llvm/unittests/MC/SystemZ/SystemZMCDisassemblerTest.cpp +++ b/llvm/unittests/MC/SystemZ/SystemZMCDisassemblerTest.cpp @@ -61,7 +61,7 @@ Context &getContext() { class SystemZMCSymbolizerTest : public MCSymbolizer { public: SystemZMCSymbolizerTest(MCContext &MC) : MCSymbolizer(MC, nullptr) {} - ~SystemZMCSymbolizerTest() override {} + ~SystemZMCSymbolizerTest() override = default; bool tryAddingSymbolicOperand([[maybe_unused]] MCInst &Inst, [[maybe_unused]] raw_ostream &CStream, diff --git a/llvm/unittests/MC/X86/X86MCDisassemblerTest.cpp b/llvm/unittests/MC/X86/X86MCDisassemblerTest.cpp index 286528f..6d44151 100644 --- a/llvm/unittests/MC/X86/X86MCDisassemblerTest.cpp +++ b/llvm/unittests/MC/X86/X86MCDisassemblerTest.cpp @@ -62,7 +62,7 @@ Context &getContext() { class X86MCSymbolizerTest : public MCSymbolizer { public: X86MCSymbolizerTest(MCContext &MC) : MCSymbolizer(MC, nullptr) {} - ~X86MCSymbolizerTest() override {} + ~X86MCSymbolizerTest() override = default; struct OpInfo { int64_t Value = 0; diff --git a/llvm/unittests/MIR/MachineMetadata.cpp b/llvm/unittests/MIR/MachineMetadata.cpp index 0f038d9..8c36377 100644 --- a/llvm/unittests/MIR/MachineMetadata.cpp +++ b/llvm/unittests/MIR/MachineMetadata.cpp @@ -33,7 +33,7 @@ using namespace llvm; class MachineMetadataTest : public testing::Test { public: - MachineMetadataTest() {} + MachineMetadataTest() = default; protected: LLVMContext Context; @@ -205,8 +205,8 @@ TEST_F(MachineMetadataTest, MMSlotTrackerAArch64) { StringRef MIRString = R"MIR( --- | - define i32 @test0(i32* %p) { - %r = load i32, i32* %p, align 4 + define i32 @test0(ptr %p) { + %r = load i32, ptr %p, align 4 ret i32 %r } ... @@ -354,8 +354,8 @@ TEST_F(MachineMetadataTest, MMSlotTrackerX64) { StringRef MIRString = R"MIR( --- | - define i32 @test0(i32* %p) { - %r = load i32, i32* %p, align 4 + define i32 @test0(ptr %p) { + %r = load i32, ptr %p, align 4 ret i32 %r } ... @@ -446,8 +446,8 @@ TEST_F(MachineMetadataTest, MMSlotTrackerAMDGPU) { StringRef MIRString = R"MIR( --- | - define i32 @test0(i32* %p) { - %r = load i32, i32* %p, align 4 + define i32 @test0(ptr %p) { + %r = load i32, ptr %p, align 4 ret i32 %r } ... diff --git a/llvm/unittests/MIR/MachineStableHashTest.cpp b/llvm/unittests/MIR/MachineStableHashTest.cpp index ea0de1a..bedecb1 100644 --- a/llvm/unittests/MIR/MachineStableHashTest.cpp +++ b/llvm/unittests/MIR/MachineStableHashTest.cpp @@ -22,7 +22,7 @@ using namespace llvm; class MachineStableHashTest : public testing::Test { public: - MachineStableHashTest() {} + MachineStableHashTest() = default; protected: LLVMContext Context; 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/Object/XCOFFObjectFileTest.cpp b/llvm/unittests/Object/XCOFFObjectFileTest.cpp index f696cde..10217f6 100644 --- a/llvm/unittests/Object/XCOFFObjectFileTest.cpp +++ b/llvm/unittests/Object/XCOFFObjectFileTest.cpp @@ -18,10 +18,10 @@ using namespace llvm::XCOFF; TEST(XCOFFObjectFileTest, XCOFFObjectType) { // Create an arbitrary object of a non-XCOFF type and test that // dyn_cast<XCOFFObjectFile> returns null for it. - char Buf[sizeof(typename ELF64LE::Ehdr)] = {}; + char Buf[sizeof(ELF64LE::Ehdr)] = {}; memcpy(Buf, "\177ELF", 4); - auto *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(Buf); + auto *EHdr = reinterpret_cast<ELF64LE::Ehdr *>(Buf); EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64; EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; diff --git a/llvm/unittests/Option/OptionSubCommandsTest.cpp b/llvm/unittests/Option/OptionSubCommandsTest.cpp index e31a326..d4744c9 100644 --- a/llvm/unittests/Option/OptionSubCommandsTest.cpp +++ b/llvm/unittests/Option/OptionSubCommandsTest.cpp @@ -192,6 +192,19 @@ TYPED_TEST(OptSubCommandTableTest, SubCommandParsing) { std::string::npos, ErrMsg.find("Option [lowercase] is not valid for SubCommand [bar]")); } + + { + // Test case 7: Check valid use of a valid subcommand following more + // positional arguments. + const char *Args[] = {"bar", "input"}; + InputArgList AL = T.ParseArgs(Args, MAI, MAC); + StringRef SC = AL.getSubCommand( + T.getSubCommands(), HandleMultipleSubcommands, HandleOtherPositionals); + EXPECT_EQ(SC, "bar"); // valid subcommand + EXPECT_NE(std::string::npos, + ErrMsg.find("Unregistered positionals passed")); + EXPECT_NE(std::string::npos, ErrMsg.find("input")); + } } TYPED_TEST(OptSubCommandTableTest, SubCommandHelp) { 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/AlignOfTest.cpp b/llvm/unittests/Support/AlignOfTest.cpp index 979f2cf..53358a28 100644 --- a/llvm/unittests/Support/AlignOfTest.cpp +++ b/llvm/unittests/Support/AlignOfTest.cpp @@ -79,14 +79,14 @@ struct V8 : V5, virtual V6, V7 { double zz; double S6::f() { return 0.0; } float D2::g() { return 0.0f; } -V1::~V1() {} -V2::~V2() {} -V3::~V3() {} -V4::~V4() {} -V5::~V5() {} -V6::~V6() {} -V7::~V7() {} -V8::~V8() {} +V1::~V1() = default; +V2::~V2() = default; +V3::~V3() = default; +V4::~V4() = default; +V5::~V5() = default; +V6::~V6() = default; +V7::~V7() = default; +V8::~V8() = default; template <typename M> struct T { M m; }; diff --git a/llvm/unittests/Support/AllocatorTest.cpp b/llvm/unittests/Support/AllocatorTest.cpp index 1069e43..2337f34 100644 --- a/llvm/unittests/Support/AllocatorTest.cpp +++ b/llvm/unittests/Support/AllocatorTest.cpp @@ -235,7 +235,7 @@ class MockSlabAllocator { static size_t LastSlabSize; public: - ~MockSlabAllocator() { } + ~MockSlabAllocator() = default; void *Allocate(size_t Size, size_t /*Alignment*/) { // Allocate space for the alignment, the slab, and a void* that goes right diff --git a/llvm/unittests/Support/BinaryStreamTest.cpp b/llvm/unittests/Support/BinaryStreamTest.cpp index 70cd403..06ed12b 100644 --- a/llvm/unittests/Support/BinaryStreamTest.cpp +++ b/llvm/unittests/Support/BinaryStreamTest.cpp @@ -110,7 +110,7 @@ constexpr uint32_t NumStreams = 2 * NumEndians; class BinaryStreamTest : public testing::Test { public: - BinaryStreamTest() {} + BinaryStreamTest() = default; void SetUp() override { Streams.clear(); diff --git a/llvm/unittests/Support/Casting.cpp b/llvm/unittests/Support/Casting.cpp index 18327f6..0df8b9f 100644 --- a/llvm/unittests/Support/Casting.cpp +++ b/llvm/unittests/Support/Casting.cpp @@ -23,7 +23,7 @@ template <typename T> IllegalCast *cast(...) { return nullptr; } // with conversion facility // struct bar { - bar() {} + bar() = default; bar(const bar &) = delete; struct foo *baz(); struct foo *caz(); @@ -36,7 +36,7 @@ struct foo { }; struct base { - virtual ~base() {} + virtual ~base() = default; }; struct derived : public base { @@ -375,12 +375,12 @@ namespace inferred_upcasting { class Base { public: // No classof. We are testing that the upcast is inferred. - Base() {} + Base() = default; }; class Derived : public Base { public: - Derived() {} + Derived() = default; }; // Even with no explicit classof() in Base, we should still be able to cast @@ -529,7 +529,7 @@ TEST(CastingTest, smart_dyn_cast_or_null) { #ifndef NDEBUG namespace assertion_checks { struct Base { - virtual ~Base() {} + virtual ~Base() = default; }; struct Derived : public Base { @@ -561,6 +561,47 @@ TEST(CastingTest, assertion_check_unique_ptr) { << "Invalid cast of const ref did not cause an abort()"; } +TEST(Casting, StaticCastPredicate) { + uint32_t Value = 1; + + static_assert( + std::is_same_v<decltype(StaticCastTo<uint64_t>(Value)), uint64_t>); +} + +TEST(Casting, LLVMRTTIPredicates) { + struct Base { + enum Kind { BK_Base, BK_Derived }; + const Kind K; + Base(Kind K = BK_Base) : K(K) {} + Kind getKind() const { return K; } + virtual ~Base() = default; + }; + + struct Derived : Base { + Derived() : Base(BK_Derived) {} + static bool classof(const Base *B) { return B->getKind() == BK_Derived; } + bool Field = false; + }; + + Base B; + Derived D; + Base *BD = &D; + Base *Null = nullptr; + + // Pointers. + EXPECT_EQ(DynCastTo<Derived>(BD), &D); + EXPECT_EQ(CastTo<Derived>(BD), &D); + EXPECT_EQ(DynCastTo<Derived>(&B), nullptr); + EXPECT_EQ(CastIfPresentTo<Derived>(BD), &D); + EXPECT_EQ(CastIfPresentTo<Derived>(Null), nullptr); + EXPECT_EQ(DynCastIfPresentTo<Derived>(BD), &D); + EXPECT_EQ(DynCastIfPresentTo<Derived>(Null), nullptr); + + Base &R = D; + CastTo<Derived>(R).Field = true; + EXPECT_TRUE(D.Field); +} + } // end namespace assertion_checks #endif } // end namespace diff --git a/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp b/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp index 8ff2c30..8f115ae 100644 --- a/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp +++ b/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp @@ -8,6 +8,8 @@ #include "PipSqueak.h" +#include <vector> + struct Global { std::string *Str; std::vector<std::string> *Vec; diff --git a/llvm/unittests/Support/DynamicLibrary/PipSqueak.h b/llvm/unittests/Support/DynamicLibrary/PipSqueak.h index dc069ca..f69c7bfa 100644 --- a/llvm/unittests/Support/DynamicLibrary/PipSqueak.h +++ b/llvm/unittests/Support/DynamicLibrary/PipSqueak.h @@ -15,11 +15,9 @@ #pragma warning(disable: 4530) #pragma warning(disable: 4577) #include <string> -#include <vector> #pragma warning(pop) #else #include <string> -#include <vector> #endif #if defined(_WIN32) || defined(__CYGWIN__) 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/InstructionCostTest.cpp b/llvm/unittests/Support/InstructionCostTest.cpp index efe8388..5392689 100644 --- a/llvm/unittests/Support/InstructionCostTest.cpp +++ b/llvm/unittests/Support/InstructionCostTest.cpp @@ -14,7 +14,7 @@ using namespace llvm; namespace { struct CostTest : public testing::Test { - CostTest() {} + CostTest() = default; }; } // namespace 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/OptimizedStructLayoutTest.cpp b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp index e8cd5f4..0bcae0d 100644 --- a/llvm/unittests/Support/OptimizedStructLayoutTest.cpp +++ b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp @@ -25,7 +25,7 @@ class LayoutTest { bool Verified = false; public: - LayoutTest() {} + LayoutTest() = default; LayoutTest(const LayoutTest &) = delete; LayoutTest &operator=(const LayoutTest &) = delete; ~LayoutTest() { assert(Verified); } diff --git a/llvm/unittests/Support/ParallelTest.cpp b/llvm/unittests/Support/ParallelTest.cpp index 041067d..c7ecc4e 100644 --- a/llvm/unittests/Support/ParallelTest.cpp +++ b/llvm/unittests/Support/ParallelTest.cpp @@ -15,7 +15,6 @@ #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS #include "llvm/Support/ThreadPool.h" #include "gtest/gtest.h" -#include <array> #include <random> uint32_t array[1024 * 1024]; 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/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp index 750feda..812e0d3 100644 --- a/llvm/unittests/Support/SpecialCaseListTest.cpp +++ b/llvm/unittests/Support/SpecialCaseListTest.cpp @@ -308,43 +308,49 @@ TEST_F(SpecialCaseListTest, Version2) { } TEST_F(SpecialCaseListTest, DotSlash) { - std::unique_ptr<SpecialCaseList> SCL2 = makeSpecialCaseList("[dot]\n" - "fun:./foo\n" - "src:./bar\n" - "[not]\n" - "fun:foo\n" - "src:bar\n"); - std::unique_ptr<SpecialCaseList> SCL3 = makeSpecialCaseList("[dot]\n" - "fun:./foo\n" - "src:./bar\n" - "[not]\n" - "fun:foo\n" - "src:bar\n", - /*Version=*/3); + StringRef IgnoreList = "[dot]\n" + "fun:./foo\n" + "src:./bar\n" + "[not]\n" + "fun:foo\n" + "src:bar\n"; + std::unique_ptr<SpecialCaseList> SCL2 = makeSpecialCaseList(IgnoreList); + std::unique_ptr<SpecialCaseList> SCL3 = + makeSpecialCaseList(IgnoreList, /*Version=*/3); + std::unique_ptr<SpecialCaseList> SCL4 = makeSpecialCaseList(IgnoreList, + /*Version=*/4); EXPECT_TRUE(SCL2->inSection("dot", "fun", "./foo")); EXPECT_TRUE(SCL3->inSection("dot", "fun", "./foo")); + EXPECT_TRUE(SCL4->inSection("dot", "fun", "./foo")); EXPECT_FALSE(SCL2->inSection("dot", "fun", "foo")); EXPECT_FALSE(SCL3->inSection("dot", "fun", "foo")); + EXPECT_FALSE(SCL4->inSection("dot", "fun", "foo")); EXPECT_TRUE(SCL2->inSection("dot", "src", "./bar")); EXPECT_FALSE(SCL3->inSection("dot", "src", "./bar")); + EXPECT_FALSE(SCL4->inSection("dot", "src", "./bar")); EXPECT_FALSE(SCL2->inSection("dot", "src", "bar")); EXPECT_FALSE(SCL3->inSection("dot", "src", "bar")); + EXPECT_FALSE(SCL4->inSection("dot", "src", "bar")); EXPECT_FALSE(SCL2->inSection("not", "fun", "./foo")); EXPECT_FALSE(SCL3->inSection("not", "fun", "./foo")); + EXPECT_FALSE(SCL4->inSection("not", "fun", "./foo")); EXPECT_TRUE(SCL2->inSection("not", "fun", "foo")); EXPECT_TRUE(SCL3->inSection("not", "fun", "foo")); + EXPECT_TRUE(SCL4->inSection("not", "fun", "foo")); EXPECT_FALSE(SCL2->inSection("not", "src", "./bar")); EXPECT_TRUE(SCL3->inSection("not", "src", "./bar")); + EXPECT_TRUE(SCL4->inSection("not", "src", "./bar")); EXPECT_TRUE(SCL2->inSection("not", "src", "bar")); EXPECT_TRUE(SCL3->inSection("not", "src", "bar")); + EXPECT_TRUE(SCL4->inSection("not", "src", "bar")); } TEST_F(SpecialCaseListTest, LinesInSection) { diff --git a/llvm/unittests/Support/ThreadPool.cpp b/llvm/unittests/Support/ThreadPool.cpp index aa7f874..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 @@ -183,6 +184,56 @@ TYPED_TEST(ThreadPoolTest, Async) { ASSERT_EQ(2, i.load()); } +TYPED_TEST(ThreadPoolTest, AsyncMoveOnly) { + CHECK_UNSUPPORTED(); + DefaultThreadPool Pool; + std::promise<int> p; + std::future<int> f = p.get_future(); + Pool.async([this, p = std::move(p)]() mutable { + this->waitForMainThread(); + p.set_value(42); + }); + this->setMainThreadReady(); + Pool.wait(); + 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/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp index 283e5f8..7446c07 100644 --- a/llvm/unittests/Support/YAMLIOTest.cpp +++ b/llvm/unittests/Support/YAMLIOTest.cpp @@ -3221,12 +3221,12 @@ template <> struct TaggedScalarTraits<Scalar> { template <> struct CustomMappingTraits<Map> { static void inputOne(IO &IO, StringRef Key, Map &M) { - IO.mapRequired(Key.str().c_str(), M[Key]); + IO.mapRequired(Key, M[Key]); } static void output(IO &IO, Map &M) { for (auto &N : M) - IO.mapRequired(N.getKey().str().c_str(), N.getValue()); + IO.mapRequired(N.getKey(), N.getValue()); } }; diff --git a/llvm/unittests/Support/raw_ostream_proxy_test.cpp b/llvm/unittests/Support/raw_ostream_proxy_test.cpp index 864dda7..446e64a 100644 --- a/llvm/unittests/Support/raw_ostream_proxy_test.cpp +++ b/llvm/unittests/Support/raw_ostream_proxy_test.cpp @@ -40,8 +40,6 @@ public: bool IsDisplayed = false; }; -constexpr size_t BufferedNoPwriteSmallVectorStream::PreferredBufferSize; - TEST(raw_ostream_proxyTest, write) { // Besides confirming that "write" works, this test confirms that the proxy // takes on the buffer from the stream it's proxying, such that writes to the diff --git a/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp b/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp index 4dfc0bc..a835a34 100644 --- a/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp +++ b/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp @@ -36,10 +36,8 @@ static std::string AArch64InstPrinterTestPrintAlignedLabel(uint64_t value) { MCAsmInfo MAI; MCInstrInfo MII; MCRegisterInfo MRI; - MCSubtargetInfo STI(Triple(""), "", "", "", {}, - ArrayRef((SubtargetFeatureKV *)NULL, (size_t)0), - ArrayRef((SubtargetSubTypeKV *)NULL, (size_t)0), NULL, - NULL, NULL, NULL, NULL, NULL); + MCSubtargetInfo STI(Triple(""), "", "", "", {}, {}, {}, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr); MCContext Ctx(Triple(""), &MAI, &MRI, &STI); MCInst MI; 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/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp index d7f2908..c36ed93 100644 --- a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp +++ b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp @@ -75,7 +75,7 @@ TEST(WebAssemblyExceptionInfoTest, TEST0) { declare i32 @__gxx_wasm_personality_v0(...) - define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { + define void @test0() personality ptr @__gxx_wasm_personality_v0 { unreachable } @@ -237,7 +237,7 @@ TEST(WebAssemblyExceptionInfoTest, TEST1) { declare i32 @__gxx_wasm_personality_v0(...) - define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { + define void @test1() personality ptr @__gxx_wasm_personality_v0 { unreachable } diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index bfc1275..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 @@ -1204,6 +1204,7 @@ Experimental extensions zvfofp8min 0.2 zvkgs 0.7 zvqdotq 0.0 + smpmpmt 0.6 svukte 0.3 xqccmp 0.3 xqcia 0.7 diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 759109a..92e2d77 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -737,8 +737,7 @@ TEST(TargetParserTest, ARMFPUNeonSupportLevel) { for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); FK <= ARM::FPUKind::FK_LAST; FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) - if (FK == ARM::FK_LAST || - ARM::getFPUName(FK).find("neon") == std::string::npos) + if (FK == ARM::FK_LAST || !ARM::getFPUName(FK).contains("neon")) EXPECT_EQ(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK)); else EXPECT_NE(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK)); @@ -748,9 +747,8 @@ TEST(TargetParserTest, ARMFPURestriction) { for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); FK <= ARM::FPUKind::FK_LAST; FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) { - if (FK == ARM::FK_LAST || - (ARM::getFPUName(FK).find("d16") == std::string::npos && - ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos)) + if (FK == ARM::FK_LAST || (!ARM::getFPUName(FK).contains("d16") && + !ARM::getFPUName(FK).contains("vfpv3xd"))) EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK)); else EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK)); @@ -1415,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, @@ -1454,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; @@ -1513,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")); @@ -1578,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. @@ -1698,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"}, @@ -1756,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/TextAPI/TextStubHelpers.h b/llvm/unittests/TextAPI/TextStubHelpers.h index 7c9c74a..87ca7e1 100644 --- a/llvm/unittests/TextAPI/TextStubHelpers.h +++ b/llvm/unittests/TextAPI/TextStubHelpers.h @@ -8,7 +8,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/TextAPI/InterfaceFile.h" -#include <algorithm> #include <string> #ifndef TEXT_STUB_HELPERS_H diff --git a/llvm/unittests/TextAPI/TextStubV1Tests.cpp b/llvm/unittests/TextAPI/TextStubV1Tests.cpp index 3778f75..950e79d 100644 --- a/llvm/unittests/TextAPI/TextStubV1Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV1Tests.cpp @@ -12,7 +12,6 @@ #include "llvm/TextAPI/TextAPIWriter.h" #include "gtest/gtest.h" #include <string> -#include <vector> using namespace llvm; using namespace llvm::MachO; diff --git a/llvm/unittests/TextAPI/TextStubV2Tests.cpp b/llvm/unittests/TextAPI/TextStubV2Tests.cpp index 11dc0b4..548f748 100644 --- a/llvm/unittests/TextAPI/TextStubV2Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV2Tests.cpp @@ -11,7 +11,6 @@ #include "llvm/TextAPI/TextAPIWriter.h" #include "gtest/gtest.h" #include <string> -#include <vector> using namespace llvm; using namespace llvm::MachO; diff --git a/llvm/unittests/TextAPI/TextStubV4Tests.cpp b/llvm/unittests/TextAPI/TextStubV4Tests.cpp index 350ef41..1a10c91 100644 --- a/llvm/unittests/TextAPI/TextStubV4Tests.cpp +++ b/llvm/unittests/TextAPI/TextStubV4Tests.cpp @@ -12,7 +12,6 @@ #include "llvm/TextAPI/TextAPIWriter.h" #include "gtest/gtest.h" #include <string> -#include <vector> using namespace llvm; using namespace llvm::MachO; diff --git a/llvm/unittests/Transforms/IPO/AttributorTest.cpp b/llvm/unittests/Transforms/IPO/AttributorTest.cpp index e442dae..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 { @@ -78,17 +77,17 @@ TEST_F(AttributorTestBase, AAReachabilityTest) { const char *ModuleString = R"( @x = external global i32 define void @func4() { - store i32 0, i32* @x + store i32 0, ptr @x ret void } define internal void @func3() { - store i32 0, i32* @x + store i32 0, ptr @x ret void } define internal void @func8() { - store i32 0, i32* @x + store i32 0, ptr @x ret void } @@ -105,7 +104,7 @@ TEST_F(AttributorTestBase, AAReachabilityTest) { } declare void @unknown() - define internal void @func5(void ()* %ptr) { + define internal void @func5(ptr %ptr) { entry: call void %ptr() call void @unknown() @@ -114,8 +113,8 @@ TEST_F(AttributorTestBase, AAReachabilityTest) { define void @func6() { entry: - store i32 0, i32* @x - call void @func5(void ()* @func3) + store i32 0, ptr @x + call void @func5(ptr @func3) ret void } diff --git a/llvm/unittests/Transforms/Scalar/LICMTest.cpp b/llvm/unittests/Transforms/Scalar/LICMTest.cpp index 98a69bb..a193993b 100644 --- a/llvm/unittests/Transforms/Scalar/LICMTest.cpp +++ b/llvm/unittests/Transforms/Scalar/LICMTest.cpp @@ -37,13 +37,13 @@ TEST(LICMTest, TestSCEVInvalidationOnHoisting) { SMDiagnostic Error; StringRef Text = R"( - define void @foo(i64* %ptr) { + define void @foo(ptr %ptr) { entry: br label %loop loop: %iv = phi i64 [ 0, %entry ], [ %iv.inc, %loop ] - %n = load i64, i64* %ptr, !invariant.load !0 + %n = load i64, ptr %ptr, !invariant.load !0 %iv.inc = add i64 %iv, 1 %cmp = icmp ult i64 %iv.inc, %n br i1 %cmp, label %loop, label %exit @@ -62,17 +62,17 @@ TEST(LICMTest, TestSCEVInvalidationOnHoisting) { BasicBlock &EntryBB = F->getEntryBlock(); BasicBlock *LoopBB = EntryBB.getUniqueSuccessor(); - // Select `load i64, i64* %ptr`. + // Select `load i64, ptr %ptr`. Instruction *IBefore = &*LoopBB->getFirstNonPHIIt(); // Make sure the right instruction was selected. ASSERT_TRUE(isa<LoadInst>(IBefore)); - // Upon this query SCEV caches disposition of <load i64, i64* %ptr> SCEV. + // Upon this query SCEV caches disposition of <load i64, ptr %ptr> SCEV. ASSERT_EQ(SE.getBlockDisposition(SE.getSCEV(IBefore), LoopBB), ScalarEvolution::BlockDisposition::DominatesBlock); MPM.run(*M, MAM); - // Select `load i64, i64* %ptr` after it was hoisted. + // Select `load i64, ptr %ptr` after it was hoisted. Instruction *IAfter = &*EntryBB.getFirstNonPHIIt(); // Make sure the right instruction was selected. ASSERT_TRUE(isa<LoadInst>(IAfter)); @@ -84,7 +84,7 @@ TEST(LICMTest, TestSCEVInvalidationOnHoisting) { SE.getBlockDisposition(SE.getSCEV(IAfter), LoopBB); // If LICM have properly invalidated SCEV, - // 1. SCEV of <load i64, i64* %ptr> should properly dominate the "loop" BB, + // 1. SCEV of <load i64, ptr %ptr> should properly dominate the "loop" BB, // 2. extra invalidation shouldn't change result of the query. EXPECT_EQ(DispositionBeforeInvalidation, ScalarEvolution::BlockDisposition::ProperlyDominatesBlock); diff --git a/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp b/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp index cb3d1001..88eaa87 100644 --- a/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp +++ b/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp @@ -265,21 +265,21 @@ protected: public: LoopPassManagerTest() : M(parseIR(Context, - "define void @f(i1* %ptr) {\n" + "define void @f(ptr %ptr) {\n" "entry:\n" " br label %loop.0\n" "loop.0:\n" - " %cond.0 = load volatile i1, i1* %ptr\n" + " %cond.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0, label %loop.0.0.ph, label %end\n" "loop.0.0.ph:\n" " br label %loop.0.0\n" "loop.0.0:\n" - " %cond.0.0 = load volatile i1, i1* %ptr\n" + " %cond.0.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n" "loop.0.1.ph:\n" " br label %loop.0.1\n" "loop.0.1:\n" - " %cond.0.1 = load volatile i1, i1* %ptr\n" + " %cond.0.1 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.1, label %loop.0.1, label %loop.0.latch\n" "loop.0.latch:\n" " br label %loop.0\n" @@ -287,11 +287,11 @@ public: " ret void\n" "}\n" "\n" - "define void @g(i1* %ptr) {\n" + "define void @g(ptr %ptr) {\n" "entry:\n" " br label %loop.g.0\n" "loop.g.0:\n" - " %cond.0 = load volatile i1, i1* %ptr\n" + " %cond.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0, label %loop.g.0, label %end\n" "end:\n" " ret void\n" @@ -861,26 +861,26 @@ TEST_F(LoopPassManagerTest, IndirectOuterPassInvalidation) { TEST_F(LoopPassManagerTest, LoopChildInsertion) { // Super boring module with three loops in a single loop nest. - M = parseIR(Context, "define void @f(i1* %ptr) {\n" + M = parseIR(Context, "define void @f(ptr %ptr) {\n" "entry:\n" " br label %loop.0\n" "loop.0:\n" - " %cond.0 = load volatile i1, i1* %ptr\n" + " %cond.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0, label %loop.0.0.ph, label %end\n" "loop.0.0.ph:\n" " br label %loop.0.0\n" "loop.0.0:\n" - " %cond.0.0 = load volatile i1, i1* %ptr\n" + " %cond.0.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n" "loop.0.1.ph:\n" " br label %loop.0.1\n" "loop.0.1:\n" - " %cond.0.1 = load volatile i1, i1* %ptr\n" + " %cond.0.1 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.1, label %loop.0.1, label %loop.0.2.ph\n" "loop.0.2.ph:\n" " br label %loop.0.2\n" "loop.0.2:\n" - " %cond.0.2 = load volatile i1, i1* %ptr\n" + " %cond.0.2 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.2, label %loop.0.2, label %loop.0.latch\n" "loop.0.latch:\n" " br label %loop.0\n" @@ -1064,28 +1064,28 @@ TEST_F(LoopPassManagerTest, LoopChildInsertion) { TEST_F(LoopPassManagerTest, LoopPeerInsertion) { // Super boring module with two loop nests and loop nest with two child // loops. - M = parseIR(Context, "define void @f(i1* %ptr) {\n" + M = parseIR(Context, "define void @f(ptr %ptr) {\n" "entry:\n" " br label %loop.0\n" "loop.0:\n" - " %cond.0 = load volatile i1, i1* %ptr\n" + " %cond.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0, label %loop.0.0.ph, label %loop.2.ph\n" "loop.0.0.ph:\n" " br label %loop.0.0\n" "loop.0.0:\n" - " %cond.0.0 = load volatile i1, i1* %ptr\n" + " %cond.0.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.0, label %loop.0.0, label %loop.0.2.ph\n" "loop.0.2.ph:\n" " br label %loop.0.2\n" "loop.0.2:\n" - " %cond.0.2 = load volatile i1, i1* %ptr\n" + " %cond.0.2 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.2, label %loop.0.2, label %loop.0.latch\n" "loop.0.latch:\n" " br label %loop.0\n" "loop.2.ph:\n" " br label %loop.2\n" "loop.2:\n" - " %cond.2 = load volatile i1, i1* %ptr\n" + " %cond.2 = load volatile i1, ptr %ptr\n" " br i1 %cond.2, label %loop.2, label %end\n" "end:\n" " ret void\n" @@ -1318,31 +1318,31 @@ TEST_F(LoopPassManagerTest, LoopDeletion) { // Build a module with a single loop nest that contains one outer loop with // three subloops, and one of those with its own subloop. We will // incrementally delete all of these to test different deletion scenarios. - M = parseIR(Context, "define void @f(i1* %ptr) {\n" + M = parseIR(Context, "define void @f(ptr %ptr) {\n" "entry:\n" " br label %loop.0\n" "loop.0:\n" - " %cond.0 = load volatile i1, i1* %ptr\n" + " %cond.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0, label %loop.0.0.ph, label %end\n" "loop.0.0.ph:\n" " br label %loop.0.0\n" "loop.0.0:\n" - " %cond.0.0 = load volatile i1, i1* %ptr\n" + " %cond.0.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n" "loop.0.1.ph:\n" " br label %loop.0.1\n" "loop.0.1:\n" - " %cond.0.1 = load volatile i1, i1* %ptr\n" + " %cond.0.1 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.1, label %loop.0.1, label %loop.0.2.ph\n" "loop.0.2.ph:\n" " br label %loop.0.2\n" "loop.0.2:\n" - " %cond.0.2 = load volatile i1, i1* %ptr\n" + " %cond.0.2 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.2, label %loop.0.2.0.ph, label %loop.0.latch\n" "loop.0.2.0.ph:\n" " br label %loop.0.2.0\n" "loop.0.2.0:\n" - " %cond.0.2.0 = load volatile i1, i1* %ptr\n" + " %cond.0.2.0 = load volatile i1, ptr %ptr\n" " br i1 %cond.0.2.0, label %loop.0.2.0, label %loop.0.2.latch\n" "loop.0.2.latch:\n" " br label %loop.0.2\n" diff --git a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp index 4235c93..00d9e9f 100644 --- a/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp +++ b/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp @@ -484,9 +484,9 @@ exit: TEST(BasicBlockUtils, SplitIndirectBrCriticalEdgesIgnorePHIs) { LLVMContext C; std::unique_ptr<Module> M = parseIR(C, R"IR( -define void @crit_edge(i8* %tgt, i1 %cond0, i1 %cond1) { +define void @crit_edge(ptr %tgt, i1 %cond0, i1 %cond1) { entry: - indirectbr i8* %tgt, [label %bb0, label %bb1, label %bb2] + indirectbr ptr %tgt, [label %bb0, label %bb1, label %bb2] bb0: br i1 %cond0, label %bb1, label %bb2 bb1: @@ -526,9 +526,9 @@ bb4: TEST(BasicBlockUtils, SplitIndirectBrCriticalEdges) { LLVMContext C; std::unique_ptr<Module> M = parseIR(C, R"IR( -define void @crit_edge(i8* %tgt, i1 %cond0, i1 %cond1) { +define void @crit_edge(ptr %tgt, i1 %cond0, i1 %cond1) { entry: - indirectbr i8* %tgt, [label %bb0, label %bb1, label %bb2] + indirectbr ptr %tgt, [label %bb0, label %bb1, label %bb2] bb0: br i1 %cond0, label %bb1, label %bb2 bb1: diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp index d990808..237bc6e 100644 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -394,7 +394,7 @@ TEST(CloneLoop, CloneLoopNest) { std::unique_ptr<Module> M = parseIR( Context, - R"(define void @foo(i32* %A, i32 %ub) { + R"(define void @foo(ptr %A, i32 %ub) { entry: %guardcmp = icmp slt i32 0, %ub br i1 %guardcmp, label %for.outer.preheader, label %for.end @@ -408,8 +408,8 @@ for.inner.preheader: for.inner: %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ] %idxprom = sext i32 %i to i64 - %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom - store i32 %i, i32* %arrayidx, align 4 + %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom + store i32 %i, ptr %arrayidx, align 4 %inc = add nsw i32 %i, 1 %cmp = icmp slt i32 %inc, %ub br i1 %cmp, label %for.inner, label %for.inner.exit @@ -728,10 +728,10 @@ TEST(CloneFunction, CloneEmptyFunction) { TEST(CloneFunction, CloneFunctionWithInalloca) { StringRef ImplAssembly = R"( - declare void @a(i32* inalloca(i32)) + declare void @a(ptr inalloca(i32)) define void @foo() { %a = alloca inalloca i32 - call void @a(i32* inalloca(i32) %a) + call void @a(ptr inalloca(i32) %a) ret void } declare void @bar() diff --git a/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp b/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp index 9ea8de3..90f0620 100644 --- a/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp +++ b/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp @@ -154,13 +154,13 @@ TEST(CodeExtractor, ExitBlockOrderingPhis) { %0 = alloca i32, align 4 br label %test0 test0: - %c = load i32, i32* %0, align 4 + %c = load i32, ptr %0, align 4 br label %test1 test1: - %e = load i32, i32* %0, align 4 + %e = load i32, ptr %0, align 4 br i1 true, label %first, label %test test: - %d = load i32, i32* %0, align 4 + %d = load i32, ptr %0, align 4 br i1 true, label %first, label %next first: %1 = phi i32 [ %c, %test ], [ %e, %test1 ] @@ -212,13 +212,13 @@ TEST(CodeExtractor, ExitBlockOrdering) { %0 = alloca i32, align 4 br label %test0 test0: - %c = load i32, i32* %0, align 4 + %c = load i32, ptr %0, align 4 br label %test1 test1: - %e = load i32, i32* %0, align 4 + %e = load i32, ptr %0, align 4 br i1 true, label %first, label %test test: - %d = load i32, i32* %0, align 4 + %d = load i32, ptr %0, align 4 br i1 true, label %first, label %next first: ret void @@ -317,7 +317,7 @@ TEST(CodeExtractor, StoreOutputInvokeResultAfterEHPad) { std::unique_ptr<Module> M(parseAssemblyString(R"invalid( declare i8 @hoge() - define i32 @foo() personality i8* null { + define i32 @foo() personality ptr null { entry: %call = invoke i8 @hoge() to label %invoke.cont unwind label %lpad @@ -326,8 +326,8 @@ TEST(CodeExtractor, StoreOutputInvokeResultAfterEHPad) { unreachable lpad: ; preds = %entry - %0 = landingpad { i8*, i32 } - catch i8* null + %0 = landingpad { ptr, i32 } + catch ptr null br i1 undef, label %catch, label %finally.catchall catch: ; preds = %lpad @@ -342,13 +342,13 @@ TEST(CodeExtractor, StoreOutputInvokeResultAfterEHPad) { unreachable lpad2: ; preds = %invoke.cont2, %catch - %ex.1 = phi i8* [ undef, %invoke.cont2 ], [ null, %catch ] - %1 = landingpad { i8*, i32 } - catch i8* null + %ex.1 = phi ptr [ undef, %invoke.cont2 ], [ null, %catch ] + %1 = landingpad { ptr, i32 } + catch ptr null br label %finally.catchall finally.catchall: ; preds = %lpad33, %lpad - %ex.2 = phi i8* [ %ex.1, %lpad2 ], [ null, %lpad ] + %ex.2 = phi ptr [ %ex.1, %lpad2 ], [ null, %lpad ] unreachable } )invalid", Err, Ctx)); @@ -384,7 +384,7 @@ TEST(CodeExtractor, StoreOutputInvokeResultInExitStub) { std::unique_ptr<Module> M(parseAssemblyString(R"invalid( declare i32 @bar() - define i32 @foo() personality i8* null { + define i32 @foo() personality ptr null { entry: %0 = invoke i32 @bar() to label %exit unwind label %lpad @@ -392,9 +392,9 @@ TEST(CodeExtractor, StoreOutputInvokeResultInExitStub) { ret i32 %0 lpad: - %1 = landingpad { i8*, i32 } + %1 = landingpad { ptr, i32 } cleanup - resume { i8*, i32 } %1 + resume { ptr, i32 } %1 } )invalid", Err, Ctx)); @@ -421,7 +421,7 @@ TEST(CodeExtractor, ExtractAndInvalidateAssumptionCache) { target triple = "aarch64" %b = type { i64 } - declare void @g(i8*) + declare void @g(ptr) declare void @llvm.assume(i1) #0 @@ -430,9 +430,9 @@ TEST(CodeExtractor, ExtractAndInvalidateAssumptionCache) { br label %label label: - %0 = load %b*, %b** inttoptr (i64 8 to %b**), align 8 - %1 = getelementptr inbounds %b, %b* %0, i64 undef, i32 0 - %2 = load i64, i64* %1, align 8 + %0 = load ptr, ptr inttoptr (i64 8 to ptr), align 8 + %1 = getelementptr inbounds %b, ptr %0, i64 undef, i32 0 + %2 = load i64, ptr %1, align 8 %3 = icmp ugt i64 %2, 1 br i1 %3, label %if.then, label %if.else @@ -440,8 +440,8 @@ TEST(CodeExtractor, ExtractAndInvalidateAssumptionCache) { unreachable if.else: - call void @g(i8* undef) - store i64 undef, i64* null, align 536870912 + call void @g(ptr undef) + store i64 undef, ptr null, align 536870912 %4 = icmp eq i64 %2, 0 call void @llvm.assume(i1 %4) unreachable @@ -473,9 +473,9 @@ TEST(CodeExtractor, RemoveBitcastUsesFromOuterLifetimeMarkers) { target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" - declare void @use(i32*) - declare void @llvm.lifetime.start.p0i8(i64, i8*) - declare void @llvm.lifetime.end.p0i8(i64, i8*) + declare void @use(ptr) + declare void @llvm.lifetime.start.p0i8(i64, ptr) + declare void @llvm.lifetime.end.p0i8(i64, ptr) define void @foo() { entry: @@ -483,14 +483,14 @@ TEST(CodeExtractor, RemoveBitcastUsesFromOuterLifetimeMarkers) { br label %extract extract: - %1 = bitcast i32* %0 to i8* - call void @llvm.lifetime.start.p0i8(i64 4, i8* %1) - call void @use(i32* %0) + %1 = bitcast ptr %0 to ptr + call void @llvm.lifetime.start.p0i8(i64 4, ptr %1) + call void @use(ptr %0) br label %exit exit: - call void @use(i32* %0) - call void @llvm.lifetime.end.p0i8(i64 4, i8* %1) + call void @use(ptr %0) + call void @llvm.lifetime.end.p0i8(i64 4, ptr %1) ret void } )ir", diff --git a/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp b/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp index 9466977..191ccc3 100644 --- a/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp +++ b/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp @@ -75,21 +75,21 @@ TEST(CodeMoverUtils, IsControlFlowEquivalentSimpleTest) { // i = 3; // } std::unique_ptr<Module> M = - parseIR(C, R"(define void @foo(i32* %i, i1 %cond1, i1 %cond2) { + parseIR(C, R"(define void @foo(ptr %i, i1 %cond1, i1 %cond2) { entry: br i1 %cond1, label %if.first, label %if.first.end if.first: - store i32 1, i32* %i, align 4 + store i32 1, ptr %i, align 4 br label %if.first.end if.first.end: br i1 %cond1, label %if.second, label %if.second.end if.second: - store i32 2, i32* %i, align 4 + store i32 2, ptr %i, align 4 br label %if.second.end if.second.end: br i1 %cond2, label %if.third, label %if.third.end if.third: - store i32 3, i32* %i, align 4 + store i32 3, ptr %i, align 4 br label %if.third.end if.third.end: ret void @@ -136,51 +136,51 @@ TEST(CodeMoverUtils, IsControlFlowEquivalentOppositeCondTest) { // i = 9; // } std::unique_ptr<Module> M = - parseIR(C, R"(define void @foo(i32* %i, i32 %X, i32 %Y) { + parseIR(C, R"(define void @foo(ptr %i, i32 %X, i32 %Y) { entry: %cmp1 = icmp ult i32 %X, %Y br i1 %cmp1, label %if.first, label %if.first.end if.first: - store i32 1, i32* %i, align 4 + store i32 1, ptr %i, align 4 br label %if.first.end if.first.end: %cmp2 = icmp ugt i32 %Y, %X br i1 %cmp2, label %if.second, label %if.second.end if.second: - store i32 2, i32* %i, align 4 + store i32 2, ptr %i, align 4 br label %if.second.end if.second.end: %cmp3 = icmp uge i32 %X, %Y br i1 %cmp3, label %if.third, label %if.third.else if.third: - store i32 3, i32* %i, align 4 + store i32 3, ptr %i, align 4 br label %if.third.end if.third.else: - store i32 4, i32* %i, align 4 + store i32 4, ptr %i, align 4 br label %if.third.end if.third.end: %cmp4 = icmp eq i32 %X, %Y br i1 %cmp4, label %if.fourth, label %if.fourth.end if.fourth: - store i32 5, i32* %i, align 4 + store i32 5, ptr %i, align 4 br label %if.fourth.end if.fourth.end: %cmp5 = icmp eq i32 %Y, %X br i1 %cmp5, label %if.fifth, label %if.fifth.else if.fifth: - store i32 6, i32* %i, align 4 + store i32 6, ptr %i, align 4 br label %if.fifth.end if.fifth.else: - store i32 7, i32* %i, align 4 + store i32 7, ptr %i, align 4 br label %if.fifth.end if.fifth.end: %cmp6 = icmp ne i32 %X, %Y br i1 %cmp6, label %if.sixth, label %if.sixth.else if.sixth: - store i32 8, i32* %i, align 4 + store i32 8, ptr %i, align 4 br label %if.sixth.end if.sixth.else: - store i32 9, i32* %i, align 4 + store i32 9, ptr %i, align 4 br label %if.sixth.end if.sixth.end: ret void @@ -227,20 +227,20 @@ TEST(CodeMoverUtils, IsControlFlowEquivalentCondNestTest) { // i = 2; // } std::unique_ptr<Module> M = - parseIR(C, R"(define void @foo(i32* %i, i1 %cond1, i1 %cond2) { + parseIR(C, R"(define void @foo(ptr %i, i1 %cond1, i1 %cond2) { entry: br i1 %cond1, label %if.outer.first, label %if.first.end if.outer.first: br i1 %cond2, label %if.inner.first, label %if.first.end if.inner.first: - store i32 1, i32* %i, align 4 + store i32 1, ptr %i, align 4 br label %if.first.end if.first.end: br i1 %cond2, label %if.outer.second, label %if.second.end if.outer.second: br i1 %cond1, label %if.inner.second, label %if.second.end if.inner.second: - store i32 2, i32* %i, align 4 + store i32 2, ptr %i, align 4 br label %if.second.end if.second.end: ret void @@ -283,7 +283,7 @@ TEST(CodeMoverUtils, IsControlFlowEquivalentImbalanceTest) { // i = 4; // } std::unique_ptr<Module> M = - parseIR(C, R"(define void @foo(i32* %i, i1 %cond1, i1 %cond2, i1 %cond3) { + parseIR(C, R"(define void @foo(ptr %i, i1 %cond1, i1 %cond2, i1 %cond3) { entry: br i1 %cond1, label %if.outer.first, label %if.first.end if.outer.first: @@ -291,26 +291,26 @@ TEST(CodeMoverUtils, IsControlFlowEquivalentImbalanceTest) { if.middle.first: br i1 %cond3, label %if.inner.first, label %if.first.end if.inner.first: - store i32 1, i32* %i, align 4 + store i32 1, ptr %i, align 4 br label %if.first.end if.first.end: br i1 %cond2, label %if.outer.second, label %if.second.end if.outer.second: br i1 %cond3, label %if.inner.second, label %if.second.end if.inner.second: - store i32 2, i32* %i, align 4 + store i32 2, ptr %i, align 4 br label %if.second.end if.second.end: br i1 %cond1, label %if.outer.third, label %if.third.end if.outer.third: br i1 %cond1, label %if.inner.third, label %if.third.end if.inner.third: - store i32 3, i32* %i, align 4 + store i32 3, ptr %i, align 4 br label %if.third.end if.third.end: br i1 %cond1, label %if.fourth, label %if.fourth.end if.fourth: - store i32 4, i32* %i, align 4 + store i32 4, ptr %i, align 4 br label %if.fourth.end if.fourth.end: ret void @@ -343,28 +343,28 @@ TEST(CodeMoverUtils, IsControlFlowEquivalentPointerTest) { // i = 3; // } std::unique_ptr<Module> M = - parseIR(C, R"(define void @foo(i32* %i, i32* %cond) { + parseIR(C, R"(define void @foo(ptr %i, ptr %cond) { entry: - %0 = load i32, i32* %cond, align 4 + %0 = load i32, ptr %cond, align 4 %tobool1 = icmp ne i32 %0, 0 br i1 %tobool1, label %if.first, label %if.first.end if.first: - store i32 1, i32* %i, align 4 + store i32 1, ptr %i, align 4 br label %if.first.end if.first.end: - %1 = load i32, i32* %cond, align 4 + %1 = load i32, ptr %cond, align 4 %tobool2 = icmp ne i32 %1, 0 br i1 %tobool2, label %if.second, label %if.second.end if.second: - store i32 2, i32* %i, align 4 + store i32 2, ptr %i, align 4 br label %if.second.end if.second.end: - store i32 1, i32* %cond, align 4 - %2 = load i32, i32* %cond, align 4 + store i32 1, ptr %cond, align 4 + %2 = load i32, ptr %cond, align 4 %tobool3 = icmp ne i32 %2, 0 br i1 %tobool3, label %if.third, label %if.third.end if.third: - store i32 3, i32* %i, align 4 + store i32 3, ptr %i, align 4 br label %if.third.end if.third.end: ret void @@ -450,7 +450,7 @@ TEST(CodeMoverUtils, IsSafeToMoveTest1) { // } // } std::unique_ptr<Module> M = parseIR( - C, R"(define void @foo(i32* noalias %A, i32* noalias %B, i32* noalias %C + C, R"(define void @foo(ptr noalias %A, ptr noalias %B, ptr noalias %C , i64 %N) { entry: %X = sdiv i64 1, %N @@ -461,18 +461,18 @@ TEST(CodeMoverUtils, IsSafeToMoveTest1) { br i1 %cmp1, label %for.body, label %for.end for.body: %i = phi i64 [ 0, %entry ], [ %inc, %for.body ] - %arrayidx_A5 = getelementptr inbounds i32, i32* %A, i64 5 - store i32 5, i32* %arrayidx_A5, align 4 - %arrayidx_A = getelementptr inbounds i32, i32* %A, i64 %i - store i32 0, i32* %arrayidx_A, align 4 - %load1 = load i32, i32* %arrayidx_A, align 4 - %arrayidx_B = getelementptr inbounds i32, i32* %B, i64 %i - store i32 %load1, i32* %arrayidx_B, align 4 - %load2 = load i32, i32* %arrayidx_A, align 4 - %arrayidx_C = getelementptr inbounds i32, i32* %C, i64 %i - store i32 %load2, i32* %arrayidx_C, align 4 - %arrayidx_A6 = getelementptr inbounds i32, i32* %A, i64 6 - store i32 6, i32* %arrayidx_A6, align 4 + %arrayidx_A5 = getelementptr inbounds i32, ptr %A, i64 5 + store i32 5, ptr %arrayidx_A5, align 4 + %arrayidx_A = getelementptr inbounds i32, ptr %A, i64 %i + store i32 0, ptr %arrayidx_A, align 4 + %load1 = load i32, ptr %arrayidx_A, align 4 + %arrayidx_B = getelementptr inbounds i32, ptr %B, i64 %i + store i32 %load1, ptr %arrayidx_B, align 4 + %load2 = load i32, ptr %arrayidx_A, align 4 + %arrayidx_C = getelementptr inbounds i32, ptr %C, i64 %i + store i32 %load2, ptr %arrayidx_C, align 4 + %arrayidx_A6 = getelementptr inbounds i32, ptr %A, i64 6 + store i32 6, ptr %arrayidx_A6, align 4 %inc = add nsw i64 %i, 1 %cmp = icmp slt i64 %inc, %N br i1 %cmp, label %for.body, label %for.end @@ -686,19 +686,19 @@ TEST(CodeMoverUtils, IsSafeToMoveTest5) { LLVMContext C; std::unique_ptr<Module> M = - parseIR(C, R"(define void @dependence(i32* noalias %A, i32* noalias %B){ + parseIR(C, R"(define void @dependence(ptr noalias %A, ptr noalias %B){ entry: - store i32 0, i32* %A, align 4 ; storeA0 - store i32 2, i32* %A, align 4 ; storeA1 - %tmp0 = load i32, i32* %A, align 4 ; loadA0 - store i32 1, i32* %B, align 4 ; storeB0 - %tmp1 = load i32, i32* %A, align 4 ; loadA1 - store i32 2, i32* %A, align 4 ; storeA2 - store i32 4, i32* %B, align 4 ; StoreB1 - %tmp2 = load i32, i32* %A, align 4 ; loadA2 - %tmp3 = load i32, i32* %A, align 4 ; loadA3 - %tmp4 = load i32, i32* %B, align 4 ; loadB2 - %tmp5 = load i32, i32* %B, align 4 ; loadB3 + store i32 0, ptr %A, align 4 ; storeA0 + store i32 2, ptr %A, align 4 ; storeA1 + %tmp0 = load i32, ptr %A, align 4 ; loadA0 + store i32 1, ptr %B, align 4 ; storeB0 + %tmp1 = load i32, ptr %A, align 4 ; loadA1 + store i32 2, ptr %A, align 4 ; storeA2 + store i32 4, ptr %B, align 4 ; StoreB1 + %tmp2 = load i32, ptr %A, align 4 ; loadA2 + %tmp3 = load i32, ptr %A, align 4 ; loadA3 + %tmp4 = load i32, ptr %B, align 4 ; loadB2 + %tmp5 = load i32, ptr %B, align 4 ; loadB3 ret void })"); @@ -763,63 +763,63 @@ TEST(CodeMoverUtils, IsSafeToMoveTest6) { LLVMContext C; std::unique_ptr<Module> M = parseIR( - C, R"(define void @dependence(i1 %cond, i32* noalias %A, i32* noalias %B){ + C, R"(define void @dependence(i1 %cond, ptr noalias %A, ptr noalias %B){ entry: br i1 %cond, label %bb0, label %bb1 bb0: br label %bb1 bb1: - store i32 0, i32* %A, align 4 ; storeA0 + store i32 0, ptr %A, align 4 ; storeA0 br i1 %cond, label %bb2, label %bb3 bb2: br label %bb3 bb3: - store i32 2, i32* %A, align 4 ; storeA1 + store i32 2, ptr %A, align 4 ; storeA1 br i1 %cond, label %bb4, label %bb5 bb4: br label %bb5 bb5: - %tmp0 = load i32, i32* %A, align 4 ; loadA0 + %tmp0 = load i32, ptr %A, align 4 ; loadA0 br i1 %cond, label %bb6, label %bb7 bb6: br label %bb7 bb7: - store i32 1, i32* %B, align 4 ; storeB0 + store i32 1, ptr %B, align 4 ; storeB0 br i1 %cond, label %bb8, label %bb9 bb8: br label %bb9 bb9: - %tmp1 = load i32, i32* %A, align 4 ; loadA1 + %tmp1 = load i32, ptr %A, align 4 ; loadA1 br i1 %cond, label %bb10, label %bb11 bb10: br label %bb11 bb11: - store i32 2, i32* %A, align 4 ; storeA2 + store i32 2, ptr %A, align 4 ; storeA2 br i1 %cond, label %bb12, label %bb13 bb12: br label %bb13 bb13: - store i32 4, i32* %B, align 4 ; StoreB1 + store i32 4, ptr %B, align 4 ; StoreB1 br i1 %cond, label %bb14, label %bb15 bb14: br label %bb15 bb15: - %tmp2 = load i32, i32* %A, align 4 ; loadA2 + %tmp2 = load i32, ptr %A, align 4 ; loadA2 br i1 %cond, label %bb16, label %bb17 bb16: br label %bb17 bb17: - %tmp3 = load i32, i32* %A, align 4 ; loadA3 + %tmp3 = load i32, ptr %A, align 4 ; loadA3 br i1 %cond, label %bb18, label %bb19 bb18: br label %bb19 bb19: - %tmp4 = load i32, i32* %B, align 4 ; loadB2 + %tmp4 = load i32, ptr %B, align 4 ; loadB2 br i1 %cond, label %bb20, label %bb21 bb20: br label %bb21 bb21: - %tmp5 = load i32, i32* %B, align 4 ; loadB3 + %tmp5 = load i32, ptr %B, align 4 ; loadB3 ret void })"); run(*M, "dependence", diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp index 4b53cc3..896e1de 100644 --- a/llvm/unittests/Transforms/Utils/LocalTest.cpp +++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp @@ -183,7 +183,7 @@ TEST(Local, MergeBasicBlockIntoOnlyPred) { auto resetIR = [&]() { M = parseIR(C, R"( - define i32 @f(i8* %str) { + define i32 @f(ptr %str) { entry: br label %bb2.i bb2.i: ; preds = %bb4.i, %entry @@ -411,7 +411,7 @@ TEST(Local, ConstantFoldTerminator) { define void @indirectbr() { entry: - indirectbr i8* blockaddress(@indirectbr, %bb0), [label %bb0, label %bb1] + indirectbr ptr blockaddress(@indirectbr, %bb0), [label %bb0, label %bb1] bb0: ret void bb1: @@ -420,14 +420,14 @@ TEST(Local, ConstantFoldTerminator) { define void @indirectbr_repeated() { entry: - indirectbr i8* blockaddress(@indirectbr_repeated, %bb0), [label %bb0, label %bb0] + indirectbr ptr blockaddress(@indirectbr_repeated, %bb0), [label %bb0, label %bb0] bb0: ret void } define void @indirectbr_unreachable() { entry: - indirectbr i8* blockaddress(@indirectbr_unreachable, %bb0), [label %bb1] + indirectbr ptr blockaddress(@indirectbr_unreachable, %bb0), [label %bb1] bb0: ret void bb1: @@ -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. @@ -925,7 +924,7 @@ TEST(Local, RemoveUnreachableBlocks) { declare i32 @__gxx_personality_v0(...) - define void @invoke_terminator() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { + define void @invoke_terminator() personality ptr @__gxx_personality_v0 { entry: br i1 undef, label %invoke.block, label %exit @@ -943,8 +942,8 @@ TEST(Local, RemoveUnreachableBlocks) { unreachable lpad.block: - %lp = landingpad { i8*, i32 } - catch i8* null + %lp = landingpad { ptr, i32 } + catch ptr null br label %exit exit: @@ -1153,7 +1152,7 @@ TEST(Local, ExpressionForConstant) { IntegerType *Int1Ty = Type::getInt1Ty(Context); Expr = createExpression(ConstantInt::getTrue(Context), Int1Ty); EXPECT_NE(Expr, nullptr); - EXPECT_EQ(Expr->getElement(1), 18446744073709551615U); + EXPECT_EQ(Expr->getElement(1), 1U); Expr = createExpression(ConstantInt::getFalse(Context), Int1Ty); EXPECT_NE(Expr, nullptr); 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 b97bc31..752029e 100644 --- a/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp +++ b/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp @@ -98,13 +98,13 @@ struct MemTransferLowerTest : public testing::Test { // For that reason expandMemCpyAsLoop is expected to explicitly mark // loads from source and stores to destination as not aliasing. TEST_F(MemTransferLowerTest, MemCpyKnownLength) { - ParseAssembly("declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8 *, i64, i1)\n" - "define void @foo(i8* %dst, i8* %src, i64 %n) optsize {\n" + ParseAssembly("declare void @llvm.memcpy.p0i8.p0i8.i64(ptr, ptr, i64, i1)\n" + "define void @foo(ptr %dst, ptr %src, i64 %n) optsize {\n" "entry:\n" - " %is_not_equal = icmp ne i8* %dst, %src\n" + " %is_not_equal = icmp ne ptr %dst, %src\n" " br i1 %is_not_equal, label %memcpy, label %exit\n" "memcpy:\n" - " call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, " + " call void @llvm.memcpy.p0i8.p0i8.i64(ptr %dst, ptr %src, " "i64 1024, i1 false)\n" " br label %exit\n" "exit:\n" @@ -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)); @@ -138,13 +139,13 @@ TEST_F(MemTransferLowerTest, MemCpyKnownLength) { // llvm.memcpy lowering) doesn't alias by making sure the loop can be // successfully vectorized without additional runtime checks. TEST_F(MemTransferLowerTest, VecMemCpyKnownLength) { - ParseAssembly("declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8 *, i64, i1)\n" - "define void @foo(i8* %dst, i8* %src, i64 %n) optsize {\n" + ParseAssembly("declare void @llvm.memcpy.p0i8.p0i8.i64(ptr, ptr, i64, i1)\n" + "define void @foo(ptr %dst, ptr %src, i64 %n) optsize {\n" "entry:\n" - " %is_not_equal = icmp ne i8* %dst, %src\n" + " %is_not_equal = icmp ne ptr %dst, %src\n" " br i1 %is_not_equal, label %memcpy, label %exit\n" "memcpy:\n" - " call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, " + " call void @llvm.memcpy.p0i8.p0i8.i64(ptr %dst, ptr %src, " "i64 1024, i1 false)\n" " br label %exit\n" "exit:\n" @@ -176,16 +177,16 @@ TEST_F(MemTransferLowerTest, VecMemCpyKnownLength) { TEST_F(MemTransferLowerTest, AtomicMemCpyKnownLength) { ParseAssembly("declare void " - "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(i32*, " + "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(ptr, " "i32 *, i64, i32)\n" - "define void @foo(i32* %dst, i32* %src, i64 %n) optsize {\n" + "define void @foo(ptr %dst, ptr %src, i64 %n) optsize {\n" "entry:\n" - " %is_not_equal = icmp ne i32* %dst, %src\n" + " %is_not_equal = icmp ne ptr %dst, %src\n" " br i1 %is_not_equal, label %memcpy, label %exit\n" "memcpy:\n" " call void " - "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(i32* " - "%dst, i32* %src, " + "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(ptr " + "%dst, ptr %src, " "i64 1024, i32 4)\n" " br label %exit\n" "exit:\n" @@ -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()); @@ -221,16 +223,16 @@ TEST_F(MemTransferLowerTest, AtomicMemCpyKnownLength) { TEST_F(MemTransferLowerTest, AtomicMemCpyUnKnownLength) { ParseAssembly("declare void " - "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(i32*, " + "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(ptr, " "i32 *, i64, i32)\n" - "define void @foo(i32* %dst, i32* %src, i64 %n) optsize {\n" + "define void @foo(ptr %dst, ptr %src, i64 %n) optsize {\n" "entry:\n" - " %is_not_equal = icmp ne i32* %dst, %src\n" + " %is_not_equal = icmp ne ptr %dst, %src\n" " br i1 %is_not_equal, label %memcpy, label %exit\n" "memcpy:\n" " call void " - "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(i32* " - "%dst, i32* %src, " + "@llvm.memcpy.element.unordered.atomic.p0i32.p0i32.i64(ptr " + "%dst, ptr %src, " "i64 %n, i32 4)\n" " br label %exit\n" "exit:\n" @@ -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 716f5f2..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, @@ -393,9 +390,8 @@ static void RunEliminateNewDuplicatePHINode( } Function *F = M->getFunction("main"); - auto BBIt = std::find_if(F->begin(), F->end(), [](const BasicBlock &Block) { - return Block.getName() == "testbb"; - }); + auto BBIt = llvm::find_if( + *F, [](const BasicBlock &Block) { return Block.getName() == "testbb"; }); ASSERT_NE(BBIt, F->end()); Check(*BBIt, EliminateNewDuplicatePHINodes); } diff --git a/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp b/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp index 55eae64..4fe3080 100644 --- a/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp +++ b/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp @@ -121,18 +121,18 @@ TEST_F(ScalarEvolutionExpanderTest, ExpandPtrTypeSCEV) { TEST_F(ScalarEvolutionExpanderTest, SCEVZeroExtendExprNonIntegral) { /* * Create the following code: - * func(i64 addrspace(10)* %arg) + * func(ptr addrspace(10) %arg) * top: * br label %L.ph * L.ph: - * %gepbase = getelementptr i64 addrspace(10)* %arg, i64 1 + * %gepbase = getelementptr ptr addrspace(10) %arg, i64 1 * br label %L * L: * %phi = phi i64 [i64 0, %L.ph], [ %add, %L2 ] * %add = add i64 %phi2, 1 * br i1 undef, label %post, label %L2 * post: - * #= %gep = getelementptr i64 addrspace(10)* %gepbase, i64 %add =# + * #= %gep = getelementptr ptr addrspace(10) %gepbase, i64 %add =# * ret void * * We will create the appropriate SCEV expression for %gep and expand it, @@ -199,7 +199,7 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVZeroExtendExprNonIntegral) { TEST_F(ScalarEvolutionExpanderTest, SCEVExpanderIsSafeToExpandAt) { /* * Create the following code: - * func(i64 addrspace(10)* %arg) + * func(ptr addrspace(10) %arg) * top: * br label %L.ph * L.ph: @@ -704,14 +704,14 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpanderShlNSW) { EXPECT_FALSE(I->hasNoSignedWrap()); }; - checkOneCase("define void @f(i16* %arrayidx) { " - " %1 = load i16, i16* %arrayidx " + checkOneCase("define void @f(ptr %arrayidx) { " + " %1 = load i16, ptr %arrayidx " " %2 = and i16 %1, -32768 " " ret void " "} "); - checkOneCase("define void @f(i8* %arrayidx) { " - " %1 = load i8, i8* %arrayidx " + checkOneCase("define void @f(ptr %arrayidx) { " + " %1 = load i8, ptr %arrayidx " " %2 = and i8 %1, -128 " " ret void " "} "); diff --git a/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp b/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp index eec1011..7ba259d 100644 --- a/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp +++ b/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp @@ -34,7 +34,7 @@ TEST(LoopUnrollRuntime, Latch) { std::unique_ptr<Module> M = parseIR( C, - R"(define i32 @test(i32* %a, i32* %b, i32* %c, i64 %n) { + R"(define i32 @test(ptr %a, ptr %b, ptr %c, i64 %n) { entry: br label %while.cond @@ -44,13 +44,13 @@ while.cond: ; preds = %while.body, %entry br i1 %cmp, label %while.body, label %while.end while.body: ; preds = %while.cond - %arrayidx = getelementptr inbounds i32, i32* %b, i64 %i.0 - %0 = load i32, i32* %arrayidx - %arrayidx1 = getelementptr inbounds i32, i32* %c, i64 %i.0 - %1 = load i32, i32* %arrayidx1 + %arrayidx = getelementptr inbounds i32, ptr %b, i64 %i.0 + %0 = load i32, ptr %arrayidx + %arrayidx1 = getelementptr inbounds i32, ptr %c, i64 %i.0 + %1 = load i32, ptr %arrayidx1 %mul = mul nsw i32 %0, %1 - %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %i.0 - store i32 %mul, i32* %arrayidx2 + %arrayidx2 = getelementptr inbounds i32, ptr %a, i64 %i.0 + store i32 %mul, ptr %arrayidx2 %inc = add nsw i64 %i.0, 1 br label %while.cond diff --git a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp index e39cd70..60e9c56 100644 --- a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp +++ b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp @@ -74,7 +74,7 @@ TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) { // Create a cycle that references G0. MDNode *N0; // !0 = !{!1} - MDNode *N1; // !1 = !{!0, i8* @G0} + MDNode *N1; // !1 = !{!0, ptr @G0} { auto T0 = MDTuple::getTemporary(Context, nullptr); Metadata *Ops1[] = {T0.get(), ConstantAsMetadata::get(G0.get())}; @@ -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 59a9ea1..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()); @@ -704,18 +704,30 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) { } } +TEST_F(VPBasicBlockTest, splitAtEnd) { + VPlan &Plan = getPlan(); + VPInstruction *VPI = new VPInstruction(VPInstruction::StepVector, {}); + VPBasicBlock *VPBB = Plan.createVPBasicBlock("VPBB1", VPI); + VPBlockUtils::connectBlocks(Plan.getEntry(), VPBB); + VPBlockUtils::connectBlocks(VPBB, Plan.getScalarHeader()); + VPBB->splitAt(VPBB->end()); + EXPECT_EQ(VPBB->size(), 1u); + EXPECT_EQ(&VPBB->front(), VPI); + auto *Split = cast<VPBasicBlock>(VPBB->getSingleSuccessor()); + EXPECT_TRUE(Split->empty()); + EXPECT_EQ(Split->getSingleSuccessor(), Plan.getScalarHeader()); +} + #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); @@ -724,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); @@ -737,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()); @@ -748,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=""] @@ -782,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; @@ -794,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; @@ -807,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"); @@ -841,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>: @@ -865,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>: @@ -889,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>: @@ -908,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); @@ -926,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 @@ -955,16 +963,40 @@ compound=true #endif using VPRecipeTest = VPlanTestBase; + +namespace { +template <typename RecipeT, typename T, typename... Rest> +void checkVPRecipeCastImpl(RecipeT *R) { + // Direct checks on recipe pointer + EXPECT_TRUE(isa<T>(R)); + EXPECT_EQ(R, dyn_cast<T>(R)); + (void)cast<T>(R); // Verify cast succeeds (asserts on failure) + + // Check through base pointer + VPRecipeBase *BaseR = R; + EXPECT_TRUE(isa<T>(BaseR)); + EXPECT_EQ(R, dyn_cast<T>(BaseR)); + (void)cast<T>(BaseR); + + // Check through const base pointer + const VPRecipeBase *ConstBaseR = R; + EXPECT_TRUE(isa<T>(ConstBaseR)); + EXPECT_EQ(R, dyn_cast<T>(ConstBaseR)); + (void)cast<T>(ConstBaseR); + + if constexpr (sizeof...(Rest) > 0) + checkVPRecipeCastImpl<RecipeT, Rest...>(R); +} +} // namespace + TEST_F(VPRecipeTest, CastVPInstructionToVPUser) { IntegerType *Int32 = IntegerType::get(C, 32); VPlan &Plan = getPlan(); VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPInstruction Recipe(Instruction::Add, {Op1, Op2}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPInstruction, VPUser, VPIRMetadata>(&Recipe); } TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) { @@ -977,11 +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())); - EXPECT_TRUE(isa<VPUser>(&WidenR)); - VPRecipeBase *WidenRBase = &WidenR; - EXPECT_TRUE(isa<VPUser>(WidenRBase)); - EXPECT_EQ(&WidenR, WidenRBase); + VPWidenRecipe WidenR(*AI, Args); + + checkVPRecipeCastImpl<VPWidenRecipe, VPUser, VPIRMetadata>(&WidenR); delete AI; } @@ -999,10 +1029,8 @@ TEST_F(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) { Args.push_back(Op2); Args.push_back(CalledFn); VPWidenCallRecipe Recipe(Call, Fn, Args); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPWidenCallRecipe, VPUser, VPIRMetadata>(&Recipe); VPValue *VPV = &Recipe; EXPECT_TRUE(VPV->getDefiningRecipe()); @@ -1025,15 +1053,13 @@ 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())); - EXPECT_TRUE(isa<VPUser>(&WidenSelectR)); - VPRecipeBase *BaseR = &WidenSelectR; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&WidenSelectR, BaseR); + + checkVPRecipeCastImpl<VPWidenSelectRecipe, VPUser, VPIRMetadata>( + &WidenSelectR); VPValue *VPV = &WidenSelectR; - EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); EXPECT_EQ(&WidenSelectR, VPV->getDefiningRecipe()); delete SelectI; @@ -1051,10 +1077,8 @@ TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) { Args.push_back(Op1); Args.push_back(Op2); VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end())); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPWidenGEPRecipe, VPUser>(&Recipe); VPValue *VPV = &Recipe; EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); @@ -1063,6 +1087,28 @@ TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) { delete GEP; } +TEST_F(VPRecipeTest, CastVPWidenCastRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + 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); + + checkVPRecipeCastImpl<VPWidenCastRecipe, VPUser, VPIRMetadata>(&Recipe); + delete Cast; +} + +TEST_F(VPRecipeTest, CastVPWidenIntrinsicRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Op1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *Op2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPWidenIntrinsicRecipe Recipe(Intrinsic::smax, {Op1, Op2}, Int32); + + checkVPRecipeCastImpl<VPWidenIntrinsicRecipe, VPUser, VPIRMetadata>(&Recipe); +} + TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) { VPlan &Plan = getPlan(); IntegerType *Int32 = IntegerType::get(C, 32); @@ -1076,9 +1122,9 @@ TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) { Args.push_back(I2); Args.push_back(M2); VPBlendRecipe Recipe(Phi, Args, {}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); + + checkVPRecipeCastImpl<VPBlendRecipe, VPUser>(&Recipe); + delete Phi; } @@ -1089,10 +1135,8 @@ TEST_F(VPRecipeTest, CastVPInterleaveRecipeToVPUser) { VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); InterleaveGroup<Instruction> IG(4, false, Align(4)); VPInterleaveRecipe Recipe(&IG, Addr, {}, Mask, false, {}, DebugLoc()); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPInterleaveRecipe, VPUser, VPIRMetadata>(&Recipe); } TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) { @@ -1107,9 +1151,9 @@ TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) { FunctionType *FTy = FunctionType::get(Int32, false); auto *Call = CallInst::Create(FTy, PoisonValue::get(FTy)); VPReplicateRecipe Recipe(Call, make_range(Args.begin(), Args.end()), true); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); + + checkVPRecipeCastImpl<VPReplicateRecipe, VPUser, VPIRMetadata>(&Recipe); + delete Call; } @@ -1118,10 +1162,8 @@ TEST_F(VPRecipeTest, CastVPBranchOnMaskRecipeToVPUser) { IntegerType *Int32 = IntegerType::get(C, 32); VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPBranchOnMaskRecipe Recipe(Mask, {}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + + checkVPRecipeCastImpl<VPBranchOnMaskRecipe, VPUser>(&Recipe); } TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { @@ -1132,12 +1174,9 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1)); VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); - VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, Load->getAlign(), {}, - {}); - EXPECT_TRUE(isa<VPUser>(&Recipe)); - VPRecipeBase *BaseR = &Recipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - EXPECT_EQ(&Recipe, BaseR); + VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, {}, {}); + + checkVPRecipeCastImpl<VPWidenLoadRecipe, VPUser, VPIRMetadata>(&Recipe); VPValue *VPV = Recipe.getVPSingleValue(); EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe())); @@ -1146,6 +1185,71 @@ TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) { delete Load; } +TEST_F(VPRecipeTest, CastVPInterleaveEVLRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8)); + InterleaveGroup<Instruction> IG(4, false, Align(4)); + VPInterleaveRecipe BaseRecipe(&IG, Addr, {}, Mask, false, {}, DebugLoc()); + VPInterleaveEVLRecipe Recipe(BaseRecipe, *EVL, Mask); + + checkVPRecipeCastImpl<VPInterleaveEVLRecipe, VPUser, VPIRMetadata>(&Recipe); +} + +TEST_F(VPRecipeTest, CastVPWidenLoadEVLRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + PointerType *Int32Ptr = PointerType::get(C, 0); + auto *Load = + new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1)); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8)); + VPWidenLoadRecipe BaseLoad(*Load, Addr, Mask, true, false, {}, {}); + VPWidenLoadEVLRecipe Recipe(BaseLoad, Addr, *EVL, Mask); + + checkVPRecipeCastImpl<VPWidenLoadEVLRecipe, VPUser, VPIRMetadata>(&Recipe); + + delete Load; +} + +TEST_F(VPRecipeTest, CastVPWidenStoreRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + PointerType *Int32Ptr = PointerType::get(C, 0); + auto *Store = new StoreInst(PoisonValue::get(Int32), + PoisonValue::get(Int32Ptr), false, Align(1)); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *StoredVal = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 42)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPWidenStoreRecipe Recipe(*Store, Addr, StoredVal, Mask, true, false, {}, {}); + + checkVPRecipeCastImpl<VPWidenStoreRecipe, VPUser, VPIRMetadata>(&Recipe); + + delete Store; +} + +TEST_F(VPRecipeTest, CastVPWidenStoreEVLRecipeToVPUser) { + VPlan &Plan = getPlan(); + IntegerType *Int32 = IntegerType::get(C, 32); + PointerType *Int32Ptr = PointerType::get(C, 0); + auto *Store = new StoreInst(PoisonValue::get(Int32), + PoisonValue::get(Int32Ptr), false, Align(1)); + VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *StoredVal = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 42)); + VPValue *EVL = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 8)); + VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); + VPWidenStoreRecipe BaseStore(*Store, Addr, StoredVal, Mask, true, false, {}, + {}); + VPWidenStoreEVLRecipe Recipe(BaseStore, Addr, *EVL, Mask); + + checkVPRecipeCastImpl<VPWidenStoreEVLRecipe, VPUser, VPIRMetadata>(&Recipe); + + delete Store; +} + TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { IntegerType *Int1 = IntegerType::get(C, 1); IntegerType *Int32 = IntegerType::get(C, 32); @@ -1160,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()); @@ -1179,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()); @@ -1214,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; } { @@ -1250,8 +1348,7 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1)); VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); - VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, Load->getAlign(), - {}, {}); + VPWidenLoadRecipe Recipe(*Load, Addr, Mask, true, false, {}, {}); EXPECT_FALSE(Recipe.mayHaveSideEffects()); EXPECT_TRUE(Recipe.mayReadFromMemory()); EXPECT_FALSE(Recipe.mayWriteToMemory()); @@ -1265,8 +1362,8 @@ TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) { VPValue *Mask = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPValue *Addr = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2)); VPValue *StoredV = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 3)); - VPWidenStoreRecipe Recipe(*Store, Addr, StoredV, Mask, false, false, - Store->getAlign(), {}, {}); + VPWidenStoreRecipe Recipe(*Store, Addr, StoredV, Mask, false, false, {}, + {}); EXPECT_TRUE(Recipe.mayHaveSideEffects()); EXPECT_FALSE(Recipe.mayReadFromMemory()); EXPECT_TRUE(Recipe.mayWriteToMemory()); @@ -1309,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()); @@ -1365,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); { @@ -1587,34 +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); EXPECT_TRUE(isa<VPUser>(&Recipe)); VPRecipeBase *BaseR = &Recipe; EXPECT_TRUE(isa<VPUser>(BaseR)); - delete Add; } 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); - EXPECT_TRUE(isa<VPUser>(&EVLRecipe)); - VPRecipeBase *BaseR = &EVLRecipe; - EXPECT_TRUE(isa<VPUser>(BaseR)); - delete Add; + checkVPRecipeCastImpl<VPReductionEVLRecipe, VPUser>(&EVLRecipe); } } // namespace @@ -1628,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 }; @@ -1640,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 50ad4d5..97783a6 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp @@ -21,9 +21,9 @@ using VPVerifierTest = VPlanTestBase; namespace { TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) { VPlan &Plan = getPlan(); - VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); - VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI}); + VPValue *Zero = Plan.getConstantInt(32, 0); + 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", @@ -56,9 +56,9 @@ TEST_F(VPVerifierTest, VPInstructionUseBeforeDefSameBB) { TEST_F(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) { VPlan &Plan = getPlan(); - VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); - VPInstruction *DefI = new VPInstruction(Instruction::Add, {Zero}); - VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI}); + VPValue *Zero = Plan.getConstantInt(32, 0); + 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()); @@ -184,8 +184,8 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) { TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) { VPlan &Plan = getPlan(); - VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero}); + VPValue *Zero = Plan.getConstantInt(32, 0); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -218,8 +218,8 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) { TEST_F(VPVerifierTest, DuplicateSuccessorsInsideRegion) { VPlan &Plan = getPlan(); - VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero}); + VPValue *Zero = Plan.getConstantInt(32, 0); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Zero, Zero}); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -259,11 +259,11 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) { VPBasicBlock *VPBB1 = Plan.getEntry(); VPBasicBlock *VPBB2 = Plan.createVPBasicBlock(""); - VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); + VPValue *Zero = Plan.getConstantInt(32, 0); 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}); @@ -288,7 +288,7 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) { TEST_F(VPVerifierTest, NonHeaderPHIInHeader) { VPlan &Plan = getPlan(); - VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); + VPValue *Zero = Plan.getConstantInt(32, 0); auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); auto *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); @@ -326,22 +326,18 @@ TEST_F(VPVerifierTest, NonHeaderPHIInHeader) { class VPIRVerifierTest : public VPlanTestIRBase {}; -TEST_F(VPIRVerifierTest, testVerifyIRPhi) { +TEST_F(VPIRVerifierTest, testVerifyIRPhiInScalarHeaderVPIRBB) { const char *ModuleString = "define void @f(ptr %A, i64 %N) {\n" "entry:\n" " br label %loop\n" "loop:\n" " %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]\n" - " %arr.idx = getelementptr inbounds i32, ptr %A, i64 %iv\n" - " %l1 = load i32, ptr %arr.idx, align 4\n" - " %res = add i32 %l1, 10\n" - " store i32 %res, ptr %arr.idx, align 4\n" " %iv.next = add i64 %iv, 1\n" " %exitcond = icmp ne i64 %iv.next, %N\n" " br i1 %exitcond, label %loop, label %for.end\n" "for.end:\n" - " %p = phi i32 [ %l1, %loop ]\n" + " %p = phi i64 [ %iv, %loop ]\n" " ret void\n" "}\n"; @@ -350,9 +346,49 @@ TEST_F(VPIRVerifierTest, testVerifyIRPhi) { 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); - Plan->getExitBlocks()[0]->front().addOperand( - Plan->getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(*Ctx), 0))); +#if GTEST_HAS_STREAM_REDIRECTION + ::testing::internal::CaptureStderr(); +#endif + EXPECT_FALSE(verifyVPlanIsValid(*Plan)); +#if GTEST_HAS_STREAM_REDIRECTION + EXPECT_STREQ( + "Phi-like recipe with different number of operands and predecessors.\n", + ::testing::internal::GetCapturedStderr().c_str()); +#endif +} + +TEST_F(VPIRVerifierTest, testVerifyIRPhiInExitVPIRBB) { + const char *ModuleString = + "define void @f(ptr %A, i64 %N) {\n" + "entry:\n" + " br label %loop\n" + "loop:\n" + " %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]\n" + " %iv.next = add i64 %iv, 1\n" + " %exitcond = icmp ne i64 %iv.next, %N\n" + " br i1 %exitcond, label %loop, label %for.end\n" + "for.end:\n" + " %p = phi i64 [ %iv, %loop ]\n" + " ret void\n" + "}\n"; + + Module &M = parseModule(ModuleString); + + Function *F = M.getFunction("f"); + BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor(); + auto Plan = buildVPlan(LoopHeader); + + // Create a definition in the vector loop header that will be used by the phi. + auto *HeaderBlock = + cast<VPBasicBlock>(Plan->getVectorLoopRegion()->getEntry()); + VPInstruction *DefI = + new VPInstruction(VPInstruction::ExtractLastLane, + {HeaderBlock->front().getVPSingleValue()}); + DefI->insertBefore(Plan->getMiddleBlock()->getTerminator()); + Plan->getExitBlocks()[0]->front().addOperand(DefI); #if GTEST_HAS_STREAM_REDIRECTION ::testing::internal::CaptureStderr(); diff --git a/llvm/unittests/XRay/GraphTest.cpp b/llvm/unittests/XRay/GraphTest.cpp index 37f07cc..0d46a3d 100644 --- a/llvm/unittests/XRay/GraphTest.cpp +++ b/llvm/unittests/XRay/GraphTest.cpp @@ -23,8 +23,8 @@ struct EAttr { unsigned EA; }; typedef Graph<VAttr, EAttr, unsigned> GraphT; -typedef typename GraphT::VertexIdentifier VI; -typedef typename GraphT::EdgeIdentifier EI; +typedef GraphT::VertexIdentifier VI; +typedef GraphT::EdgeIdentifier EI; // Test Fixture template <typename T> class GraphTest : public testing::Test { @@ -56,8 +56,8 @@ private: typedef ::testing::Types<GraphT, const GraphT> GraphTestTypes; -using VVT = typename GraphT::VertexValueType; -using EVT = typename GraphT::EdgeValueType; +using VVT = GraphT::VertexValueType; +using EVT = GraphT::EdgeValueType; TYPED_TEST_SUITE(GraphTest, GraphTestTypes, ); diff --git a/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp index 7a66117b..5bc489b 100644 --- a/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp @@ -28,7 +28,7 @@ using testing::IsEmpty; using testing::Not; using testing::NotNull; -constexpr const char kTriple[] = "aarch64-unknown-linux"; +constexpr char kTriple[] = "aarch64-unknown-linux"; class AArch64TargetTest : public ::testing::Test { protected: 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/PowerPC/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp index 3708f18..0e90654 100644 --- a/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp @@ -20,16 +20,13 @@ namespace llvm{ namespace exegesis { - -void InitializePowerPCExegesisTarget(); - namespace { using testing::NotNull; using testing::IsEmpty; using testing::Not; -constexpr const char kTriple[] = "powerpc64le-unknown-linux"; +constexpr char kTriple[] = "powerpc64le-unknown-linux"; class PowerPCTargetTest : public PPCTestBase { protected: diff --git a/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/RISCV/TargetTest.cpp index c86a436..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" @@ -20,9 +19,6 @@ namespace llvm { namespace exegesis { - -void InitializeRISCVExegesisTarget(); - namespace { using testing::IsEmpty; 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/SnippetFileTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetFileTest.cpp index de883ab..755a748 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetFileTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetFileTest.cpp @@ -23,9 +23,6 @@ namespace llvm { namespace exegesis { - -void InitializeX86ExegesisTarget(); - namespace { using testing::ElementsAre; diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp index 60c7262..3e0b1f4 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp @@ -16,13 +16,8 @@ #include "X86InstrInfo.h" #include "llvm/ADT/SetOperations.h" -#include <unordered_set> - namespace llvm { namespace exegesis { - -void InitializeX86ExegesisTarget(); - namespace { using testing::AnyOf; diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp index 41ee402..7a40901de 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp @@ -16,9 +16,6 @@ namespace llvm { namespace exegesis { - -void InitializeX86ExegesisTarget(); - namespace { using testing::ElementsAre; @@ -52,8 +49,8 @@ protected: Fill(Sink); } - static constexpr const unsigned kMinInstructions = 3; - static constexpr const unsigned kLoopBodySize = 5; + static constexpr unsigned kMinInstructions = 3; + static constexpr unsigned kLoopBodySize = 5; std::unique_ptr<TargetMachine> TM; std::unique_ptr<LLVMContext> Context; diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SubprocessMemoryTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SubprocessMemoryTest.cpp index a0cad28..08c18e4 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SubprocessMemoryTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SubprocessMemoryTest.cpp @@ -29,7 +29,7 @@ namespace exegesis { // This needs to be updated anytime a test is added or removed from the test // suite. -static constexpr const size_t TestCount = 4; +static constexpr size_t TestCount = 4; class SubprocessMemoryTest : public X86TestBase { protected: diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 846729c6..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" @@ -53,9 +52,6 @@ bool operator==(const MCInst &a, const MCInst &b) { namespace llvm { namespace exegesis { - -void InitializeX86ExegesisTarget(); - namespace { using testing::AllOf; @@ -585,7 +581,7 @@ TEST_F(X86Core2TargetTest, SetRegToDf0) { TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) { const Instruction &I = getInstr(X86::ADD64rm); InstructionTemplate IT(&I); - constexpr const int kOffset = 42; + constexpr int kOffset = 42; State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset); // Memory is operands 2-6. EXPECT_THAT(IT.getValueFor(I.Operands[2]), IsReg(X86::RDI)); @@ -598,7 +594,7 @@ TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) { TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_VGATHERDPSZ128rm) { const Instruction &I = getInstr(X86::VGATHERDPSZ128rm); InstructionTemplate IT(&I); - constexpr const int kOffset = 42; + constexpr int kOffset = 42; State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset); // Memory is operands 4-8. EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(X86::RDI)); @@ -628,9 +624,9 @@ TEST_F(X86Core2TargetTest, GenerateLowerMunmapTest) { } #ifdef __arm__ -static constexpr const uintptr_t VAddressSpaceCeiling = 0xC0000000; +static constexpr uintptr_t VAddressSpaceCeiling = 0xC0000000; #else -static constexpr const uintptr_t VAddressSpaceCeiling = 0x0000800000000000; +static constexpr uintptr_t VAddressSpaceCeiling = 0x0000800000000000; #endif TEST_F(X86Core2TargetTest, GenerateUpperMunmapTest) { diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TestBase.h b/llvm/unittests/tools/llvm-exegesis/X86/TestBase.h index 4122726..b4c84d1 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/TestBase.h +++ b/llvm/unittests/tools/llvm-exegesis/X86/TestBase.h @@ -22,7 +22,7 @@ namespace exegesis { void InitializeX86ExegesisTarget(); -constexpr const char kTriple[] = "x86_64-unknown-linux"; +constexpr char kTriple[] = "x86_64-unknown-linux"; class X86TestBase : public ::testing::Test { protected: |
