summaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'unittests')
-rw-r--r--unittests/Analysis/ProfileSummaryInfoTest.cpp6
-rw-r--r--unittests/Analysis/TargetLibraryInfoTest.cpp46
-rw-r--r--unittests/DebugInfo/CMakeLists.txt2
-rw-r--r--unittests/DebugInfo/CodeView/CMakeLists.txt11
-rw-r--r--unittests/DebugInfo/CodeView/ErrorChecking.h61
-rw-r--r--unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp353
-rw-r--r--unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp2
-rw-r--r--unittests/ExecutionEngine/Orc/OrcTestCommon.h2
-rw-r--r--unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp29
-rw-r--r--unittests/IR/ConstantRangeTest.cpp9
-rw-r--r--unittests/IR/InstructionsTest.cpp7
-rw-r--r--unittests/IR/TypeBuilderTest.cpp30
-rw-r--r--unittests/Support/CMakeLists.txt1
-rw-r--r--unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp4
-rw-r--r--unittests/Support/ParallelTest.cpp53
-rw-r--r--unittests/Support/Path.cpp2
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp65
17 files changed, 619 insertions, 64 deletions
diff --git a/unittests/Analysis/ProfileSummaryInfoTest.cpp b/unittests/Analysis/ProfileSummaryInfoTest.cpp
index 0b4b1de28053b..3454474f0376d 100644
--- a/unittests/Analysis/ProfileSummaryInfoTest.cpp
+++ b/unittests/Analysis/ProfileSummaryInfoTest.cpp
@@ -162,6 +162,12 @@ TEST_F(ProfileSummaryInfoTest, InstrProf) {
EXPECT_TRUE(PSI.isHotCallSite(CS1, &BFI));
EXPECT_FALSE(PSI.isHotCallSite(CS2, &BFI));
+
+ // Test that adding an MD_prof metadata with a hot count on CS2 does not
+ // change its hotness as it has no effect in instrumented profiling.
+ MDBuilder MDB(M->getContext());
+ CI2->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights({400}));
+ EXPECT_FALSE(PSI.isHotCallSite(CS2, &BFI));
}
TEST_F(ProfileSummaryInfoTest, SampleProf) {
diff --git a/unittests/Analysis/TargetLibraryInfoTest.cpp b/unittests/Analysis/TargetLibraryInfoTest.cpp
index 44c141d6a1e9f..9d852cf0301b9 100644
--- a/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -470,6 +470,52 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
"declare i32 @isascii(i32)\n"
"declare i32 @isdigit(i32)\n"
"declare i32 @toascii(i32)\n"
+
+ // These functions were extracted from math-finite.h which provides
+ // functions similar to those in math.h, but optimized for handling
+ // finite values only.
+ "declare double @__acos_finite(double)\n"
+ "declare float @__acosf_finite(float)\n"
+ "declare x86_fp80 @__acosl_finite(x86_fp80)\n"
+ "declare double @__acosh_finite(double)\n"
+ "declare float @__acoshf_finite(float)\n"
+ "declare x86_fp80 @__acoshl_finite(x86_fp80)\n"
+ "declare double @__asin_finite(double)\n"
+ "declare float @__asinf_finite(float)\n"
+ "declare x86_fp80 @__asinl_finite(x86_fp80)\n"
+ "declare double @__atan2_finite(double, double)\n"
+ "declare float @__atan2f_finite(float, float)\n"
+ "declare x86_fp80 @__atan2l_finite(x86_fp80, x86_fp80)\n"
+ "declare double @__atanh_finite(double)\n"
+ "declare float @__atanhf_finite(float)\n"
+ "declare x86_fp80 @__atanhl_finite(x86_fp80)\n"
+ "declare double @__cosh_finite(double)\n"
+ "declare float @__coshf_finite(float)\n"
+ "declare x86_fp80 @__coshl_finite(x86_fp80)\n"
+ "declare double @__exp10_finite(double)\n"
+ "declare float @__exp10f_finite(float)\n"
+ "declare x86_fp80 @__exp10l_finite(x86_fp80)\n"
+ "declare double @__exp2_finite(double)\n"
+ "declare float @__exp2f_finite(float)\n"
+ "declare x86_fp80 @__exp2l_finite(x86_fp80)\n"
+ "declare double @__exp_finite(double)\n"
+ "declare float @__expf_finite(float)\n"
+ "declare x86_fp80 @__expl_finite(x86_fp80)\n"
+ "declare double @__log10_finite(double)\n"
+ "declare float @__log10f_finite(float)\n"
+ "declare x86_fp80 @__log10l_finite(x86_fp80)\n"
+ "declare double @__log2_finite(double)\n"
+ "declare float @__log2f_finite(float)\n"
+ "declare x86_fp80 @__log2l_finite(x86_fp80)\n"
+ "declare double @__log_finite(double)\n"
+ "declare float @__logf_finite(float)\n"
+ "declare x86_fp80 @__logl_finite(x86_fp80)\n"
+ "declare double @__pow_finite(double, double)\n"
+ "declare float @__powf_finite(float, float)\n"
+ "declare x86_fp80 @__powl_finite(x86_fp80, x86_fp80)\n"
+ "declare double @__sinh_finite(double)\n"
+ "declare float @__sinhf_finite(float)\n"
+ "declare x86_fp80 @__sinhl_finite(x86_fp80)\n"
);
for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
diff --git a/unittests/DebugInfo/CMakeLists.txt b/unittests/DebugInfo/CMakeLists.txt
index dae472bafdd71..e38fff58cae6a 100644
--- a/unittests/DebugInfo/CMakeLists.txt
+++ b/unittests/DebugInfo/CMakeLists.txt
@@ -1,3 +1,3 @@
-
+add_subdirectory(CodeView)
add_subdirectory(DWARF)
add_subdirectory(PDB)
diff --git a/unittests/DebugInfo/CodeView/CMakeLists.txt b/unittests/DebugInfo/CodeView/CMakeLists.txt
new file mode 100644
index 0000000000000..854182c4efb41
--- /dev/null
+++ b/unittests/DebugInfo/CodeView/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS
+ DebugInfoCodeView
+ )
+
+set(DebugInfoCodeViewSources
+ RandomAccessVisitorTest.cpp
+ )
+
+add_llvm_unittest(DebugInfoCodeViewTests
+ ${DebugInfoCodeViewSources}
+ )
diff --git a/unittests/DebugInfo/CodeView/ErrorChecking.h b/unittests/DebugInfo/CodeView/ErrorChecking.h
new file mode 100644
index 0000000000000..09310883bf588
--- /dev/null
+++ b/unittests/DebugInfo/CodeView/ErrorChecking.h
@@ -0,0 +1,61 @@
+//===- ErrorChecking.h - Helpers for verifying llvm::Errors -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_UNITTESTS_DEBUGINFO_CODEVIEW_ERRORCHECKING_H
+#define LLVM_UNITTESTS_DEBUGINFO_CODEVIEW_ERRORCHECKING_H
+
+#define EXPECT_NO_ERROR(Err) \
+ { \
+ auto E = Err; \
+ EXPECT_FALSE(static_cast<bool>(E)); \
+ if (E) \
+ consumeError(std::move(E)); \
+ }
+
+#define EXPECT_ERROR(Err) \
+ { \
+ auto E = Err; \
+ EXPECT_TRUE(static_cast<bool>(E)); \
+ if (E) \
+ consumeError(std::move(E)); \
+ }
+
+#define EXPECT_EXPECTED(Exp) \
+ { \
+ auto E = Exp.takeError(); \
+ EXPECT_FALSE(static_cast<bool>(E)); \
+ if (E) { \
+ consumeError(std::move(E)); \
+ return; \
+ } \
+ }
+
+#define EXPECT_EXPECTED_EQ(Val, Exp) \
+ { \
+ auto Result = Exp; \
+ auto E = Result.takeError(); \
+ EXPECT_FALSE(static_cast<bool>(E)); \
+ if (E) { \
+ consumeError(std::move(E)); \
+ return; \
+ } \
+ EXPECT_EQ(Val, *Result); \
+ }
+
+#define EXPECT_UNEXPECTED(Exp) \
+ { \
+ auto E = Exp.takeError(); \
+ EXPECT_TRUE(static_cast<bool>(E)); \
+ if (E) { \
+ consumeError(std::move(E)); \
+ return; \
+ } \
+ }
+
+#endif
diff --git a/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp b/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
new file mode 100644
index 0000000000000..fedb5978da816
--- /dev/null
+++ b/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
@@ -0,0 +1,353 @@
+//===- llvm/unittest/DebugInfo/CodeView/RandomAccessVisitorTest.cpp -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ErrorChecking.h"
+
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
+#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryItemStream.h"
+#include "llvm/Support/Error.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+namespace llvm {
+namespace codeview {
+inline bool operator==(const ArrayRecord &R1, const ArrayRecord &R2) {
+ if (R1.ElementType != R2.ElementType)
+ return false;
+ if (R1.IndexType != R2.IndexType)
+ return false;
+ if (R1.Name != R2.Name)
+ return false;
+ if (R1.Size != R2.Size)
+ return false;
+ return true;
+}
+inline bool operator!=(const ArrayRecord &R1, const ArrayRecord &R2) {
+ return !(R1 == R2);
+}
+
+inline bool operator==(const CVType &R1, const CVType &R2) {
+ if (R1.Type != R2.Type)
+ return false;
+ if (R1.RecordData != R2.RecordData)
+ return false;
+ return true;
+}
+inline bool operator!=(const CVType &R1, const CVType &R2) {
+ return !(R1 == R2);
+}
+}
+}
+
+namespace llvm {
+template <> struct BinaryItemTraits<CVType> {
+ static size_t length(const CVType &Item) { return Item.length(); }
+ static ArrayRef<uint8_t> bytes(const CVType &Item) { return Item.data(); }
+};
+}
+
+namespace {
+
+class MockCallbacks : public TypeVisitorCallbacks {
+public:
+ virtual Error visitTypeBegin(CVType &CVR, TypeIndex Index) {
+ Indices.push_back(Index);
+ return Error::success();
+ }
+ virtual Error visitKnownRecord(CVType &CVR, ArrayRecord &AR) {
+ VisitedRecords.push_back(AR);
+ RawRecords.push_back(CVR);
+ return Error::success();
+ }
+
+ uint32_t count() const {
+ assert(Indices.size() == RawRecords.size());
+ assert(Indices.size() == VisitedRecords.size());
+ return Indices.size();
+ }
+ std::vector<TypeIndex> Indices;
+ std::vector<CVType> RawRecords;
+ std::vector<ArrayRecord> VisitedRecords;
+};
+
+class RandomAccessVisitorTest : public testing::Test {
+public:
+ RandomAccessVisitorTest() {}
+
+ static void SetUpTestCase() {
+ GlobalState = llvm::make_unique<GlobalTestState>();
+
+ TypeTableBuilder Builder(GlobalState->Allocator);
+
+ uint32_t Offset = 0;
+ for (int I = 0; I < 11; ++I) {
+ ArrayRecord AR(TypeRecordKind::Array);
+ AR.ElementType = TypeIndex::Int32();
+ AR.IndexType = TypeIndex::UInt32();
+ AR.Size = I;
+ std::string Name;
+ raw_string_ostream Stream(Name);
+ Stream << "Array [" << I << "]";
+ AR.Name = GlobalState->Strings.save(Stream.str());
+ GlobalState->Records.push_back(AR);
+ GlobalState->Indices.push_back(Builder.writeKnownType(AR));
+
+ CVType Type(TypeLeafKind::LF_ARRAY, Builder.records().back());
+ GlobalState->TypeVector.push_back(Type);
+
+ GlobalState->AllOffsets.push_back(
+ {GlobalState->Indices.back(), ulittle32_t(Offset)});
+ Offset += Type.length();
+ }
+
+ GlobalState->ItemStream.setItems(GlobalState->TypeVector);
+ GlobalState->TypeArray = VarStreamArray<CVType>(GlobalState->ItemStream);
+ }
+
+ static void TearDownTestCase() { GlobalState.reset(); }
+
+ void SetUp() override {
+ TestState = llvm::make_unique<PerTestState>();
+
+ TestState->Pipeline.addCallbackToPipeline(TestState->Deserializer);
+ TestState->Pipeline.addCallbackToPipeline(TestState->Callbacks);
+ }
+
+ void TearDown() override { TestState.reset(); }
+
+protected:
+ bool ValidateDatabaseRecord(const RandomAccessTypeVisitor &Visitor,
+ uint32_t Index) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(Index);
+ if (!Visitor.database().contains(TI))
+ return false;
+ if (GlobalState->TypeVector[Index] != Visitor.database().getTypeRecord(TI))
+ return false;
+ return true;
+ }
+
+ bool ValidateVisitedRecord(uint32_t VisitationOrder,
+ uint32_t GlobalArrayIndex) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(GlobalArrayIndex);
+ if (TI != TestState->Callbacks.Indices[VisitationOrder])
+ return false;
+
+ if (GlobalState->TypeVector[TI.toArrayIndex()] !=
+ TestState->Callbacks.RawRecords[VisitationOrder])
+ return false;
+
+ if (GlobalState->Records[TI.toArrayIndex()] !=
+ TestState->Callbacks.VisitedRecords[VisitationOrder])
+ return false;
+
+ return true;
+ }
+
+ struct GlobalTestState {
+ GlobalTestState() : Strings(Allocator), ItemStream(llvm::support::little) {}
+
+ BumpPtrAllocator Allocator;
+ StringSaver Strings;
+
+ std::vector<ArrayRecord> Records;
+ std::vector<TypeIndex> Indices;
+ std::vector<TypeIndexOffset> AllOffsets;
+ std::vector<CVType> TypeVector;
+ BinaryItemStream<CVType> ItemStream;
+ VarStreamArray<CVType> TypeArray;
+
+ MutableBinaryByteStream Stream;
+ };
+
+ struct PerTestState {
+ FixedStreamArray<TypeIndexOffset> Offsets;
+
+ TypeVisitorCallbackPipeline Pipeline;
+ TypeDeserializer Deserializer;
+ MockCallbacks Callbacks;
+ };
+
+ FixedStreamArray<TypeIndexOffset>
+ createPartialOffsets(MutableBinaryByteStream &Storage,
+ std::initializer_list<uint32_t> Indices) {
+
+ uint32_t Count = Indices.size();
+ uint32_t Size = Count * sizeof(TypeIndexOffset);
+ uint8_t *Buffer = GlobalState->Allocator.Allocate<uint8_t>(Size);
+ MutableArrayRef<uint8_t> Bytes(Buffer, Size);
+ Storage = MutableBinaryByteStream(Bytes, support::little);
+ BinaryStreamWriter Writer(Storage);
+ for (const auto I : Indices)
+ consumeError(Writer.writeObject(GlobalState->AllOffsets[I]));
+
+ BinaryStreamReader Reader(Storage);
+ FixedStreamArray<TypeIndexOffset> Result;
+ consumeError(Reader.readArray(Result, Count));
+ return Result;
+ }
+
+ static std::unique_ptr<GlobalTestState> GlobalState;
+ std::unique_ptr<PerTestState> TestState;
+};
+
+std::unique_ptr<RandomAccessVisitorTest::GlobalTestState>
+ RandomAccessVisitorTest::GlobalState;
+}
+
+TEST_F(RandomAccessVisitorTest, MultipleVisits) {
+ TestState->Offsets = createPartialOffsets(GlobalState->Stream, {0, 8});
+ RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+ GlobalState->TypeVector.size(),
+ TestState->Offsets);
+
+ std::vector<uint32_t> IndicesToVisit = {5, 5, 5};
+
+ for (uint32_t I : IndicesToVisit) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(I);
+ EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
+ }
+
+ // [0,8) should be present
+ EXPECT_EQ(8u, Visitor.database().size());
+ for (uint32_t I = 0; I < 8; ++I)
+ EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
+
+ // 5, 5, 5
+ EXPECT_EQ(3u, TestState->Callbacks.count());
+ for (auto I : enumerate(IndicesToVisit))
+ EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value()));
+}
+
+TEST_F(RandomAccessVisitorTest, DescendingWithinChunk) {
+ // Visit multiple items from the same "chunk" in reverse order. In this
+ // example, it's 7 then 4 then 2. At the end, all records from 0 to 7 should
+ // be known by the database, but only 2, 4, and 7 should have been visited.
+ TestState->Offsets = createPartialOffsets(GlobalState->Stream, {0, 8});
+
+ std::vector<uint32_t> IndicesToVisit = {7, 4, 2};
+
+ RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+ GlobalState->TypeVector.size(),
+ TestState->Offsets);
+
+ for (uint32_t I : IndicesToVisit) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(I);
+ EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
+ }
+
+ // [0, 7]
+ EXPECT_EQ(8u, Visitor.database().size());
+ for (uint32_t I = 0; I < 8; ++I)
+ EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
+
+ // 2, 4, 7
+ EXPECT_EQ(3u, TestState->Callbacks.count());
+ for (auto I : enumerate(IndicesToVisit))
+ EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value()));
+}
+
+TEST_F(RandomAccessVisitorTest, AscendingWithinChunk) {
+ // * Visit multiple items from the same chunk in ascending order, ensuring
+ // that intermediate items are not visited. In the below example, it's
+ // 5 -> 6 -> 7 which come from the [4,8) chunk.
+ TestState->Offsets = createPartialOffsets(GlobalState->Stream, {0, 8});
+
+ std::vector<uint32_t> IndicesToVisit = {2, 4, 7};
+
+ RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+ GlobalState->TypeVector.size(),
+ TestState->Offsets);
+
+ for (uint32_t I : IndicesToVisit) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(I);
+ EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
+ }
+
+ // [0, 7]
+ EXPECT_EQ(8u, Visitor.database().size());
+ for (uint32_t I = 0; I < 8; ++I)
+ EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
+
+ // 2, 4, 7
+ EXPECT_EQ(3u, TestState->Callbacks.count());
+ for (auto &I : enumerate(IndicesToVisit))
+ EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value()));
+}
+
+TEST_F(RandomAccessVisitorTest, StopPrematurelyInChunk) {
+ // * Don't visit the last item in one chunk, ensuring that visitation stops
+ // at the record you specify, and the chunk is only partially visited.
+ // In the below example, this is tested by visiting 0 and 1 but not 2,
+ // all from the [0,3) chunk.
+ TestState->Offsets = createPartialOffsets(GlobalState->Stream, {0, 8});
+
+ std::vector<uint32_t> IndicesToVisit = {0, 1, 2};
+
+ RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+ GlobalState->TypeVector.size(),
+ TestState->Offsets);
+
+ for (uint32_t I : IndicesToVisit) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(I);
+ EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
+ }
+
+ // [0, 8) should be visited.
+ EXPECT_EQ(8u, Visitor.database().size());
+ for (uint32_t I = 0; I < 8; ++I)
+ EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
+
+ // [0, 2]
+ EXPECT_EQ(3u, TestState->Callbacks.count());
+ for (auto I : enumerate(IndicesToVisit))
+ EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value()));
+}
+
+TEST_F(RandomAccessVisitorTest, InnerChunk) {
+ // Test that when a request comes from a chunk in the middle of the partial
+ // offsets array, that items from surrounding chunks are not visited or
+ // added to the database.
+ TestState->Offsets = createPartialOffsets(GlobalState->Stream, {0, 4, 9});
+
+ std::vector<uint32_t> IndicesToVisit = {5, 7};
+
+ RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+ GlobalState->TypeVector.size(),
+ TestState->Offsets);
+
+ for (uint32_t I : IndicesToVisit) {
+ TypeIndex TI = TypeIndex::fromArrayIndex(I);
+ EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
+ }
+
+ // [4, 9)
+ EXPECT_EQ(5u, Visitor.database().size());
+ for (uint32_t I = 4; I < 9; ++I)
+ EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
+
+ // 5, 7
+ EXPECT_EQ(2u, TestState->Callbacks.count());
+ for (auto &I : enumerate(IndicesToVisit))
+ EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value()));
+}
diff --git a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
index 96214a368dce0..362c143c54ef4 100644
--- a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
+++ b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
@@ -304,7 +304,7 @@ TEST(ObjectTransformLayerTest, Main) {
return nullptr;
}
void registerEHFrames(uint8_t *, uint64_t, size_t) override {}
- void deregisterEHFrames(uint8_t *, uint64_t, size_t) override {}
+ void deregisterEHFrames() override {}
bool finalizeMemory(std::string *) override { return false; }
};
diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/unittests/ExecutionEngine/Orc/OrcTestCommon.h
index 7fb26634c7a7a..dff72c6b9d575 100644
--- a/unittests/ExecutionEngine/Orc/OrcTestCommon.h
+++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -101,7 +101,7 @@ class TypeBuilder<DummyStruct, XCompile> {
public:
static StructType *get(LLVMContext &Context) {
return StructType::get(
- TypeBuilder<types::i<32>[256], XCompile>::get(Context), nullptr);
+ TypeBuilder<types::i<32>[256], XCompile>::get(Context));
}
};
diff --git a/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index de99c022fb9dc..c13a75a5cbfe9 100644
--- a/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -90,7 +90,8 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
Objs.push_back(OwningObj.getBinary());
bool DebugSectionSeen = false;
- SectionMemoryManagerWrapper SMMW(DebugSectionSeen);
+ auto SMMW =
+ std::make_shared<SectionMemoryManagerWrapper>(DebugSectionSeen);
auto Resolver =
createLambdaResolver(
[](const std::string &Name) {
@@ -102,7 +103,7 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
{
// Test with ProcessAllSections = false (the default).
- auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
+ auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
ObjLayer.emitAndFinalize(H);
EXPECT_EQ(DebugSectionSeen, false)
<< "Unexpected debug info section";
@@ -112,7 +113,7 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
{
// Test with ProcessAllSections = true.
ObjLayer.setProcessAllSections(true);
- auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
+ auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
ObjLayer.emitAndFinalize(H);
EXPECT_EQ(DebugSectionSeen, true)
<< "Expected debug info section not seen";
@@ -178,14 +179,15 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
return JITSymbol(nullptr);
});
- SectionMemoryManagerWrapper SMMW;
- ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver);
- auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver);
+ auto SMMW = std::make_shared<SectionMemoryManagerWrapper>();
+ ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &*Resolver);
+ auto H = ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &*Resolver);
ObjLayer.emitAndFinalize(H);
-
+ ObjLayer.removeObjectSet(H);
+
// Finalization of module 2 should trigger finalization of module 1.
// Verify that finalize on SMMW is only called once.
- EXPECT_EQ(SMMW.FinalizationCount, 1)
+ EXPECT_EQ(SMMW->FinalizationCount, 1)
<< "Extra call to finalize";
}
@@ -238,14 +240,15 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
std::vector<object::ObjectFile*> Obj2Set;
Obj2Set.push_back(Obj2.getBinary());
- SectionMemoryManagerWrapper SMMW;
+ auto SMMW = std::make_shared<SectionMemoryManagerWrapper>();
NullResolver NR;
- auto H = ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &NR);
- ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &NR);
+ auto H = ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &NR);
+ ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &NR);
ObjLayer.emitAndFinalize(H);
-
+ ObjLayer.removeObjectSet(H);
+
// Only one call to needsToReserveAllocationSpace should have been made.
- EXPECT_EQ(SMMW.NeedsToReserveAllocationSpaceCount, 1)
+ EXPECT_EQ(SMMW->NeedsToReserveAllocationSpaceCount, 1)
<< "More than one call to needsToReserveAllocationSpace "
"(multiple unrelated objects loaded prior to finalization)";
}
diff --git a/unittests/IR/ConstantRangeTest.cpp b/unittests/IR/ConstantRangeTest.cpp
index b22f82154f403..c6c9bf6d6b503 100644
--- a/unittests/IR/ConstantRangeTest.cpp
+++ b/unittests/IR/ConstantRangeTest.cpp
@@ -443,6 +443,11 @@ TEST_F(ConstantRangeTest, Multiply) {
EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 255)).multiply(
ConstantRange(APInt(8, 2), APInt(8, 4))),
ConstantRange(APInt(8, 250), APInt(8, 253)));
+
+ // TODO: This should be return [-2, 0]
+ EXPECT_EQ(ConstantRange(APInt(8, -2)).multiply(
+ ConstantRange(APInt(8, 0), APInt(8, 2))),
+ ConstantRange(APInt(8, -2), APInt(8, 1)));
}
TEST_F(ConstantRangeTest, UMax) {
@@ -703,13 +708,13 @@ TEST(ConstantRange, MakeGuaranteedNoWrapRegion) {
Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
OBO::NoUnsignedWrap);
EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
- NSWForAllValues.getSingleElement()->isMinValue());
+ NUWForAllValues.getSingleElement()->isMinValue());
auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
OBO::NoUnsignedWrap | OBO::NoSignedWrap);
EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
- NSWForAllValues.getSingleElement()->isMinValue());
+ NUWAndNSWForAllValues.getSingleElement()->isMinValue());
ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
diff --git a/unittests/IR/InstructionsTest.cpp b/unittests/IR/InstructionsTest.cpp
index 7c75aaec17539..b8d398c5cc388 100644
--- a/unittests/IR/InstructionsTest.cpp
+++ b/unittests/IR/InstructionsTest.cpp
@@ -21,6 +21,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Operator.h"
+#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"
#include <memory>
@@ -740,5 +741,11 @@ TEST(InstructionsTest, SwitchInst) {
EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor());
}
+TEST(InstructionsTest, CommuteShuffleMask) {
+ SmallVector<int, 16> Indices({-1, 0, 7});
+ ShuffleVectorInst::commuteShuffleMask(Indices, 4);
+ EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef<int>({-1, 4, 3})));
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/unittests/IR/TypeBuilderTest.cpp b/unittests/IR/TypeBuilderTest.cpp
index f2dccac001a4b..9ba776543d944 100644
--- a/unittests/IR/TypeBuilderTest.cpp
+++ b/unittests/IR/TypeBuilderTest.cpp
@@ -264,23 +264,21 @@ namespace {
TEST(TypeBuilderTest, Extensions) {
LLVMContext Context;
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<int, false>::get(Context),
- TypeBuilder<int *, false>::get(Context),
- TypeBuilder<void *[], false>::get(Context), (void *)nullptr)),
+ EXPECT_EQ(PointerType::getUnqual(
+ StructType::get(TypeBuilder<int, false>::get(Context),
+ TypeBuilder<int *, false>::get(Context),
+ TypeBuilder<void *[], false>::get(Context))),
(TypeBuilder<MyType *, false>::get(Context)));
- EXPECT_EQ(
- PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(Context),
- TypeBuilder<types::i<32> *, false>::get(Context),
- TypeBuilder<types::i<8> *[], false>::get(Context), (void *)nullptr)),
- (TypeBuilder<MyPortableType *, false>::get(Context)));
- EXPECT_EQ(
- PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(Context),
- TypeBuilder<types::i<32> *, false>::get(Context),
- TypeBuilder<types::i<8> *[], false>::get(Context), (void *)nullptr)),
- (TypeBuilder<MyPortableType *, true>::get(Context)));
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(
+ TypeBuilder<types::i<32>, false>::get(Context),
+ TypeBuilder<types::i<32> *, false>::get(Context),
+ TypeBuilder<types::i<8> *[], false>::get(Context))),
+ (TypeBuilder<MyPortableType *, false>::get(Context)));
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(
+ TypeBuilder<types::i<32>, false>::get(Context),
+ TypeBuilder<types::i<32> *, false>::get(Context),
+ TypeBuilder<types::i<8> *[], false>::get(Context))),
+ (TypeBuilder<MyPortableType *, true>::get(Context)));
}
} // anonymous namespace
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index 1f677100dcef3..f8d3c1c9a8c77 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -36,6 +36,7 @@ add_llvm_unittest(SupportTests
MemoryBufferTest.cpp
MemoryTest.cpp
NativeFormatTests.cpp
+ ParallelTest.cpp
Path.cpp
ProcessTest.cpp
ProgramTest.cpp
diff --git a/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp b/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
index d46eadc9a0460..0674a91282a1a 100644
--- a/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
+++ b/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
@@ -23,8 +23,10 @@ using namespace llvm::sys;
extern "C" PIPSQUEAK_EXPORT const char *TestA() { return "ProcessCall"; }
std::string LibPath() {
+ const std::vector<testing::internal::string>& Argvs = testing::internal::GetArgvs();
+ const char *Argv0 = Argvs.size() > 0 ? Argvs[0].c_str() : "DynamicLibraryTests";
void *Ptr = (void*)(intptr_t)TestA;
- std::string Path = fs::getMainExecutable("DynamicLibraryTests", Ptr);
+ std::string Path = fs::getMainExecutable(Argv0, Ptr);
llvm::SmallString<256> Buf(path::parent_path(Path));
path::append(Buf, "PipSqueak.so");
return Buf.str();
diff --git a/unittests/Support/ParallelTest.cpp b/unittests/Support/ParallelTest.cpp
new file mode 100644
index 0000000000000..d734e0dd8586a
--- /dev/null
+++ b/unittests/Support/ParallelTest.cpp
@@ -0,0 +1,53 @@
+//===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Parallel.h unit tests.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Parallel.h"
+#include "gtest/gtest.h"
+#include <array>
+#include <random>
+
+uint32_t array[1024 * 1024];
+
+using namespace llvm;
+
+// Tests below are hanging up on mingw. Investigating.
+#if !defined(__MINGW32__)
+
+TEST(Parallel, sort) {
+ std::mt19937 randEngine;
+ std::uniform_int_distribution<uint32_t> dist;
+
+ for (auto &i : array)
+ i = dist(randEngine);
+
+ sort(parallel::par, std::begin(array), std::end(array));
+ ASSERT_TRUE(std::is_sorted(std::begin(array), std::end(array)));
+}
+
+TEST(Parallel, parallel_for) {
+ // We need to test the case with a TaskSize > 1. We are white-box testing
+ // here. The TaskSize is calculated as (End - Begin) / 1024 at the time of
+ // writing.
+ uint32_t range[2050];
+ std::fill(range, range + 2050, 1);
+ for_each_n(parallel::par, 0, 2049, [&range](size_t I) { ++range[I]; });
+
+ uint32_t expected[2049];
+ std::fill(expected, expected + 2049, 2);
+ ASSERT_TRUE(std::equal(range, range + 2049, expected));
+ // Check that we don't write past the end of the requested range.
+ ASSERT_EQ(range[2049], 1u);
+}
+
+#endif
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 426aff47c7462..a4bdcb5c79a27 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -1047,7 +1047,7 @@ TEST_F(FileSystemTest, MD5) {
SmallString<64> TempPath;
ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
StringRef Data("abcdefghijklmnopqrstuvwxyz");
- write(FD, Data.data(), Data.size());
+ ASSERT_EQ(write(FD, Data.data(), Data.size()), static_cast<ssize_t>(Data.size()));
lseek(FD, 0, SEEK_SET);
auto Hash = fs::md5_contents(FD);
::close(FD);
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index 2f4ee8636530d..83f146dca704a 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -296,7 +296,6 @@ protected:
Value* AllocaContent = IBuilder.getInt32(1);
Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
- Instruction* Terminator = IBuilder.CreateRetVoid();
// Create a local variable around the alloca
auto *IntType = DBuilder.createBasicType("int", 32, dwarf::DW_ATE_signed);
@@ -306,12 +305,25 @@ protected:
auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
- Terminator);
- // Finalize the debug info
+ Entry);
+ // Also create an inlined variable.
+ auto *InlinedSP =
+ DBuilder.createFunction(CU, "inlined", "inlined", File, 8, FuncType,
+ true, true, 9, DINode::FlagZero, false);
+ auto *InlinedVar =
+ DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, IntType, true);
+ auto *Scope = DBuilder.createLexicalBlock(
+ DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1);
+ auto InlinedDL =
+ DebugLoc::get(9, 4, Scope, DebugLoc::get(5, 2, Subprogram));
+ IBuilder.SetCurrentDebugLocation(InlinedDL);
+ DBuilder.insertDeclare(Alloca, InlinedVar, E, InlinedDL, Store);
+ IBuilder.CreateStore(IBuilder.getInt32(2), Alloca);
+ // Finalize the debug info.
DBuilder.finalize();
+ IBuilder.CreateRetVoid();
-
- // Create another, empty, compile unit
+ // Create another, empty, compile unit.
DIBuilder DBuilder2(*M);
DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
DBuilder.createFile("extra.c", "/file/dir"),
@@ -345,15 +357,8 @@ TEST_F(CloneFunc, NewFunctionCreated) {
// function, while the original subprogram still points to the old one.
TEST_F(CloneFunc, Subprogram) {
EXPECT_FALSE(verifyModule(*M));
-
- unsigned SubprogramCount = Finder->subprogram_count();
- EXPECT_EQ(1U, SubprogramCount);
-
- auto Iter = Finder->subprograms().begin();
- auto *Sub = cast<DISubprogram>(*Iter);
-
- EXPECT_TRUE(Sub == OldFunc->getSubprogram());
- EXPECT_TRUE(Sub == NewFunc->getSubprogram());
+ EXPECT_EQ(3U, Finder->subprogram_count());
+ EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram());
}
// Test that instructions in the old function still belong to it in the
@@ -380,8 +385,8 @@ TEST_F(CloneFunc, InstructionOwnership) {
EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
// But that they belong to different functions
- auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
- auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
+ auto *OldSubprogram = cast<DISubprogram>(OldDL.getInlinedAtScope());
+ auto *NewSubprogram = cast<DISubprogram>(NewDL.getInlinedAtScope());
EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
}
@@ -416,22 +421,26 @@ TEST_F(CloneFunc, DebugIntrinsics) {
EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
getParent()->getParent());
- // Old variable must belong to the old function
- EXPECT_EQ(OldFunc->getSubprogram(),
- cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
- // New variable must belong to the New function
- EXPECT_EQ(NewFunc->getSubprogram(),
- cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
+ if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
+ // Old variable must belong to the old function.
+ EXPECT_EQ(OldFunc->getSubprogram(),
+ cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
+ // New variable must belong to the new function.
+ EXPECT_EQ(NewFunc->getSubprogram(),
+ cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
+ }
} else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
EXPECT_TRUE(NewIntrin);
- // Old variable must belong to the old function
- EXPECT_EQ(OldFunc->getSubprogram(),
- cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
- // New variable must belong to the New function
- EXPECT_EQ(NewFunc->getSubprogram(),
- cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
+ if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
+ // Old variable must belong to the old function.
+ EXPECT_EQ(OldFunc->getSubprogram(),
+ cast<DISubprogram>(OldIntrin->getVariable()->getScope()));
+ // New variable must belong to the new function.
+ EXPECT_EQ(NewFunc->getSubprogram(),
+ cast<DISubprogram>(NewIntrin->getVariable()->getScope()));
+ }
}
++OldIter;