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