diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-01-14 19:56:11 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-01-14 19:56:11 +0000 |
commit | ca82c85029ae0befb17bc14a4faa9f3d51dd72b3 (patch) | |
tree | 2df9dea922feef454abe6d1499112a4abc270079 /gnu/llvm/unittests/IR | |
parent | 04c0d479b956b5e4f4e20ce989b95443aa03da0b (diff) |
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm/unittests/IR')
21 files changed, 1327 insertions, 491 deletions
diff --git a/gnu/llvm/unittests/IR/AttributesTest.cpp b/gnu/llvm/unittests/IR/AttributesTest.cpp index ebcb772bc37..9f8013ff181 100644 --- a/gnu/llvm/unittests/IR/AttributesTest.cpp +++ b/gnu/llvm/unittests/IR/AttributesTest.cpp @@ -34,6 +34,15 @@ TEST(Attributes, Uniquing) { TEST(Attributes, Ordering) { LLVMContext C; + Attribute Align4 = Attribute::get(C, Attribute::Alignment, 4); + Attribute Align5 = Attribute::get(C, Attribute::Alignment, 5); + Attribute Deref4 = Attribute::get(C, Attribute::Dereferenceable, 4); + Attribute Deref5 = Attribute::get(C, Attribute::Dereferenceable, 5); + EXPECT_TRUE(Align4 < Align5); + EXPECT_TRUE(Align4 < Deref4); + EXPECT_TRUE(Align4 < Deref5); + EXPECT_TRUE(Align5 < Deref4); + AttributeSet ASs[] = { AttributeSet::get(C, 2, Attribute::ZExt), AttributeSet::get(C, 1, Attribute::SExt) diff --git a/gnu/llvm/unittests/IR/CMakeLists.txt b/gnu/llvm/unittests/IR/CMakeLists.txt index 5aad8edc913..2baa4370c70 100644 --- a/gnu/llvm/unittests/IR/CMakeLists.txt +++ b/gnu/llvm/unittests/IR/CMakeLists.txt @@ -11,9 +11,12 @@ set(IRSources ConstantRangeTest.cpp ConstantsTest.cpp DebugInfoTest.cpp + DebugTypeODRUniquingTest.cpp DominatorTreeTest.cpp + FunctionTest.cpp IRBuilderTest.cpp InstructionsTest.cpp + IntrinsicsTest.cpp LegacyPassManagerTest.cpp MDBuilderTest.cpp MetadataTest.cpp diff --git a/gnu/llvm/unittests/IR/ConstantRangeTest.cpp b/gnu/llvm/unittests/IR/ConstantRangeTest.cpp index 1f32eea3e43..f7a8a82043b 100644 --- a/gnu/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/gnu/llvm/unittests/IR/ConstantRangeTest.cpp @@ -450,6 +450,45 @@ TEST_F(ConstantRangeTest, SMax) { EXPECT_EQ(One.smax(One), One); } +TEST_F(ConstantRangeTest, UMin) { + EXPECT_EQ(Full.umin(Full), Full); + EXPECT_EQ(Full.umin(Empty), Empty); + EXPECT_EQ(Full.umin(Some), ConstantRange(APInt(16, 0), APInt(16, 0xaaa))); + EXPECT_EQ(Full.umin(Wrap), Full); + EXPECT_EQ(Empty.umin(Empty), Empty); + EXPECT_EQ(Empty.umin(Some), Empty); + EXPECT_EQ(Empty.umin(Wrap), Empty); + EXPECT_EQ(Empty.umin(One), Empty); + EXPECT_EQ(Some.umin(Some), Some); + EXPECT_EQ(Some.umin(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa))); + EXPECT_EQ(Some.umin(One), One); + // TODO: ConstantRange is currently over-conservative here. + EXPECT_EQ(Wrap.umin(Wrap), Full); + EXPECT_EQ(Wrap.umin(One), ConstantRange(APInt(16, 0), APInt(16, 0xb))); + EXPECT_EQ(One.umin(One), One); +} + +TEST_F(ConstantRangeTest, SMin) { + EXPECT_EQ(Full.smin(Full), Full); + EXPECT_EQ(Full.smin(Empty), Empty); + EXPECT_EQ(Full.smin(Some), ConstantRange(APInt(16, (uint64_t)INT16_MIN), + APInt(16, 0xaaa))); + EXPECT_EQ(Full.smin(Wrap), Full); + EXPECT_EQ(Empty.smin(Empty), Empty); + EXPECT_EQ(Empty.smin(Some), Empty); + EXPECT_EQ(Empty.smin(Wrap), Empty); + EXPECT_EQ(Empty.smin(One), Empty); + EXPECT_EQ(Some.smin(Some), Some); + EXPECT_EQ(Some.smin(Wrap), ConstantRange(APInt(16, (uint64_t)INT16_MIN), + APInt(16, 0xaaa))); + EXPECT_EQ(Some.smin(One), One); + // TODO: ConstantRange is currently over-conservative here. + EXPECT_EQ(Wrap.smin(Wrap), Full); + EXPECT_EQ(Wrap.smin(One), ConstantRange(APInt(16, (uint64_t)INT16_MIN), + APInt(16, 0xb))); + EXPECT_EQ(One.smin(One), One); +} + TEST_F(ConstantRangeTest, UDiv) { EXPECT_EQ(Full.udiv(Full), Full); EXPECT_EQ(Full.udiv(Empty), Empty); @@ -569,7 +608,7 @@ TEST(ConstantRange, MakeSatisfyingICmpRegion) { ConstantRange(APInt(8, 4), APInt(8, -128))); } -TEST(ConstantRange, MakeOverflowingRegion) { +TEST(ConstantRange, MakeGuaranteedNoWrapRegion) { const int IntMin4Bits = 8; const int IntMax4Bits = 7; typedef OverflowingBinaryOperator OBO; @@ -577,17 +616,17 @@ TEST(ConstantRange, MakeOverflowingRegion) { for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) { APInt C(4, Const, true /* = isSigned */); - auto NUWRegion = - ConstantRange::makeNoWrapRegion(Instruction::Add, C, OBO::NoUnsignedWrap); + auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, C, OBO::NoUnsignedWrap); EXPECT_FALSE(NUWRegion.isEmptySet()); - auto NSWRegion = - ConstantRange::makeNoWrapRegion(Instruction::Add, C, OBO::NoSignedWrap); + auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, C, OBO::NoSignedWrap); EXPECT_FALSE(NSWRegion.isEmptySet()); - auto NoWrapRegion = ConstantRange::makeNoWrapRegion( + auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion( Instruction::Add, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap); EXPECT_FALSE(NoWrapRegion.isEmptySet()); @@ -618,6 +657,109 @@ TEST(ConstantRange, MakeOverflowingRegion) { EXPECT_FALSE(Overflow); } } + + auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, ConstantRange(32, /* isFullSet = */ true), + OBO::NoSignedWrap); + EXPECT_TRUE(NSWForAllValues.isSingleElement() && + NSWForAllValues.getSingleElement()->isMinValue()); + + auto NUWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, ConstantRange(32, /* isFullSet = */ true), + OBO::NoUnsignedWrap); + EXPECT_TRUE(NUWForAllValues.isSingleElement() && + NSWForAllValues.getSingleElement()->isMinValue()); + + auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, ConstantRange(32, /* isFullSet = */ true), + OBO::NoUnsignedWrap | OBO::NoSignedWrap); + EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() && + NSWForAllValues.getSingleElement()->isMinValue()); + + ConstantRange OneToFive(APInt(32, 1), APInt(32, 6)); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, OneToFive, OBO::NoSignedWrap), + ConstantRange(APInt::getSignedMinValue(32), + APInt::getSignedMaxValue(32) - 4)); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, OneToFive, OBO::NoUnsignedWrap), + ConstantRange(APInt::getMinValue(32), APInt::getMinValue(32) - 5)); + EXPECT_EQ( + ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap), + ConstantRange(APInt::getMinValue(32), APInt::getSignedMaxValue(32) - 4)); + + ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1)); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, MinusFiveToMinusTwo, OBO::NoSignedWrap), + ConstantRange(APInt::getSignedMinValue(32) + 5, + APInt::getSignedMinValue(32))); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, MinusFiveToMinusTwo, OBO::NoUnsignedWrap), + ConstantRange(APInt(32, 0), APInt(32, 2))); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, MinusFiveToMinusTwo, + OBO::NoUnsignedWrap | OBO::NoSignedWrap), + ConstantRange(APInt(32, 0), APInt(32, 2))); + + ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2)); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, MinusOneToOne, OBO::NoSignedWrap), + ConstantRange(APInt::getSignedMinValue(32) + 1, + APInt::getSignedMinValue(32) - 1)); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, MinusOneToOne, OBO::NoUnsignedWrap), + ConstantRange(APInt(32, 0), APInt(32, 1))); + EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::Add, MinusOneToOne, + OBO::NoUnsignedWrap | OBO::NoSignedWrap), + ConstantRange(APInt(32, 0), APInt(32, 1))); +} + +TEST(ConstantRange, GetEquivalentICmp) { + APInt RHS; + CmpInst::Predicate Pred; + + EXPECT_TRUE(ConstantRange(APInt::getMinValue(32), APInt(32, 100)) + .getEquivalentICmp(Pred, RHS)); + EXPECT_EQ(Pred, CmpInst::ICMP_ULT); + EXPECT_EQ(RHS, APInt(32, 100)); + + EXPECT_TRUE(ConstantRange(APInt::getSignedMinValue(32), APInt(32, 100)) + .getEquivalentICmp(Pred, RHS)); + EXPECT_EQ(Pred, CmpInst::ICMP_SLT); + EXPECT_EQ(RHS, APInt(32, 100)); + + EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getMinValue(32)) + .getEquivalentICmp(Pred, RHS)); + EXPECT_EQ(Pred, CmpInst::ICMP_UGE); + EXPECT_EQ(RHS, APInt(32, 100)); + + EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getSignedMinValue(32)) + .getEquivalentICmp(Pred, RHS)); + EXPECT_EQ(Pred, CmpInst::ICMP_SGE); + EXPECT_EQ(RHS, APInt(32, 100)); + + EXPECT_TRUE( + ConstantRange(32, /*isFullSet=*/true).getEquivalentICmp(Pred, RHS)); + EXPECT_EQ(Pred, CmpInst::ICMP_UGE); + EXPECT_EQ(RHS, APInt(32, 0)); + + EXPECT_TRUE( + ConstantRange(32, /*isFullSet=*/false).getEquivalentICmp(Pred, RHS)); + EXPECT_EQ(Pred, CmpInst::ICMP_ULT); + EXPECT_EQ(RHS, APInt(32, 0)); + + EXPECT_FALSE(ConstantRange(APInt(32, 100), APInt(32, 200)) + .getEquivalentICmp(Pred, RHS)); + + EXPECT_FALSE(ConstantRange(APInt::getSignedMinValue(32) - APInt(32, 100), + APInt::getSignedMinValue(32) + APInt(32, 100)) + .getEquivalentICmp(Pred, RHS)); + + EXPECT_FALSE(ConstantRange(APInt::getMinValue(32) - APInt(32, 100), + APInt::getMinValue(32) + APInt(32, 100)) + .getEquivalentICmp(Pred, RHS)); } } // anonymous namespace diff --git a/gnu/llvm/unittests/IR/ConstantsTest.cpp b/gnu/llvm/unittests/IR/ConstantsTest.cpp index 7471584097d..6959ac85e49 100644 --- a/gnu/llvm/unittests/IR/ConstantsTest.cpp +++ b/gnu/llvm/unittests/IR/ConstantsTest.cpp @@ -22,7 +22,8 @@ namespace llvm { namespace { TEST(ConstantsTest, Integer_i1) { - IntegerType* Int1 = IntegerType::get(getGlobalContext(), 1); + LLVMContext Context; + IntegerType *Int1 = IntegerType::get(Context, 1); Constant* One = ConstantInt::get(Int1, 1, true); Constant* Zero = ConstantInt::get(Int1, 0); Constant* NegOne = ConstantInt::get(Int1, static_cast<uint64_t>(-1), true); @@ -103,7 +104,8 @@ TEST(ConstantsTest, Integer_i1) { } TEST(ConstantsTest, IntSigns) { - IntegerType* Int8Ty = Type::getInt8Ty(getGlobalContext()); + LLVMContext Context; + IntegerType *Int8Ty = Type::getInt8Ty(Context); EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue()); EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue()); EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue()); @@ -116,16 +118,17 @@ TEST(ConstantsTest, IntSigns) { } TEST(ConstantsTest, FP128Test) { - Type *FP128Ty = Type::getFP128Ty(getGlobalContext()); + LLVMContext Context; + Type *FP128Ty = Type::getFP128Ty(Context); - IntegerType *Int128Ty = Type::getIntNTy(getGlobalContext(), 128); + IntegerType *Int128Ty = Type::getIntNTy(Context, 128); Constant *Zero128 = Constant::getNullValue(Int128Ty); Constant *X = ConstantExpr::getUIToFP(Zero128, FP128Ty); EXPECT_TRUE(isa<ConstantFP>(X)); } TEST(ConstantsTest, PointerCast) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; Type *Int8PtrTy = Type::getInt8PtrTy(C); Type *Int32PtrTy = Type::getInt32PtrTy(C); Type *Int64Ty = Type::getInt64Ty(C); @@ -152,6 +155,27 @@ TEST(ConstantsTest, PointerCast) { EXPECT_EQ(Constant::getNullValue(Int32PtrVecTy), ConstantExpr::getPointerCast( Constant::getNullValue(Int8PtrVecTy), Int32PtrVecTy)); + + Type *Int32Ptr1Ty = Type::getInt32PtrTy(C, 1); + ConstantInt *K = ConstantInt::get(Type::getInt64Ty(C), 1234); + + // Make sure that addrspacecast of inttoptr is not folded away. + EXPECT_NE(K, + ConstantExpr::getAddrSpaceCast( + ConstantExpr::getIntToPtr(K, Int32PtrTy), Int32Ptr1Ty)); + EXPECT_NE(K, + ConstantExpr::getAddrSpaceCast( + ConstantExpr::getIntToPtr(K, Int32Ptr1Ty), Int32PtrTy)); + + Constant *NullInt32Ptr0 = Constant::getNullValue(Int32PtrTy); + Constant *NullInt32Ptr1 = Constant::getNullValue(Int32Ptr1Ty); + + // Make sure that addrspacecast of null is not folded away. + EXPECT_NE(Constant::getNullValue(Int32PtrTy), + ConstantExpr::getAddrSpaceCast(NullInt32Ptr0, Int32Ptr1Ty)); + + EXPECT_NE(Constant::getNullValue(Int32Ptr1Ty), + ConstantExpr::getAddrSpaceCast(NullInt32Ptr1, Int32PtrTy)); } #define CHECK(x, y) { \ @@ -165,14 +189,15 @@ TEST(ConstantsTest, PointerCast) { } TEST(ConstantsTest, AsInstructionsTest) { - std::unique_ptr<Module> M(new Module("MyModule", getGlobalContext())); + LLVMContext Context; + std::unique_ptr<Module> M(new Module("MyModule", Context)); - Type *Int64Ty = Type::getInt64Ty(getGlobalContext()); - Type *Int32Ty = Type::getInt32Ty(getGlobalContext()); - Type *Int16Ty = Type::getInt16Ty(getGlobalContext()); - Type *Int1Ty = Type::getInt1Ty(getGlobalContext()); - Type *FloatTy = Type::getFloatTy(getGlobalContext()); - Type *DoubleTy = Type::getDoubleTy(getGlobalContext()); + Type *Int64Ty = Type::getInt64Ty(Context); + Type *Int32Ty = Type::getInt32Ty(Context); + Type *Int16Ty = Type::getInt16Ty(Context); + Type *Int1Ty = Type::getInt1Ty(Context); + Type *FloatTy = Type::getFloatTy(Context); + Type *DoubleTy = Type::getDoubleTy(Context); Constant *Global = M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty)); @@ -189,8 +214,7 @@ TEST(ConstantsTest, AsInstructionsTest) { Constant *One = ConstantInt::get(Int32Ty, 1); Constant *Two = ConstantInt::get(Int64Ty, 2); - Constant *Big = ConstantInt::get(getGlobalContext(), - APInt{256, uint64_t(-1), true}); + Constant *Big = ConstantInt::get(Context, APInt{256, uint64_t(-1), true}); Constant *Elt = ConstantInt::get(Int16Ty, 2015); Constant *Undef16 = UndefValue::get(Int16Ty); Constant *Undef64 = UndefValue::get(Int64Ty); @@ -278,9 +302,10 @@ TEST(ConstantsTest, AsInstructionsTest) { #ifdef GTEST_HAS_DEATH_TEST #ifndef NDEBUG TEST(ConstantsTest, ReplaceWithConstantTest) { - std::unique_ptr<Module> M(new Module("MyModule", getGlobalContext())); + LLVMContext Context; + std::unique_ptr<Module> M(new Module("MyModule", Context)); - Type *Int32Ty = Type::getInt32Ty(getGlobalContext()); + Type *Int32Ty = Type::getInt32Ty(Context); Constant *One = ConstantInt::get(Int32Ty, 1); Constant *Global = diff --git a/gnu/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/gnu/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp new file mode 100644 index 00000000000..2c899d85d1f --- /dev/null +++ b/gnu/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp @@ -0,0 +1,156 @@ +//===- DebugTypeODRUniquingTest.cpp - Debug type ODR uniquing tests -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(DebugTypeODRUniquingTest, enableDebugTypeODRUniquing) { + LLVMContext Context; + EXPECT_FALSE(Context.isODRUniquingDebugTypes()); + Context.enableDebugTypeODRUniquing(); + EXPECT_TRUE(Context.isODRUniquingDebugTypes()); + Context.disableDebugTypeODRUniquing(); + EXPECT_FALSE(Context.isODRUniquingDebugTypes()); +} + +TEST(DebugTypeODRUniquingTest, getODRType) { + LLVMContext Context; + MDString &UUID = *MDString::get(Context, "string"); + + // Without a type map, this should return null. + EXPECT_FALSE(DICompositeType::getODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr)); + + // Enable the mapping. There still shouldn't be a type. + Context.enableDebugTypeODRUniquing(); + EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); + + // Create some ODR-uniqued type. + auto &CT = *DICompositeType::getODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr); + EXPECT_EQ(UUID.getString(), CT.getIdentifier()); + + // Check that we get it back, even if we change a field. + EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); + EXPECT_EQ( + &CT, DICompositeType::getODRType(Context, UUID, dwarf::DW_TAG_class_type, + nullptr, nullptr, 0, nullptr, nullptr, 0, + 0, 0, 0, nullptr, 0, nullptr, nullptr)); + EXPECT_EQ(&CT, DICompositeType::getODRType( + Context, UUID, dwarf::DW_TAG_class_type, + MDString::get(Context, "name"), nullptr, 0, nullptr, + nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr)); + + // Check that it's discarded with the type map. + Context.disableDebugTypeODRUniquing(); + EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); + + // And it shouldn't magically reappear... + Context.enableDebugTypeODRUniquing(); + EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); +} + +TEST(DebugTypeODRUniquingTest, buildODRType) { + LLVMContext Context; + Context.enableDebugTypeODRUniquing(); + + // Build an ODR type that's a forward decl. + MDString &UUID = *MDString::get(Context, "Type"); + auto &CT = *DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr); + EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); + EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); + + // Update with another forward decl. This should be a no-op. + EXPECT_EQ(&CT, DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr)); + EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); + + // Update with a definition. This time we should see a change. + EXPECT_EQ(&CT, DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr)); + EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); + + // Further updates should be ignored. + EXPECT_EQ(&CT, DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr)); + EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); + EXPECT_EQ(&CT, DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, + nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr)); + EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); +} + +TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { + LLVMContext Context; + Context.enableDebugTypeODRUniquing(); + + // Build an ODR type that's a forward decl with no other fields set. + MDString &UUID = *MDString::get(Context, "UUID"); + auto &CT = *DICompositeType::buildODRType( + Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, + DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr); + +// Create macros for running through all the fields except Identifier and Flags. +#define FOR_EACH_MDFIELD() \ + DO_FOR_FIELD(Name) \ + DO_FOR_FIELD(File) \ + DO_FOR_FIELD(Scope) \ + DO_FOR_FIELD(BaseType) \ + DO_FOR_FIELD(Elements) \ + DO_FOR_FIELD(VTableHolder) \ + DO_FOR_FIELD(TemplateParams) +#define FOR_EACH_INLINEFIELD() \ + DO_FOR_FIELD(Tag) \ + DO_FOR_FIELD(Line) \ + DO_FOR_FIELD(SizeInBits) \ + DO_FOR_FIELD(AlignInBits) \ + DO_FOR_FIELD(OffsetInBits) \ + DO_FOR_FIELD(RuntimeLang) + +// Create all the fields. +#define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X); + FOR_EACH_MDFIELD(); +#undef DO_FOR_FIELD + unsigned NonZeroInit = 0; +#define DO_FOR_FIELD(X) auto X = ++NonZeroInit; + FOR_EACH_INLINEFIELD(); +#undef DO_FOR_FIELD + + // Replace all the fields with new values that are distinct from each other. + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, Tag, Name, File, Line, Scope, BaseType, + SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial, + Elements, RuntimeLang, VTableHolder, TemplateParams)); + + // Confirm that all the right fields got updated. +#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X()); + FOR_EACH_MDFIELD(); +#undef DO_FOR_FIELD +#undef FOR_EACH_MDFIELD +#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X()); + FOR_EACH_INLINEFIELD(); +#undef DO_FOR_FIELD +#undef FOR_EACH_INLINEFIELD + EXPECT_EQ(DINode::FlagArtificial, CT.getFlags()); + EXPECT_EQ(&UUID, CT.getRawIdentifier()); +} + +} // end namespace diff --git a/gnu/llvm/unittests/IR/DominatorTreeTest.cpp b/gnu/llvm/unittests/IR/DominatorTreeTest.cpp index 3aef4d64cbc..6c49deb32d9 100644 --- a/gnu/llvm/unittests/IR/DominatorTreeTest.cpp +++ b/gnu/llvm/unittests/IR/DominatorTreeTest.cpp @@ -29,7 +29,8 @@ namespace llvm { bool runOnFunction(Function &F) override { DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>(); + PostDominatorTree *PDT = + &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); Function::iterator FI = F.begin(); BasicBlock *BB0 = &*FI++; @@ -206,7 +207,7 @@ namespace llvm { } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<DominatorTreeWrapperPass>(); - AU.addRequired<PostDominatorTree>(); + AU.addRequired<PostDominatorTreeWrapperPass>(); } DPass() : FunctionPass(ID) { initializeDPassPass(*PassRegistry::getPassRegistry()); @@ -214,7 +215,7 @@ namespace llvm { }; char DPass::ID = 0; - std::unique_ptr<Module> makeLLVMModule(DPass *P) { + std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, DPass *P) { const char *ModuleStrig = "declare i32 @g()\n" \ "define void @f(i32 %x) personality i32 ()* @g {\n" \ @@ -238,14 +239,14 @@ namespace llvm { " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n" " ret void\n" \ "}\n"; - LLVMContext &C = getGlobalContext(); SMDiagnostic Err; - return parseAssemblyString(ModuleStrig, Err, C); + return parseAssemblyString(ModuleStrig, Err, Context); } TEST(DominatorTree, Unreachable) { DPass *P = new DPass(); - std::unique_ptr<Module> M = makeLLVMModule(P); + LLVMContext Context; + std::unique_ptr<Module> M = makeLLVMModule(Context, P); legacy::PassManager Passes; Passes.add(P); Passes.run(*M); @@ -255,5 +256,5 @@ namespace llvm { INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false) diff --git a/gnu/llvm/unittests/IR/FunctionTest.cpp b/gnu/llvm/unittests/IR/FunctionTest.cpp new file mode 100644 index 00000000000..fb458597c37 --- /dev/null +++ b/gnu/llvm/unittests/IR/FunctionTest.cpp @@ -0,0 +1,112 @@ +//===- FunctionTest.cpp - Function unit tests -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Function.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(FunctionTest, hasLazyArguments) { + LLVMContext C; + + Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)}; + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false); + + // Functions start out with lazy arguments. + std::unique_ptr<Function> F( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); + EXPECT_TRUE(F->hasLazyArguments()); + + // Checking for empty or size shouldn't force arguments to be instantiated. + EXPECT_FALSE(F->arg_empty()); + EXPECT_TRUE(F->hasLazyArguments()); + EXPECT_EQ(2u, F->arg_size()); + EXPECT_TRUE(F->hasLazyArguments()); + + // The argument list should be populated at first access. + (void)F->arg_begin(); + EXPECT_FALSE(F->hasLazyArguments()); +} + +TEST(FunctionTest, stealArgumentListFrom) { + LLVMContext C; + + Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)}; + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false); + std::unique_ptr<Function> F1( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F1")); + std::unique_ptr<Function> F2( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F1")); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); + + // Steal arguments before they've been accessed. Nothing should change; both + // functions should still have lazy arguments. + // + // steal(empty); drop (empty) + F1->stealArgumentListFrom(*F2); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); + + // Save arguments from F1 for later assertions. F1 won't have lazy arguments + // anymore. + SmallVector<Argument *, 4> Args; + for (Argument &A : F1->args()) + Args.push_back(&A); + EXPECT_EQ(2u, Args.size()); + EXPECT_FALSE(F1->hasLazyArguments()); + + // Steal arguments from F1 to F2. F1's arguments should be lazy again. + // + // steal(real); drop (empty) + F2->stealArgumentListFrom(*F1); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_FALSE(F2->hasLazyArguments()); + unsigned I = 0; + for (Argument &A : F2->args()) { + EXPECT_EQ(Args[I], &A); + I++; + } + EXPECT_EQ(2u, I); + + // Check that arguments in F1 don't have pointer equality with the saved ones. + // This also instantiates F1's arguments. + I = 0; + for (Argument &A : F1->args()) { + EXPECT_NE(Args[I], &A); + I++; + } + EXPECT_EQ(2u, I); + EXPECT_FALSE(F1->hasLazyArguments()); + EXPECT_FALSE(F2->hasLazyArguments()); + + // Steal back from F2. F2's arguments should be lazy again. + // + // steal(real); drop (real) + F1->stealArgumentListFrom(*F2); + EXPECT_FALSE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); + I = 0; + for (Argument &A : F1->args()) { + EXPECT_EQ(Args[I], &A); + I++; + } + EXPECT_EQ(2u, I); + + // Steal from F2 a second time. Now both functions should have lazy + // arguments. + // + // steal(empty); drop (real) + F1->stealArgumentListFrom(*F2); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); +} + +} // end namespace diff --git a/gnu/llvm/unittests/IR/IRBuilderTest.cpp b/gnu/llvm/unittests/IR/IRBuilderTest.cpp index bd0eae0399a..58fd71b8a35 100644 --- a/gnu/llvm/unittests/IR/IRBuilderTest.cpp +++ b/gnu/llvm/unittests/IR/IRBuilderTest.cpp @@ -252,7 +252,7 @@ TEST_F(IRBuilderTest, FastMathFlags) { } TEST_F(IRBuilderTest, WrapFlags) { - IRBuilder<true, NoFolder> Builder(BB); + IRBuilder<NoFolder> Builder(BB); // Test instructions. GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true, @@ -418,4 +418,18 @@ TEST_F(IRBuilderTest, DebugLoc) { DIB.finalize(); } + +TEST_F(IRBuilderTest, DIImportedEntity) { + IRBuilder<> Builder(BB); + DIBuilder DIB(*M); + auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/", + "llvm-cobol74", true, "", 0); + DIB.createImportedDeclaration(CU, nullptr, 1); + DIB.createImportedDeclaration(CU, nullptr, 1); + DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, 2); + DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, 2); + DIB.finalize(); + EXPECT_TRUE(verifyModule(*M)); + EXPECT_TRUE(CU->getImportedEntities().size() == 2); +} } diff --git a/gnu/llvm/unittests/IR/InstructionsTest.cpp b/gnu/llvm/unittests/IR/InstructionsTest.cpp index 3ca3ad2b6e8..0dac7c1bcfb 100644 --- a/gnu/llvm/unittests/IR/InstructionsTest.cpp +++ b/gnu/llvm/unittests/IR/InstructionsTest.cpp @@ -27,7 +27,7 @@ namespace llvm { namespace { TEST(InstructionsTest, ReturnInst) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; // test for PR6589 const ReturnInst* r0 = ReturnInst::Create(C); @@ -103,7 +103,7 @@ TEST_F(ModuleWithFunctionTest, InvokeInst) { } TEST(InstructionsTest, BranchInst) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; // Make a BasicBlocks BasicBlock* bb0 = BasicBlock::Create(C); @@ -169,7 +169,7 @@ TEST(InstructionsTest, BranchInst) { } TEST(InstructionsTest, CastInst) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; Type *Int8Ty = Type::getInt8Ty(C); Type *Int16Ty = Type::getInt16Ty(C); @@ -281,14 +281,18 @@ TEST(InstructionsTest, CastInst) { // First form BasicBlock *BB = BasicBlock::Create(C); Constant *NullV2I32Ptr = Constant::getNullValue(V2Int32PtrTy); - CastInst::CreatePointerCast(NullV2I32Ptr, V2Int32Ty, "foo", BB); + auto Inst1 = CastInst::CreatePointerCast(NullV2I32Ptr, V2Int32Ty, "foo", BB); // Second form - CastInst::CreatePointerCast(NullV2I32Ptr, V2Int32Ty); + auto Inst2 = CastInst::CreatePointerCast(NullV2I32Ptr, V2Int32Ty); + + delete Inst2; + Inst1->eraseFromParent(); + delete BB; } TEST(InstructionsTest, VectorGep) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; // Type Definitions Type *I8Ty = IntegerType::get(C, 8); @@ -391,7 +395,7 @@ TEST(InstructionsTest, VectorGep) { } TEST(InstructionsTest, FPMathOperator) { - LLVMContext &Context = getGlobalContext(); + LLVMContext Context; IRBuilder<> Builder(Context); MDBuilder MDHelper(Context); Instruction *I = Builder.CreatePHI(Builder.getDoubleTy(), 0); @@ -406,7 +410,7 @@ TEST(InstructionsTest, FPMathOperator) { TEST(InstructionsTest, isEliminableCastPair) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; Type* Int16Ty = Type::getInt16Ty(C); Type* Int32Ty = Type::getInt32Ty(C); @@ -486,7 +490,7 @@ TEST(InstructionsTest, isEliminableCastPair) { } TEST(InstructionsTest, CloneCall) { - LLVMContext &C(getGlobalContext()); + LLVMContext C; Type *Int32Ty = Type::getInt32Ty(C); Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty}; Type *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false); @@ -518,7 +522,62 @@ TEST(InstructionsTest, CloneCall) { } } -} // end anonymous namespace -} // end namespace llvm +TEST(InstructionsTest, AlterCallBundles) { + LLVMContext C; + Type *Int32Ty = Type::getInt32Ty(C); + Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false); + Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); + Value *Args[] = {ConstantInt::get(Int32Ty, 42)}; + OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); + std::unique_ptr<CallInst> Call( + CallInst::Create(Callee, Args, OldBundle, "result")); + Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); + AttrBuilder AB; + AB.addAttribute(Attribute::Cold); + Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); + + OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); + std::unique_ptr<CallInst> Clone(CallInst::Create(Call.get(), NewBundle)); + EXPECT_EQ(Call->getNumArgOperands(), Clone->getNumArgOperands()); + EXPECT_EQ(Call->getArgOperand(0), Clone->getArgOperand(0)); + EXPECT_EQ(Call->getCallingConv(), Clone->getCallingConv()); + EXPECT_EQ(Call->getTailCallKind(), Clone->getTailCallKind()); + EXPECT_TRUE(Clone->hasFnAttr(Attribute::AttrKind::Cold)); + EXPECT_EQ(Call->getDebugLoc(), Clone->getDebugLoc()); + EXPECT_EQ(Clone->getNumOperandBundles(), 1U); + EXPECT_TRUE(Clone->getOperandBundle("after").hasValue()); +} +TEST(InstructionsTest, AlterInvokeBundles) { + LLVMContext C; + Type *Int32Ty = Type::getInt32Ty(C); + Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false); + Value *Callee = Constant::getNullValue(FnTy->getPointerTo()); + Value *Args[] = {ConstantInt::get(Int32Ty, 42)}; + std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C)); + std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C)); + OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty)); + std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create( + Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result")); + AttrBuilder AB; + AB.addAttribute(Attribute::Cold); + Invoke->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); + + OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); + std::unique_ptr<InvokeInst> Clone( + InvokeInst::Create(Invoke.get(), NewBundle)); + EXPECT_EQ(Invoke->getNormalDest(), Clone->getNormalDest()); + EXPECT_EQ(Invoke->getUnwindDest(), Clone->getUnwindDest()); + EXPECT_EQ(Invoke->getNumArgOperands(), Clone->getNumArgOperands()); + EXPECT_EQ(Invoke->getArgOperand(0), Clone->getArgOperand(0)); + EXPECT_EQ(Invoke->getCallingConv(), Clone->getCallingConv()); + EXPECT_TRUE(Clone->hasFnAttr(Attribute::AttrKind::Cold)); + EXPECT_EQ(Invoke->getDebugLoc(), Clone->getDebugLoc()); + EXPECT_EQ(Clone->getNumOperandBundles(), 1U); + EXPECT_TRUE(Clone->getOperandBundle("after").hasValue()); +} +} // end anonymous namespace +} // end namespace llvm diff --git a/gnu/llvm/unittests/IR/IntrinsicsTest.cpp b/gnu/llvm/unittests/IR/IntrinsicsTest.cpp new file mode 100644 index 00000000000..0d12126b1fc --- /dev/null +++ b/gnu/llvm/unittests/IR/IntrinsicsTest.cpp @@ -0,0 +1,40 @@ +//===- llvm/unittest/IR/IntrinsicsTest.cpp - ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/IntrinsicInst.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +static const char *const NameTable1[] = { + "llvm.foo", + "llvm.foo.a", + "llvm.foo.b", + "llvm.foo.b.a", + "llvm.foo.c", +}; + +TEST(IntrinNameLookup, Basic) { + int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo"); + EXPECT_EQ(0, I); + I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64"); + EXPECT_EQ(0, I); + I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b"); + EXPECT_EQ(2, I); + I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a"); + EXPECT_EQ(3, I); + I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c"); + EXPECT_EQ(4, I); + I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64"); + EXPECT_EQ(4, I); +} + +} // end namespace diff --git a/gnu/llvm/unittests/IR/LegacyPassManagerTest.cpp b/gnu/llvm/unittests/IR/LegacyPassManagerTest.cpp index 1f88283dc0c..9dceb976c93 100644 --- a/gnu/llvm/unittests/IR/LegacyPassManagerTest.cpp +++ b/gnu/llvm/unittests/IR/LegacyPassManagerTest.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/LegacyPassManager.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" @@ -288,7 +287,8 @@ namespace llvm { char OnTheFlyTest::ID=0; TEST(PassManager, RunOnce) { - Module M("test-once", getGlobalContext()); + LLVMContext Context; + Module M("test-once", Context); struct ModuleNDNM *mNDNM = new ModuleNDNM(); struct ModuleDNM *mDNM = new ModuleDNM(); struct ModuleNDM *mNDM = new ModuleNDM(); @@ -311,7 +311,8 @@ namespace llvm { } TEST(PassManager, ReRun) { - Module M("test-rerun", getGlobalContext()); + LLVMContext Context; + Module M("test-rerun", Context); struct ModuleNDNM *mNDNM = new ModuleNDNM(); struct ModuleDNM *mDNM = new ModuleDNM(); struct ModuleNDM *mNDM = new ModuleNDM(); @@ -334,11 +335,12 @@ namespace llvm { EXPECT_EQ(1, mDNM->run); } - Module* makeLLVMModule(); + Module *makeLLVMModule(LLVMContext &Context); template<typename T> void MemoryTestHelper(int run) { - std::unique_ptr<Module> M(makeLLVMModule()); + LLVMContext Context; + std::unique_ptr<Module> M(makeLLVMModule(Context)); T *P = new T(); legacy::PassManager Passes; Passes.add(P); @@ -348,7 +350,8 @@ namespace llvm { template<typename T> void MemoryTestHelper(int run, int N) { - Module *M = makeLLVMModule(); + LLVMContext Context; + Module *M = makeLLVMModule(Context); T *P = new T(); legacy::PassManager Passes; Passes.add(P); @@ -383,7 +386,8 @@ namespace llvm { } TEST(PassManager, MemoryOnTheFly) { - Module *M = makeLLVMModule(); + LLVMContext Context; + Module *M = makeLLVMModule(Context); { SCOPED_TRACE("Running OnTheFlyTest"); struct OnTheFlyTest *O = new OnTheFlyTest(); @@ -396,9 +400,9 @@ namespace llvm { delete M; } - Module* makeLLVMModule() { + Module *makeLLVMModule(LLVMContext &Context) { // Module Construction - Module* mod = new Module("test-mem", getGlobalContext()); + Module *mod = new Module("test-mem", Context); mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" "a:0:64-s:64:64-f80:128:128"); @@ -406,18 +410,17 @@ namespace llvm { // Type Definitions std::vector<Type*>FuncTy_0_args; - FunctionType* FuncTy_0 = FunctionType::get( - /*Result=*/IntegerType::get(getGlobalContext(), 32), - /*Params=*/FuncTy_0_args, - /*isVarArg=*/false); + FunctionType *FuncTy_0 = FunctionType::get( + /*Result=*/IntegerType::get(Context, 32), + /*Params=*/FuncTy_0_args, + /*isVarArg=*/false); std::vector<Type*>FuncTy_2_args; - FuncTy_2_args.push_back(IntegerType::get(getGlobalContext(), 1)); - FunctionType* FuncTy_2 = FunctionType::get( - /*Result=*/Type::getVoidTy(getGlobalContext()), - /*Params=*/FuncTy_2_args, - /*isVarArg=*/false); - + FuncTy_2_args.push_back(IntegerType::get(Context, 1)); + FunctionType *FuncTy_2 = FunctionType::get( + /*Result=*/Type::getVoidTy(Context), + /*Params=*/FuncTy_2_args, + /*isVarArg=*/false); // Function Declarations @@ -465,7 +468,8 @@ namespace llvm { // Function: test1 (func_test1) { - BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,nullptr); + BasicBlock *label_entry = + BasicBlock::Create(Context, "entry", func_test1, nullptr); // Block entry (label_entry) CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry); @@ -473,14 +477,14 @@ namespace llvm { int32_3->setTailCall(false);AttributeSet int32_3_PAL; int32_3->setAttributes(int32_3_PAL); - ReturnInst::Create(getGlobalContext(), int32_3, label_entry); - + ReturnInst::Create(Context, int32_3, label_entry); } // Function: test2 (func_test2) { - BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,nullptr); + BasicBlock *label_entry_5 = + BasicBlock::Create(Context, "entry", func_test2, nullptr); // Block entry (label_entry_5) CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5); @@ -488,14 +492,14 @@ namespace llvm { int32_6->setTailCall(false);AttributeSet int32_6_PAL; int32_6->setAttributes(int32_6_PAL); - ReturnInst::Create(getGlobalContext(), int32_6, label_entry_5); - + ReturnInst::Create(Context, int32_6, label_entry_5); } // Function: test3 (func_test3) { - BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,nullptr); + BasicBlock *label_entry_8 = + BasicBlock::Create(Context, "entry", func_test3, nullptr); // Block entry (label_entry_8) CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8); @@ -503,8 +507,7 @@ namespace llvm { int32_9->setTailCall(false);AttributeSet int32_9_PAL; int32_9->setAttributes(int32_9_PAL); - ReturnInst::Create(getGlobalContext(), int32_9, label_entry_8); - + ReturnInst::Create(Context, int32_9, label_entry_8); } // Function: test4 (func_test4) @@ -513,10 +516,14 @@ namespace llvm { Value *int1_f = &*args++; int1_f->setName("f"); - BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,nullptr); - BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,nullptr); - BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,nullptr); - BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,nullptr); + BasicBlock *label_entry_11 = + BasicBlock::Create(Context, "entry", func_test4, nullptr); + BasicBlock *label_bb = + BasicBlock::Create(Context, "bb", func_test4, nullptr); + BasicBlock *label_bb1 = + BasicBlock::Create(Context, "bb1", func_test4, nullptr); + BasicBlock *label_return = + BasicBlock::Create(Context, "return", func_test4, nullptr); // Block entry (label_entry_11) BranchInst::Create(label_bb, label_entry_11); @@ -528,8 +535,7 @@ namespace llvm { BranchInst::Create(label_bb1, label_return, int1_f, label_bb1); // Block return (label_return) - ReturnInst::Create(getGlobalContext(), label_return); - + ReturnInst::Create(Context, label_return); } return mod; } diff --git a/gnu/llvm/unittests/IR/MetadataTest.cpp b/gnu/llvm/unittests/IR/MetadataTest.cpp index a745b235a38..15b03b3d572 100644 --- a/gnu/llvm/unittests/IR/MetadataTest.cpp +++ b/gnu/llvm/unittests/IR/MetadataTest.cpp @@ -80,26 +80,29 @@ protected: MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); } DISubroutineType *getSubroutineType() { - return DISubroutineType::getDistinct(Context, 0, getNode(nullptr)); + return DISubroutineType::getDistinct(Context, 0, 0, getNode(nullptr)); } DISubprogram *getSubprogram() { return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, - nullptr, false, false, 0, nullptr, 0, 0, 0, - 0); + nullptr, false, false, 0, nullptr, + 0, 0, 0, 0, false, nullptr); } - DIScopeRef getSubprogramRef() { return getSubprogram()->getRef(); } DIFile *getFile() { return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); } - DITypeRef getBasicType(StringRef Name) { - return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name) - ->getRef(); + DICompileUnit *getUnit() { + return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false, + "-g", 2, "", DICompileUnit::FullDebug, + getTuple(), getTuple(), getTuple(), + getTuple(), getTuple(), 0); } - DITypeRef getDerivedType() { + DIType *getBasicType(StringRef Name) { + return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); + } + DIType *getDerivedType() { return DIDerivedType::getDistinct(Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, - getBasicType("basictype"), 1, 2, 0, 0) - ->getRef(); + getBasicType("basictype"), 1, 2, 0, 0); } Constant *getConstant() { return ConstantInt::get(Type::getInt32Ty(Context), Counter++); @@ -107,11 +110,10 @@ protected: ConstantAsMetadata *getConstantAsMetadata() { return ConstantAsMetadata::get(getConstant()); } - DITypeRef getCompositeType() { + DIType *getCompositeType() { return DICompositeType::getDistinct( - Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, - nullptr, 32, 32, 0, 0, nullptr, 0, nullptr, nullptr, "") - ->getRef(); + Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr, + 32, 32, 0, 0, nullptr, 0, nullptr, nullptr, ""); } Function *getFunction(StringRef Name) { return cast<Function>(M.getOrInsertFunction( @@ -174,8 +176,8 @@ TEST_F(MDNodeTest, Simple) { MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); - ConstantAsMetadata *CI = ConstantAsMetadata::get( - ConstantInt::get(getGlobalContext(), APInt(8, 0))); + ConstantAsMetadata *CI = + ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); std::vector<Metadata *> V; V.push_back(s1); @@ -206,8 +208,8 @@ TEST_F(MDNodeTest, Simple) { } TEST_F(MDNodeTest, Delete) { - Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1); - Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext())); + Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1); + Instruction *I = new BitCastInst(C, Type::getInt32Ty(Context)); Metadata *const V = LocalAsMetadata::get(I); MDNode *n = MDNode::get(Context, V); @@ -447,6 +449,40 @@ TEST_F(MDNodeTest, DistinctOnUniquingCollision) { EXPECT_FALSE(Wrapped1->isDistinct()); } +TEST_F(MDNodeTest, UniquedOnDeletedOperand) { + // temp !{} + TempMDTuple T = MDTuple::getTemporary(Context, None); + + // !{temp !{}} + Metadata *Ops[] = {T.get()}; + MDTuple *N = MDTuple::get(Context, Ops); + + // !{temp !{}} => !{null} + T.reset(); + ASSERT_TRUE(N->isUniqued()); + Metadata *NullOps[] = {nullptr}; + ASSERT_EQ(N, MDTuple::get(Context, NullOps)); +} + +TEST_F(MDNodeTest, DistinctOnDeletedValueOperand) { + // i1* @GV + Type *Ty = Type::getInt1PtrTy(Context); + std::unique_ptr<GlobalVariable> GV( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); + + // !{i1* @GV} + Metadata *Ops[] = {Op}; + MDTuple *N = MDTuple::get(Context, Ops); + + // !{i1* @GV} => !{null} + GV.reset(); + ASSERT_TRUE(N->isDistinct()); + ASSERT_EQ(nullptr, N->getOperand(0)); + Metadata *NullOps[] = {nullptr}; + ASSERT_NE(N, MDTuple::get(Context, NullOps)); +} + TEST_F(MDNodeTest, getDistinct) { // !{} MDNode *Empty = MDNode::get(Context, None); @@ -494,20 +530,6 @@ TEST_F(MDNodeTest, isTemporary) { EXPECT_TRUE(T->isTemporary()); } -#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) - -TEST_F(MDNodeTest, deathOnNoReplaceTemporaryRAUW) { - auto Temp = MDNode::getTemporary(Context, None); - Temp->setCanReplace(false); - EXPECT_DEATH(Temp->replaceAllUsesWith(nullptr), - "Attempted to replace Metadata marked for no replacement"); - Temp->setCanReplace(true); - // Remove the references to Temp; required for teardown. - Temp->replaceAllUsesWith(nullptr); -} - -#endif - TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) { // temporary !{} auto Temp = MDTuple::getTemporary(Context, None); @@ -681,7 +703,7 @@ TEST_F(MDNodeTest, replaceWithUniquedResolvingOperand) { EXPECT_TRUE(N->isResolved()); } -TEST_F(MDNodeTest, replaceWithUniquedChangingOperand) { +TEST_F(MDNodeTest, replaceWithUniquedDeletedOperand) { // i1* @GV Type *Ty = Type::getInt1PtrTy(Context); std::unique_ptr<GlobalVariable> GV( @@ -698,8 +720,33 @@ TEST_F(MDNodeTest, replaceWithUniquedChangingOperand) { // !{i1* @GV} => !{null} GV.reset(); - ASSERT_TRUE(N->isUniqued()); + ASSERT_TRUE(N->isDistinct()); + ASSERT_EQ(nullptr, N->getOperand(0)); Metadata *NullOps[] = {nullptr}; + ASSERT_NE(N, MDTuple::get(Context, NullOps)); +} + +TEST_F(MDNodeTest, replaceWithUniquedChangedOperand) { + // i1* @GV + Type *Ty = Type::getInt1PtrTy(Context); + std::unique_ptr<GlobalVariable> GV( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); + + // temp !{i1* @GV} + Metadata *Ops[] = {Op}; + MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); + + // temp !{i1* @GV} => !{i1* @GV} + ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); + ASSERT_TRUE(N->isUniqued()); + + // !{i1* @GV} => !{i1* @GV2} + std::unique_ptr<GlobalVariable> GV2( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + GV->replaceAllUsesWith(GV2.get()); + ASSERT_TRUE(N->isUniqued()); + Metadata *NullOps[] = {ConstantAsMetadata::get(GV2.get())}; ASSERT_EQ(N, MDTuple::get(Context, NullOps)); } @@ -981,14 +1028,14 @@ TEST_F(DITypeTest, setFlags) { Metadata *TypesOps[] = {nullptr}; Metadata *Types = MDTuple::get(Context, TypesOps); - DIType *D = DISubroutineType::getDistinct(Context, 0u, Types); + DIType *D = DISubroutineType::getDistinct(Context, 0u, 0, Types); EXPECT_EQ(0u, D->getFlags()); D->setFlags(DINode::FlagRValueReference); EXPECT_EQ(DINode::FlagRValueReference, D->getFlags()); D->setFlags(0u); EXPECT_EQ(0u, D->getFlags()); - TempDIType T = DISubroutineType::getTemporary(Context, 0u, Types); + TempDIType T = DISubroutineType::getTemporary(Context, 0u, 0, Types); EXPECT_EQ(0u, T->getFlags()); T->setFlags(DINode::FlagRValueReference); EXPECT_EQ(DINode::FlagRValueReference, T->getFlags()); @@ -1000,8 +1047,8 @@ typedef MetadataTest DIDerivedTypeTest; TEST_F(DIDerivedTypeTest, get) { DIFile *File = getFile(); - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getBasicType("basic"); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", @@ -1034,7 +1081,7 @@ TEST_F(DIDerivedTypeTest, get) { "something", File, 2, Scope, BaseType, 2, 3, 4, 5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, - "something", File, 1, getSubprogramRef(), + "something", File, 1, getSubprogram(), BaseType, 2, 3, 4, 5, ExtraData)); EXPECT_NE(N, DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, @@ -1061,8 +1108,8 @@ TEST_F(DIDerivedTypeTest, get) { TEST_F(DIDerivedTypeTest, getWithLargeValues) { DIFile *File = getFile(); - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getBasicType("basic"); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", @@ -1080,15 +1127,15 @@ TEST_F(DICompositeTypeTest, get) { StringRef Name = "some name"; DIFile *File = getFile(); unsigned Line = 1; - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getCompositeType(); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getCompositeType(); uint64_t SizeInBits = 2; uint64_t AlignInBits = 3; uint64_t OffsetInBits = 4; unsigned Flags = 5; MDTuple *Elements = getTuple(); unsigned RuntimeLang = 6; - DITypeRef VTableHolder = getCompositeType(); + DIType *VTableHolder = getCompositeType(); MDTuple *TemplateParams = getTuple(); StringRef Identifier = "some id"; @@ -1134,7 +1181,7 @@ TEST_F(DICompositeTypeTest, get) { OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( - Context, Tag, Name, File, Line, getSubprogramRef(), BaseType, + Context, Tag, Name, File, Line, getSubprogram(), BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( @@ -1199,15 +1246,15 @@ TEST_F(DICompositeTypeTest, getWithLargeValues) { StringRef Name = "some name"; DIFile *File = getFile(); unsigned Line = 1; - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getCompositeType(); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getCompositeType(); uint64_t SizeInBits = UINT64_MAX; uint64_t AlignInBits = UINT64_MAX - 1; uint64_t OffsetInBits = UINT64_MAX - 2; unsigned Flags = 5; MDTuple *Elements = getTuple(); unsigned RuntimeLang = 6; - DITypeRef VTableHolder = getCompositeType(); + DIType *VTableHolder = getCompositeType(); MDTuple *TemplateParams = getTuple(); StringRef Identifier = "some id"; @@ -1225,8 +1272,8 @@ TEST_F(DICompositeTypeTest, replaceOperands) { StringRef Name = "some name"; DIFile *File = getFile(); unsigned Line = 1; - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getCompositeType(); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getCompositeType(); uint64_t SizeInBits = 2; uint64_t AlignInBits = 3; uint64_t OffsetInBits = 4; @@ -1245,7 +1292,7 @@ TEST_F(DICompositeTypeTest, replaceOperands) { N->replaceElements(nullptr); EXPECT_EQ(nullptr, N->getElements().get()); - DITypeRef VTableHolder = getCompositeType(); + DIType *VTableHolder = getCompositeType(); EXPECT_EQ(nullptr, N->getVTableHolder()); N->replaceVTableHolder(VTableHolder); EXPECT_EQ(VTableHolder, N->getVTableHolder()); @@ -1266,14 +1313,29 @@ TEST_F(DISubroutineTypeTest, get) { unsigned Flags = 1; MDTuple *TypeArray = getTuple(); - auto *N = DISubroutineType::get(Context, Flags, TypeArray); + auto *N = DISubroutineType::get(Context, Flags, 0, TypeArray); EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag()); EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(TypeArray, N->getTypeArray().get()); - EXPECT_EQ(N, DISubroutineType::get(Context, Flags, TypeArray)); - - EXPECT_NE(N, DISubroutineType::get(Context, Flags + 1, TypeArray)); - EXPECT_NE(N, DISubroutineType::get(Context, Flags, getTuple())); + EXPECT_EQ(N, DISubroutineType::get(Context, Flags, 0, TypeArray)); + + EXPECT_NE(N, DISubroutineType::get(Context, Flags + 1, 0, TypeArray)); + EXPECT_NE(N, DISubroutineType::get(Context, Flags, 0, getTuple())); + + // Test the hashing of calling conventions. + auto *Fast = DISubroutineType::get( + Context, Flags, dwarf::DW_CC_BORLAND_msfastcall, TypeArray); + auto *Std = DISubroutineType::get(Context, Flags, + dwarf::DW_CC_BORLAND_stdcall, TypeArray); + EXPECT_EQ(Fast, + DISubroutineType::get(Context, Flags, + dwarf::DW_CC_BORLAND_msfastcall, TypeArray)); + EXPECT_EQ(Std, DISubroutineType::get( + Context, Flags, dwarf::DW_CC_BORLAND_stdcall, TypeArray)); + + EXPECT_NE(N, Fast); + EXPECT_NE(N, Std); + EXPECT_NE(Fast, Std); TempDISubroutineType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1319,10 +1381,9 @@ TEST_F(DICompileUnitTest, get) { StringRef Flags = "flag after flag"; unsigned RuntimeVersion = 2; StringRef SplitDebugFilename = "another/file"; - unsigned EmissionKind = 3; + auto EmissionKind = DICompileUnit::FullDebug; MDTuple *EnumTypes = getTuple(); MDTuple *RetainedTypes = getTuple(); - MDTuple *Subprograms = getTuple(); MDTuple *GlobalVariables = getTuple(); MDTuple *ImportedEntities = getTuple(); uint64_t DWOId = 0x10000000c0ffee; @@ -1330,7 +1391,7 @@ TEST_F(DICompileUnitTest, get) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, Macros, + RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); @@ -1344,7 +1405,6 @@ TEST_F(DICompileUnitTest, get) { EXPECT_EQ(EmissionKind, N->getEmissionKind()); EXPECT_EQ(EnumTypes, N->getEnumTypes().get()); EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get()); - EXPECT_EQ(Subprograms, N->getSubprograms().get()); EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); EXPECT_EQ(ImportedEntities, N->getImportedEntities().get()); EXPECT_EQ(Macros, N->getMacros().get()); @@ -1362,7 +1422,6 @@ TEST_F(DICompileUnitTest, get) { EXPECT_EQ(EmissionKind, Temp->getEmissionKind()); EXPECT_EQ(EnumTypes, Temp->getEnumTypes().get()); EXPECT_EQ(RetainedTypes, Temp->getRetainedTypes().get()); - EXPECT_EQ(Subprograms, Temp->getSubprograms().get()); EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get()); EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get()); EXPECT_EQ(Macros, Temp->getMacros().get()); @@ -1382,7 +1441,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { StringRef Flags = "flag after flag"; unsigned RuntimeVersion = 2; StringRef SplitDebugFilename = "another/file"; - unsigned EmissionKind = 3; + auto EmissionKind = DICompileUnit::FullDebug; MDTuple *EnumTypes = MDTuple::getDistinct(Context, None); MDTuple *RetainedTypes = MDTuple::getDistinct(Context, None); MDTuple *ImportedEntities = MDTuple::getDistinct(Context, None); @@ -1390,14 +1449,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, nullptr, ImportedEntities, nullptr, DWOId); - - auto *Subprograms = MDTuple::getDistinct(Context, None); - EXPECT_EQ(nullptr, N->getSubprograms().get()); - N->replaceSubprograms(Subprograms); - EXPECT_EQ(Subprograms, N->getSubprograms().get()); - N->replaceSubprograms(nullptr); - EXPECT_EQ(nullptr, N->getSubprograms().get()); + RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get()); @@ -1417,7 +1469,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { typedef MetadataTest DISubprogramTest; TEST_F(DISubprogramTest, get) { - DIScopeRef Scope = getCompositeType(); + DIScope *Scope = getCompositeType(); StringRef Name = "name"; StringRef LinkageName = "linkage"; DIFile *File = getFile(); @@ -1426,19 +1478,23 @@ TEST_F(DISubprogramTest, get) { bool IsLocalToUnit = false; bool IsDefinition = true; unsigned ScopeLine = 3; - DITypeRef ContainingType = getCompositeType(); - unsigned Virtuality = 4; + DIType *ContainingType = getCompositeType(); + unsigned Virtuality = 2; unsigned VirtualIndex = 5; + int ThisAdjustment = -3; unsigned Flags = 6; + unsigned NotFlags = (~Flags) & ((1 << 27) - 1); bool IsOptimized = false; MDTuple *TemplateParams = getTuple(); DISubprogram *Declaration = getSubprogram(); MDTuple *Variables = getTuple(); + DICompileUnit *Unit = getUnit(); - auto *N = DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, - IsOptimized, TemplateParams, Declaration, Variables); + auto *N = DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables); EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -1453,102 +1509,110 @@ TEST_F(DISubprogramTest, get) { EXPECT_EQ(ContainingType, N->getContainingType()); EXPECT_EQ(Virtuality, N->getVirtuality()); EXPECT_EQ(VirtualIndex, N->getVirtualIndex()); + EXPECT_EQ(ThisAdjustment, N->getThisAdjustment()); EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(IsOptimized, N->isOptimized()); + EXPECT_EQ(Unit, N->getUnit()); EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); EXPECT_EQ(Declaration, N->getDeclaration()); EXPECT_EQ(Variables, N->getVariables().get()); EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); - - EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, - File, Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, - Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, + ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); + + EXPECT_NE(N, DISubprogram::get( + Context, getCompositeType(), Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, "other", LinkageName, File, Line, Type, + IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), - Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, - Line + 1, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - getSubroutineType(), IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, Flags, IsOptimized, + ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, Name, LinkageName, getFile(), Line, Type, + IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, Name, LinkageName, File, Line + 1, Type, + IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, + DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + getSubroutineType(), IsLocalToUnit, IsDefinition, + ScopeLine, ContainingType, Virtuality, + VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, - ScopeLine + 1, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, + ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, Name, LinkageName, File, Line, Type, + IsLocalToUnit, IsDefinition, ScopeLine + 1, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, getCompositeType(), Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality + 1, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex + 1, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - ~Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, NotFlags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, !IsOptimized, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, - DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, Flags, - IsOptimized, getTuple(), Declaration, Variables)); + ThisAdjustment, Flags, !IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - getSubprogram(), Variables)); + ThisAdjustment, Flags, IsOptimized, nullptr, + TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsOptimized, Unit, + getTuple(), Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, getTuple())); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, getSubprogram(), Variables)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, getTuple())); TempDISubprogram Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1697,7 +1761,7 @@ typedef MetadataTest DITemplateTypeParameterTest; TEST_F(DITemplateTypeParameterTest, get) { StringRef Name = "template"; - DITypeRef Type = getBasicType("basic"); + DIType *Type = getBasicType("basic"); auto *N = DITemplateTypeParameter::get(Context, Name, Type); @@ -1719,7 +1783,7 @@ typedef MetadataTest DITemplateValueParameterTest; TEST_F(DITemplateValueParameterTest, get) { unsigned Tag = dwarf::DW_TAG_template_value_parameter; StringRef Name = "template"; - DITypeRef Type = getBasicType("basic"); + DIType *Type = getBasicType("basic"); Metadata *Value = getConstantAsMetadata(); auto *N = DITemplateValueParameter::get(Context, Tag, Name, Type, Value); @@ -1751,7 +1815,7 @@ TEST_F(DIGlobalVariableTest, get) { StringRef LinkageName = "linkage"; DIFile *File = getFile(); unsigned Line = 5; - DITypeRef Type = getDerivedType(); + DIType *Type = getDerivedType(); bool IsLocalToUnit = false; bool IsDefinition = true; Constant *Variable = getConstant(); @@ -1824,9 +1888,10 @@ TEST_F(DILocalVariableTest, get) { StringRef Name = "name"; DIFile *File = getFile(); unsigned Line = 5; - DITypeRef Type = getDerivedType(); + DIType *Type = getDerivedType(); unsigned Arg = 6; unsigned Flags = 7; + unsigned NotFlags = (~Flags) & ((1 << 16) - 1); auto *N = DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, Flags); @@ -1857,7 +1922,7 @@ TEST_F(DILocalVariableTest, get) { EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg + 1, Flags)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, - ~Flags)); + NotFlags)); TempDILocalVariable Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1943,7 +2008,7 @@ TEST_F(DIObjCPropertyTest, get) { StringRef GetterName = "getter"; StringRef SetterName = "setter"; unsigned Attributes = 7; - DITypeRef Type = getBasicType("basic"); + DIType *Type = getBasicType("basic"); auto *N = DIObjCProperty::get(Context, Name, File, Line, GetterName, SetterName, Attributes, Type); @@ -1984,7 +2049,7 @@ typedef MetadataTest DIImportedEntityTest; TEST_F(DIImportedEntityTest, get) { unsigned Tag = dwarf::DW_TAG_imported_module; DIScope *Scope = getSubprogram(); - DINodeRef Entity = getCompositeType(); + DINode *Entity = getCompositeType(); unsigned Line = 5; StringRef Name = "name"; @@ -2073,10 +2138,27 @@ TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) { EXPECT_TRUE(MD->getValue() == GV1.get()); } +TEST_F(ValueAsMetadataTest, TempTempReplacement) { + // Create a constant. + ConstantAsMetadata *CI = + ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); + + auto Temp1 = MDTuple::getTemporary(Context, None); + auto Temp2 = MDTuple::getTemporary(Context, {CI}); + auto *N = MDTuple::get(Context, {Temp1.get()}); + + // Test replacing a temporary node with another temporary node. + Temp1->replaceAllUsesWith(Temp2.get()); + EXPECT_EQ(N->getOperand(0), Temp2.get()); + + // Clean up Temp2 for teardown. + Temp2->replaceAllUsesWith(nullptr); +} + TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) { // Create a constant. - ConstantAsMetadata *CI = ConstantAsMetadata::get( - ConstantInt::get(getGlobalContext(), APInt(8, 0))); + ConstantAsMetadata *CI = + ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); // Create a temporary to prevent nodes from resolving. auto Temp = MDTuple::getTemporary(Context, None); @@ -2238,44 +2320,23 @@ TEST_F(FunctionAttachmentTest, getAll) { EXPECT_EQ(T2, MDs[3].second); } -TEST_F(FunctionAttachmentTest, dropUnknownMetadata) { - Function *F = getFunction("foo"); - - MDTuple *T1 = getTuple(); - MDTuple *T2 = getTuple(); - MDTuple *P = getTuple(); - DISubprogram *SP = getSubprogram(); - - F->setMetadata("other1", T1); - F->setMetadata(LLVMContext::MD_dbg, SP); - F->setMetadata("other2", T2); - F->setMetadata(LLVMContext::MD_prof, P); - - unsigned Known[] = {Context.getMDKindID("other2"), LLVMContext::MD_prof}; - F->dropUnknownMetadata(Known); - - EXPECT_EQ(T2, F->getMetadata("other2")); - EXPECT_EQ(P, F->getMetadata(LLVMContext::MD_prof)); - EXPECT_EQ(nullptr, F->getMetadata("other1")); - EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg)); - - F->setMetadata("other2", nullptr); - F->setMetadata(LLVMContext::MD_prof, nullptr); - EXPECT_FALSE(F->hasMetadata()); -} - TEST_F(FunctionAttachmentTest, Verifier) { Function *F = getFunction("foo"); F->setMetadata("attach", getTuple()); + F->setIsMaterializable(true); - // Confirm this has no body. - ASSERT_TRUE(F->empty()); + // Confirm this is materializable. + ASSERT_TRUE(F->isMaterializable()); - // Functions without a body cannot have metadata attachments (they also can't - // be verified directly, so check that the module fails to verify). - EXPECT_TRUE(verifyModule(*F->getParent())); + // Materializable functions cannot have metadata attachments. + EXPECT_TRUE(verifyFunction(*F)); - // Functions with a body can. + // Function declarations can. + F->setIsMaterializable(false); + EXPECT_FALSE(verifyModule(*F->getParent())); + EXPECT_FALSE(verifyFunction(*F)); + + // So can definitions. (void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F)); EXPECT_FALSE(verifyModule(*F->getParent())); EXPECT_FALSE(verifyFunction(*F)); @@ -2301,4 +2362,81 @@ TEST_F(FunctionAttachmentTest, SubprogramAttachment) { EXPECT_EQ(SP, F->getMetadata(LLVMContext::MD_dbg)); } +typedef MetadataTest DistinctMDOperandPlaceholderTest; +TEST_F(DistinctMDOperandPlaceholderTest, getID) { + EXPECT_EQ(7u, DistinctMDOperandPlaceholder(7).getID()); +} + +TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWith) { + // Set up some placeholders. + DistinctMDOperandPlaceholder PH0(7); + DistinctMDOperandPlaceholder PH1(3); + DistinctMDOperandPlaceholder PH2(0); + Metadata *Ops[] = {&PH0, &PH1, &PH2}; + auto *D = MDTuple::getDistinct(Context, Ops); + ASSERT_EQ(&PH0, D->getOperand(0)); + ASSERT_EQ(&PH1, D->getOperand(1)); + ASSERT_EQ(&PH2, D->getOperand(2)); + + // Replace them. + auto *N0 = MDTuple::get(Context, None); + auto *N1 = MDTuple::get(Context, N0); + PH0.replaceUseWith(N0); + PH1.replaceUseWith(N1); + PH2.replaceUseWith(nullptr); + EXPECT_EQ(N0, D->getOperand(0)); + EXPECT_EQ(N1, D->getOperand(1)); + EXPECT_EQ(nullptr, D->getOperand(2)); +} + +TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWithNoUser) { + // There is no user, but we can still call replace. + DistinctMDOperandPlaceholder(7).replaceUseWith(MDTuple::get(Context, None)); } + +#ifndef NDEBUG +#ifdef GTEST_HAS_DEATH_TEST +TEST_F(DistinctMDOperandPlaceholderTest, MetadataAsValue) { + // This shouldn't crash. + DistinctMDOperandPlaceholder PH(7); + EXPECT_DEATH(MetadataAsValue::get(Context, &PH), + "Unexpected callback to owner"); +} + +TEST_F(DistinctMDOperandPlaceholderTest, UniquedMDNode) { + // This shouldn't crash. + DistinctMDOperandPlaceholder PH(7); + EXPECT_DEATH(MDTuple::get(Context, &PH), "Unexpected callback to owner"); +} + +TEST_F(DistinctMDOperandPlaceholderTest, SecondDistinctMDNode) { + // This shouldn't crash. + DistinctMDOperandPlaceholder PH(7); + MDTuple::getDistinct(Context, &PH); + EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), + "Placeholders can only be used once"); +} + +TEST_F(DistinctMDOperandPlaceholderTest, TrackingMDRefAndDistinctMDNode) { + // TrackingMDRef doesn't install an owner callback, so it can't be detected + // as an invalid use. However, using a placeholder in a TrackingMDRef *and* + // a distinct node isn't possible and we should assert. + // + // (There's no positive test for using TrackingMDRef because it's not a + // useful thing to do.) + { + DistinctMDOperandPlaceholder PH(7); + MDTuple::getDistinct(Context, &PH); + EXPECT_DEATH(TrackingMDRef Ref(&PH), "Placeholders can only be used once"); + } + { + DistinctMDOperandPlaceholder PH(7); + TrackingMDRef Ref(&PH); + EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), + "Placeholders can only be used once"); + } +} +#endif +#endif + +} // end namespace diff --git a/gnu/llvm/unittests/IR/PassManagerTest.cpp b/gnu/llvm/unittests/IR/PassManagerTest.cpp index 41af0b0bd25..c2ac863260a 100644 --- a/gnu/llvm/unittests/IR/PassManagerTest.cpp +++ b/gnu/llvm/unittests/IR/PassManagerTest.cpp @@ -19,23 +19,17 @@ using namespace llvm; namespace { -class TestFunctionAnalysis { +class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> { public: struct Result { Result(int Count) : InstructionCount(Count) {} int InstructionCount; }; - /// \brief Returns an opaque, unique ID for this pass type. - static void *ID() { return (void *)&PassID; } - - /// \brief Returns the name of the analysis. - static StringRef name() { return "TestFunctionAnalysis"; } - TestFunctionAnalysis(int &Runs) : Runs(Runs) {} /// \brief Run the analysis pass over the function and return a result. - Result run(Function &F, FunctionAnalysisManager *AM) { + Result run(Function &F, FunctionAnalysisManager &AM) { ++Runs; int Count = 0; for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) @@ -46,7 +40,7 @@ public: } private: - /// \brief Private static data to provide unique ID. + friend AnalysisInfoMixin<TestFunctionAnalysis>; static char PassID; int &Runs; @@ -54,20 +48,16 @@ private: char TestFunctionAnalysis::PassID; -class TestModuleAnalysis { +class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> { public: struct Result { Result(int Count) : FunctionCount(Count) {} int FunctionCount; }; - static void *ID() { return (void *)&PassID; } - - static StringRef name() { return "TestModuleAnalysis"; } - TestModuleAnalysis(int &Runs) : Runs(Runs) {} - Result run(Module &M, ModuleAnalysisManager *AM) { + Result run(Module &M, ModuleAnalysisManager &AM) { ++Runs; int Count = 0; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) @@ -76,6 +66,7 @@ public: } private: + friend AnalysisInfoMixin<TestModuleAnalysis>; static char PassID; int &Runs; @@ -83,40 +74,37 @@ private: char TestModuleAnalysis::PassID; -struct TestModulePass { +struct TestModulePass : PassInfoMixin<TestModulePass> { TestModulePass(int &RunCount) : RunCount(RunCount) {} - PreservedAnalyses run(Module &M) { + PreservedAnalyses run(Module &M, ModuleAnalysisManager &) { ++RunCount; return PreservedAnalyses::none(); } - static StringRef name() { return "TestModulePass"; } - int &RunCount; }; -struct TestPreservingModulePass { - PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); } - - static StringRef name() { return "TestPreservingModulePass"; } +struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> { + PreservedAnalyses run(Module &M, ModuleAnalysisManager &) { + return PreservedAnalyses::all(); + } }; -struct TestMinPreservingModulePass { - PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) { +struct TestMinPreservingModulePass + : PassInfoMixin<TestMinPreservingModulePass> { + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) { PreservedAnalyses PA; // Force running an analysis. - (void)AM->getResult<TestModuleAnalysis>(M); + (void)AM.getResult<TestModuleAnalysis>(M); PA.preserve<FunctionAnalysisManagerModuleProxy>(); return PA; } - - static StringRef name() { return "TestMinPreservingModulePass"; } }; -struct TestFunctionPass { +struct TestFunctionPass : PassInfoMixin<TestFunctionPass> { TestFunctionPass(int &RunCount, int &AnalyzedInstrCount, int &AnalyzedFunctionCount, bool OnlyUseCachedResults = false) @@ -124,11 +112,11 @@ struct TestFunctionPass { AnalyzedFunctionCount(AnalyzedFunctionCount), OnlyUseCachedResults(OnlyUseCachedResults) {} - PreservedAnalyses run(Function &F, FunctionAnalysisManager *AM) { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) { ++RunCount; const ModuleAnalysisManager &MAM = - AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager(); + AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager(); if (TestModuleAnalysis::Result *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent())) AnalyzedFunctionCount += TMA->FunctionCount; @@ -136,19 +124,17 @@ struct TestFunctionPass { if (OnlyUseCachedResults) { // Hack to force the use of the cached interface. if (TestFunctionAnalysis::Result *AR = - AM->getCachedResult<TestFunctionAnalysis>(F)) + AM.getCachedResult<TestFunctionAnalysis>(F)) AnalyzedInstrCount += AR->InstructionCount; } else { // Typical path just runs the analysis as needed. - TestFunctionAnalysis::Result &AR = AM->getResult<TestFunctionAnalysis>(F); + TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F); AnalyzedInstrCount += AR.InstructionCount; } return PreservedAnalyses::all(); } - static StringRef name() { return "TestFunctionPass"; } - int &RunCount; int &AnalyzedInstrCount; int &AnalyzedFunctionCount; @@ -157,43 +143,42 @@ struct TestFunctionPass { // A test function pass that invalidates all function analyses for a function // with a specific name. -struct TestInvalidationFunctionPass { +struct TestInvalidationFunctionPass + : PassInfoMixin<TestInvalidationFunctionPass> { TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {} - PreservedAnalyses run(Function &F) { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) { return F.getName() == Name ? PreservedAnalyses::none() : PreservedAnalyses::all(); } - static StringRef name() { return "TestInvalidationFunctionPass"; } - StringRef Name; }; -std::unique_ptr<Module> parseIR(const char *IR) { - LLVMContext &C = getGlobalContext(); +std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) { SMDiagnostic Err; - return parseAssemblyString(IR, Err, C); + return parseAssemblyString(IR, Err, Context); } class PassManagerTest : public ::testing::Test { protected: + LLVMContext Context; std::unique_ptr<Module> M; public: PassManagerTest() - : M(parseIR("define void @f() {\n" - "entry:\n" - " call void @g()\n" - " call void @h()\n" - " ret void\n" - "}\n" - "define void @g() {\n" - " ret void\n" - "}\n" - "define void @h() {\n" - " ret void\n" - "}\n")) {} + : M(parseIR(Context, "define void @f() {\n" + "entry:\n" + " call void @g()\n" + " call void @h()\n" + " ret void\n" + "}\n" + "define void @g() {\n" + " ret void\n" + "}\n" + "define void @h() {\n" + " ret void\n" + "}\n")) {} }; TEST_F(PassManagerTest, BasicPreservedAnalyses) { @@ -232,13 +217,13 @@ TEST_F(PassManagerTest, BasicPreservedAnalyses) { TEST_F(PassManagerTest, Basic) { FunctionAnalysisManager FAM; int FunctionAnalysisRuns = 0; - FAM.registerPass(TestFunctionAnalysis(FunctionAnalysisRuns)); + FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); }); ModuleAnalysisManager MAM; int ModuleAnalysisRuns = 0; - MAM.registerPass(TestModuleAnalysis(ModuleAnalysisRuns)); - MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM)); - FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM)); + MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); }); + MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); + FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); ModulePassManager MPM; @@ -253,8 +238,8 @@ TEST_F(PassManagerTest, Basic) { { // Pointless scope to test move assignment. FunctionPassManager NestedFPM; - NestedFPM.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1, - AnalyzedFunctionCount1)); + NestedFPM.addPass(TestFunctionPass( + FunctionPassRunCount1, AnalyzedInstrCount1, AnalyzedFunctionCount1)); FPM = std::move(NestedFPM); } NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); @@ -315,7 +300,7 @@ TEST_F(PassManagerTest, Basic) { MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); } - MPM.run(*M, &MAM); + MPM.run(*M, MAM); // Validate module pass counters. EXPECT_EQ(1, ModulePassRunCount); diff --git a/gnu/llvm/unittests/IR/PatternMatch.cpp b/gnu/llvm/unittests/IR/PatternMatch.cpp index f3a27b8d250..1121d6554db 100644 --- a/gnu/llvm/unittests/IR/PatternMatch.cpp +++ b/gnu/llvm/unittests/IR/PatternMatch.cpp @@ -35,7 +35,7 @@ struct PatternMatchTest : ::testing::Test { std::unique_ptr<Module> M; Function *F; BasicBlock *BB; - IRBuilder<true, NoFolder> IRB; + IRBuilder<NoFolder> IRB; PatternMatchTest() : M(new Module("PatternMatchTestModule", Ctx)), diff --git a/gnu/llvm/unittests/IR/TypeBuilderTest.cpp b/gnu/llvm/unittests/IR/TypeBuilderTest.cpp index b7b3e45e35e..f2dccac001a 100644 --- a/gnu/llvm/unittests/IR/TypeBuilderTest.cpp +++ b/gnu/llvm/unittests/IR/TypeBuilderTest.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/TypeBuilder.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" @@ -17,141 +16,175 @@ using namespace llvm; namespace { TEST(TypeBuilderTest, Void) { - EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext()))); + LLVMContext Context; + EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, true>::get(Context))); + EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, false>::get(Context))); // Special cases for C compatibility: - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<void*, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<const void*, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<volatile void*, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<const volatile void*, false>::get( - getGlobalContext()))); + EXPECT_EQ(Type::getInt8PtrTy(Context), + (TypeBuilder<void *, false>::get(Context))); + EXPECT_EQ(Type::getInt8PtrTy(Context), + (TypeBuilder<const void *, false>::get(Context))); + EXPECT_EQ(Type::getInt8PtrTy(Context), + (TypeBuilder<volatile void *, false>::get(Context))); + EXPECT_EQ(Type::getInt8PtrTy(Context), + (TypeBuilder<const volatile void *, false>::get(Context))); } TEST(TypeBuilderTest, HostIntegers) { - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext()))); - - EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT), - (TypeBuilder<size_t, false>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT), - (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext()))); + LLVMContext Context; + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<int8_t, false>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<uint8_t, false>::get(Context))); + EXPECT_EQ(Type::getInt16Ty(Context), + (TypeBuilder<int16_t, false>::get(Context))); + EXPECT_EQ(Type::getInt16Ty(Context), + (TypeBuilder<uint16_t, false>::get(Context))); + EXPECT_EQ(Type::getInt32Ty(Context), + (TypeBuilder<int32_t, false>::get(Context))); + EXPECT_EQ(Type::getInt32Ty(Context), + (TypeBuilder<uint32_t, false>::get(Context))); + EXPECT_EQ(Type::getInt64Ty(Context), + (TypeBuilder<int64_t, false>::get(Context))); + EXPECT_EQ(Type::getInt64Ty(Context), + (TypeBuilder<uint64_t, false>::get(Context))); + + EXPECT_EQ(IntegerType::get(Context, sizeof(size_t) * CHAR_BIT), + (TypeBuilder<size_t, false>::get(Context))); + EXPECT_EQ(IntegerType::get(Context, sizeof(ptrdiff_t) * CHAR_BIT), + (TypeBuilder<ptrdiff_t, false>::get(Context))); } TEST(TypeBuilderTest, CrossCompilableIntegers) { - EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext()))); + LLVMContext Context; + EXPECT_EQ(IntegerType::get(Context, 1), + (TypeBuilder<types::i<1>, true>::get(Context))); + EXPECT_EQ(IntegerType::get(Context, 1), + (TypeBuilder<types::i<1>, false>::get(Context))); + EXPECT_EQ(IntegerType::get(Context, 72), + (TypeBuilder<types::i<72>, true>::get(Context))); + EXPECT_EQ(IntegerType::get(Context, 72), + (TypeBuilder<types::i<72>, false>::get(Context))); } TEST(TypeBuilderTest, Float) { - EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext()))); + LLVMContext Context; + EXPECT_EQ(Type::getFloatTy(Context), + (TypeBuilder<float, false>::get(Context))); + EXPECT_EQ(Type::getDoubleTy(Context), + (TypeBuilder<double, false>::get(Context))); // long double isn't supported yet. - EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext()))); + EXPECT_EQ(Type::getFloatTy(Context), + (TypeBuilder<types::ieee_float, true>::get(Context))); + EXPECT_EQ(Type::getFloatTy(Context), + (TypeBuilder<types::ieee_float, false>::get(Context))); + EXPECT_EQ(Type::getDoubleTy(Context), + (TypeBuilder<types::ieee_double, true>::get(Context))); + EXPECT_EQ(Type::getDoubleTy(Context), + (TypeBuilder<types::ieee_double, false>::get(Context))); + EXPECT_EQ(Type::getX86_FP80Ty(Context), + (TypeBuilder<types::x86_fp80, true>::get(Context))); + EXPECT_EQ(Type::getX86_FP80Ty(Context), + (TypeBuilder<types::x86_fp80, false>::get(Context))); + EXPECT_EQ(Type::getFP128Ty(Context), + (TypeBuilder<types::fp128, true>::get(Context))); + EXPECT_EQ(Type::getFP128Ty(Context), + (TypeBuilder<types::fp128, false>::get(Context))); + EXPECT_EQ(Type::getPPC_FP128Ty(Context), + (TypeBuilder<types::ppc_fp128, true>::get(Context))); + EXPECT_EQ(Type::getPPC_FP128Ty(Context), + (TypeBuilder<types::ppc_fp128, false>::get(Context))); } TEST(TypeBuilderTest, Derived) { - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), - (TypeBuilder<int8_t**, false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), - (TypeBuilder<int8_t[7], false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), - (TypeBuilder<int8_t[], false>::get(getGlobalContext()))); - - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), - (TypeBuilder<types::i<8>**, false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), - (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), - (TypeBuilder<types::i<8>[], false>::get(getGlobalContext()))); - - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), - (TypeBuilder<types::i<8>**, true>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), - (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), - (TypeBuilder<types::i<8>[], true>::get(getGlobalContext()))); - - - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const int8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<volatile int8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext()))); - - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const types::i<8>, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext()))); - - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const types::i<8>, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext()))); - - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext()))); + LLVMContext Context; + EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)), + (TypeBuilder<int8_t **, false>::get(Context))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7), + (TypeBuilder<int8_t[7], false>::get(Context))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0), + (TypeBuilder<int8_t[], false>::get(Context))); + + EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)), + (TypeBuilder<types::i<8> **, false>::get(Context))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7), + (TypeBuilder<types::i<8>[7], false>::get(Context))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0), + (TypeBuilder<types::i<8>[], false>::get(Context))); + + EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)), + (TypeBuilder<types::i<8> **, true>::get(Context))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7), + (TypeBuilder<types::i<8>[7], true>::get(Context))); + EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0), + (TypeBuilder<types::i<8>[], true>::get(Context))); + + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<const int8_t, false>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<volatile int8_t, false>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<const volatile int8_t, false>::get(Context))); + + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<const types::i<8>, false>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<volatile types::i<8>, false>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<const volatile types::i<8>, false>::get(Context))); + + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<const types::i<8>, true>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<volatile types::i<8>, true>::get(Context))); + EXPECT_EQ(Type::getInt8Ty(Context), + (TypeBuilder<const volatile types::i<8>, true>::get(Context))); + + EXPECT_EQ(Type::getInt8PtrTy(Context), + (TypeBuilder<const volatile int8_t *const volatile, false>::get( + Context))); } TEST(TypeBuilderTest, Functions) { + LLVMContext Context; std::vector<Type*> params; - EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false), - (TypeBuilder<void(), true>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char*, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, char, char, ...), - false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*, char, char, char), - false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...), - false>::get(getGlobalContext()))); + EXPECT_EQ(FunctionType::get(Type::getVoidTy(Context), params, false), + (TypeBuilder<void(), true>::get(Context))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), + (TypeBuilder<int8_t(...), false>::get(Context))); + params.push_back(TypeBuilder<int32_t *, false>::get(Context)); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false), + (TypeBuilder<int8_t(const int32_t *), false>::get(Context))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), + (TypeBuilder<int8_t(const int32_t *, ...), false>::get(Context))); + params.push_back(TypeBuilder<char *, false>::get(Context)); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false), + (TypeBuilder<int8_t(int32_t *, void *), false>::get(Context))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), + (TypeBuilder<int8_t(int32_t *, char *, ...), false>::get(Context))); + params.push_back(TypeBuilder<char, false>::get(Context)); + EXPECT_EQ( + FunctionType::get(Type::getInt8Ty(Context), params, false), + (TypeBuilder<int8_t(int32_t *, void *, char), false>::get(Context))); + EXPECT_EQ( + FunctionType::get(Type::getInt8Ty(Context), params, true), + (TypeBuilder<int8_t(int32_t *, char *, char, ...), false>::get(Context))); + params.push_back(TypeBuilder<char, false>::get(Context)); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false), + (TypeBuilder<int8_t(int32_t *, void *, char, char), false>::get( + Context))); + EXPECT_EQ( + FunctionType::get(Type::getInt8Ty(Context), params, true), + (TypeBuilder<int8_t(int32_t *, char *, char, char, ...), false>::get( + Context))); + params.push_back(TypeBuilder<char, false>::get(Context)); + EXPECT_EQ( + FunctionType::get(Type::getInt8Ty(Context), params, false), + (TypeBuilder<int8_t(int32_t *, void *, char, char, char), false>::get( + Context))); + EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true), + (TypeBuilder<int8_t(int32_t *, char *, char, char, char, ...), + false>::get(Context))); } TEST(TypeBuilderTest, Context) { @@ -230,24 +263,24 @@ public: namespace { TEST(TypeBuilderTest, Extensions) { + LLVMContext Context; EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<int, false>::get(getGlobalContext()), - TypeBuilder<int*, false>::get(getGlobalContext()), - TypeBuilder<void*[], false>::get(getGlobalContext()), - (void*)nullptr)), - (TypeBuilder<MyType*, false>::get(getGlobalContext()))); - EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<types::i<32>, false>::get(getGlobalContext()), - TypeBuilder<types::i<32>*, false>::get(getGlobalContext()), - TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()), - (void*)nullptr)), - (TypeBuilder<MyPortableType*, false>::get(getGlobalContext()))); - EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<types::i<32>, false>::get(getGlobalContext()), - TypeBuilder<types::i<32>*, false>::get(getGlobalContext()), - TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()), - (void*)nullptr)), - (TypeBuilder<MyPortableType*, true>::get(getGlobalContext()))); + TypeBuilder<int, false>::get(Context), + TypeBuilder<int *, false>::get(Context), + TypeBuilder<void *[], false>::get(Context), (void *)nullptr)), + (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))); } } // anonymous namespace diff --git a/gnu/llvm/unittests/IR/UserTest.cpp b/gnu/llvm/unittests/IR/UserTest.cpp index 8d488389448..7d875aa80d4 100644 --- a/gnu/llvm/unittests/IR/UserTest.cpp +++ b/gnu/llvm/unittests/IR/UserTest.cpp @@ -94,9 +94,9 @@ TEST(UserTest, ValueOpIteration) { } TEST(UserTest, PersonalityUser) { - Module M("", getGlobalContext()); - FunctionType *RetVoidTy = - FunctionType::get(Type::getVoidTy(getGlobalContext()), false); + LLVMContext Context; + Module M("", Context); + FunctionType *RetVoidTy = FunctionType::get(Type::getVoidTy(Context), false); Function *PersonalityF = Function::Create( RetVoidTy, GlobalValue::ExternalLinkage, "PersonalityFn", &M); Function *TestF = diff --git a/gnu/llvm/unittests/IR/ValueHandleTest.cpp b/gnu/llvm/unittests/IR/ValueHandleTest.cpp index e1d598bbc58..59cd9d7ba37 100644 --- a/gnu/llvm/unittests/IR/ValueHandleTest.cpp +++ b/gnu/llvm/unittests/IR/ValueHandleTest.cpp @@ -20,13 +20,13 @@ namespace { class ValueHandle : public testing::Test { protected: + LLVMContext Context; Constant *ConstantV; std::unique_ptr<BitCastInst> BitcastV; - ValueHandle() : - ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)), - BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) { - } + ValueHandle() + : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)), + BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))) {} }; class ConcreteCallbackVH final : public CallbackVH { @@ -42,8 +42,8 @@ TEST_F(ValueHandle, WeakVH_BasicOperation) { // Make sure I can call a method on the underlying Value. It // doesn't matter which method. - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType()); - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType()); + EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType()); + EXPECT_EQ(Type::getInt32Ty(Context), (*WVH).getType()); } TEST_F(ValueHandle, WeakVH_Comparisons) { @@ -197,8 +197,8 @@ TEST_F(ValueHandle, CallbackVH_BasicOperation) { // Make sure I can call a method on the underlying Value. It // doesn't matter which method. - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType()); - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType()); + EXPECT_EQ(Type::getInt32Ty(Context), CVH->getType()); + EXPECT_EQ(Type::getInt32Ty(Context), (*CVH).getType()); } TEST_F(ValueHandle, CallbackVH_Comparisons) { @@ -297,15 +297,17 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) { Value *AURWArgument; LLVMContext *Context; - RecoveringVH() : DeletedCalls(0), AURWArgument(nullptr), - Context(&getGlobalContext()) {} - RecoveringVH(Value *V) - : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr), - Context(&getGlobalContext()) {} + RecoveringVH(LLVMContext &TheContext) + : DeletedCalls(0), AURWArgument(nullptr), Context(&TheContext) {} + + RecoveringVH(LLVMContext &TheContext, Value *V) + : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr), + Context(&TheContext) {} private: void deleted() override { - getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))); + getValPtr()->replaceAllUsesWith( + Constant::getNullValue(Type::getInt32Ty(*Context))); setValPtr(nullptr); } void allUsesReplacedWith(Value *new_value) override { @@ -318,15 +320,15 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) { // Normally, if a value has uses, deleting it will crash. However, we can use // a CallbackVH to remove the uses before the check for no uses. - RecoveringVH RVH; - RVH = BitcastV.get(); - std::unique_ptr<BinaryOperator> BitcastUser( - BinaryOperator::CreateAdd(RVH, - Constant::getNullValue(Type::getInt32Ty(getGlobalContext())))); + RecoveringVH RVH(Context); + RVH = RecoveringVH(Context, BitcastV.get()); + std::unique_ptr<BinaryOperator> BitcastUser(BinaryOperator::CreateAdd( + RVH, Constant::getNullValue(Type::getInt32Ty(Context)))); EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0)); BitcastV.reset(); // Would crash without the ValueHandler. - EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument); - EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), + EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)), + RVH.AURWArgument); + EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)), BitcastUser->getOperand(0)); } diff --git a/gnu/llvm/unittests/IR/ValueMapTest.cpp b/gnu/llvm/unittests/IR/ValueMapTest.cpp index 1431a8d87de..28633b44b11 100644 --- a/gnu/llvm/unittests/IR/ValueMapTest.cpp +++ b/gnu/llvm/unittests/IR/ValueMapTest.cpp @@ -22,15 +22,15 @@ namespace { template<typename T> class ValueMapTest : public testing::Test { protected: + LLVMContext Context; Constant *ConstantV; std::unique_ptr<BitCastInst> BitcastV; std::unique_ptr<BinaryOperator> AddV; - ValueMapTest() : - ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)), - BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))), - AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) { - } + ValueMapTest() + : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)), + BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))), + AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) {} }; // Run everything on Value*, a subtype to make sure that casting works as @@ -292,4 +292,4 @@ TYPED_TEST(ValueMapTest, SurvivesModificationByConfig) { EXPECT_EQ(0u, VM.count(this->AddV.get())); } -} +} // end namespace diff --git a/gnu/llvm/unittests/IR/ValueTest.cpp b/gnu/llvm/unittests/IR/ValueTest.cpp index 9cf1306dae6..607b7a1bd2c 100644 --- a/gnu/llvm/unittests/IR/ValueTest.cpp +++ b/gnu/llvm/unittests/IR/ValueTest.cpp @@ -45,7 +45,7 @@ TEST(ValueTest, UsedInBasicBlock) { } TEST(GlobalTest, CreateAddressSpace) { - LLVMContext &Ctx = getGlobalContext(); + LLVMContext Ctx; std::unique_ptr<Module> M(new Module("TestModule", Ctx)); Type *Int8Ty = Type::getInt8Ty(Ctx); Type *Int32Ty = Type::getInt32Ty(Ctx); @@ -92,7 +92,7 @@ TEST(GlobalTest, CreateAddressSpace) { #ifdef GTEST_HAS_DEATH_TEST #ifndef NDEBUG TEST(GlobalTest, AlignDeath) { - LLVMContext &Ctx = getGlobalContext(); + LLVMContext Ctx; std::unique_ptr<Module> M(new Module("TestModule", Ctx)); Type *Int32Ty = Type::getInt32Ty(Ctx); GlobalVariable *Var = diff --git a/gnu/llvm/unittests/IR/VerifierTest.cpp b/gnu/llvm/unittests/IR/VerifierTest.cpp index 4e94b4375f9..c33c92a6f7c 100644 --- a/gnu/llvm/unittests/IR/VerifierTest.cpp +++ b/gnu/llvm/unittests/IR/VerifierTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests ------------===// +//===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,24 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/Verifier.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" #include "gtest/gtest.h" namespace llvm { namespace { TEST(VerifierTest, Branch_i1) { - LLVMContext &C = getGlobalContext(); + LLVMContext C; Module M("M", C); FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy)); @@ -45,7 +47,7 @@ TEST(VerifierTest, Branch_i1) { } TEST(VerifierTest, InvalidRetAttribute) { - LLVMContext &C = getGlobalContext(); + LLVMContext C; Module M("M", C); FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy)); @@ -61,10 +63,10 @@ TEST(VerifierTest, InvalidRetAttribute) { } TEST(VerifierTest, CrossModuleRef) { - LLVMContext &C = getGlobalContext(); + LLVMContext C; Module M1("M1", C); Module M2("M2", C); - Module M3("M2", C); + Module M3("M3", C); FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); Function *F1 = cast<Function>(M1.getOrInsertFunction("foo1", FTy)); Function *F2 = cast<Function>(M2.getOrInsertFunction("foo2", FTy)); @@ -86,7 +88,21 @@ TEST(VerifierTest, CrossModuleRef) { std::string Error; raw_string_ostream ErrorOS(Error); - EXPECT_FALSE(verifyModule(M2, &ErrorOS)); + EXPECT_TRUE(verifyModule(M2, &ErrorOS)); + EXPECT_TRUE(StringRef(ErrorOS.str()) + .equals("Global is used by function in a different module\n" + "i32 ()* @foo2\n" + "; ModuleID = 'M2'\n" + "i32 ()* @foo3\n" + "; ModuleID = 'M3'\n" + "Global is referenced in a different module!\n" + "i32 ()* @foo2\n" + "; ModuleID = 'M2'\n" + " %call = call i32 @foo2()\n" + "i32 ()* @foo1\n" + "; ModuleID = 'M1'\n")); + + Error.clear(); EXPECT_TRUE(verifyModule(M1, &ErrorOS)); EXPECT_TRUE(StringRef(ErrorOS.str()).equals( "Referencing function in another module!\n" @@ -105,7 +121,104 @@ TEST(VerifierTest, CrossModuleRef) { F3->eraseFromParent(); } +TEST(VerifierTest, CrossModuleMetadataRef) { + LLVMContext C; + Module M1("M1", C); + Module M2("M2", C); + GlobalVariable *newGV = + new GlobalVariable(M1, Type::getInt8Ty(C), false, + GlobalVariable::ExternalLinkage, nullptr, + "Some Global"); + + DIBuilder dbuilder(M2); + auto CU = dbuilder.createCompileUnit(dwarf::DW_LANG_Julia, "test.jl", ".", + "unittest", false, "", 0); + auto File = dbuilder.createFile("test.jl", "."); + auto Ty = dbuilder.createBasicType("Int8", 8, 8, dwarf::DW_ATE_signed); + dbuilder.createGlobalVariable(CU, "_SOME_GLOBAL", "_SOME_GLOBAL", File, 1, Ty, + false, newGV); + dbuilder.finalize(); + std::string Error; + raw_string_ostream ErrorOS(Error); + EXPECT_TRUE(verifyModule(M2, &ErrorOS)); + EXPECT_TRUE(StringRef(ErrorOS.str()) + .startswith("Referencing global in another module!")); +} +TEST(VerifierTest, InvalidVariableLinkage) { + LLVMContext C; + Module M("M", C); + new GlobalVariable(M, Type::getInt8Ty(C), false, + GlobalValue::LinkOnceODRLinkage, nullptr, "Some Global"); + std::string Error; + raw_string_ostream ErrorOS(Error); + EXPECT_TRUE(verifyModule(M, &ErrorOS)); + EXPECT_TRUE( + StringRef(ErrorOS.str()).startswith("Global is external, but doesn't " + "have external or weak linkage!")); } + +TEST(VerifierTest, InvalidFunctionLinkage) { + LLVMContext C; + Module M("M", C); + + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); + Function::Create(FTy, GlobalValue::LinkOnceODRLinkage, "foo", &M); + std::string Error; + raw_string_ostream ErrorOS(Error); + EXPECT_TRUE(verifyModule(M, &ErrorOS)); + EXPECT_TRUE( + StringRef(ErrorOS.str()).startswith("Global is external, but doesn't " + "have external or weak linkage!")); } + +#ifndef _MSC_VER +// FIXME: This test causes an ICE in MSVC 2013. +TEST(VerifierTest, StripInvalidDebugInfo) { + LLVMContext C; + Module M("M", C); + DIBuilder DIB(M); + DIB.createCompileUnit(dwarf::DW_LANG_C89, "broken.c", "/", + "unittest", false, "", 0); + DIB.finalize(); + EXPECT_FALSE(verifyModule(M)); + + // Now break it. + auto *File = DIB.createFile("not-a-CU.f", "."); + NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); + NMD->addOperand(File); + EXPECT_TRUE(verifyModule(M)); + + ModulePassManager MPM(true); + MPM.addPass(VerifierPass(false)); + ModuleAnalysisManager MAM(true); + MAM.registerPass([&] { return VerifierAnalysis(); }); + MPM.run(M, MAM); + EXPECT_FALSE(verifyModule(M)); +} +#endif + +TEST(VerifierTest, StripInvalidDebugInfoLegacy) { + LLVMContext C; + Module M("M", C); + DIBuilder DIB(M); + DIB.createCompileUnit(dwarf::DW_LANG_C89, "broken.c", "/", + "unittest", false, "", 0); + DIB.finalize(); + EXPECT_FALSE(verifyModule(M)); + + // Now break it. + auto *File = DIB.createFile("not-a-CU.f", "."); + NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); + NMD->addOperand(File); + EXPECT_TRUE(verifyModule(M)); + + legacy::PassManager Passes; + Passes.add(createVerifierPass(false)); + Passes.run(M); + EXPECT_FALSE(verifyModule(M)); +} + +} // end anonymous namespace +} // end namespace llvm diff --git a/gnu/llvm/unittests/IR/WaymarkTest.cpp b/gnu/llvm/unittests/IR/WaymarkTest.cpp index a8924efed3f..4d2671c06c1 100644 --- a/gnu/llvm/unittests/IR/WaymarkTest.cpp +++ b/gnu/llvm/unittests/IR/WaymarkTest.cpp @@ -19,16 +19,14 @@ namespace llvm { namespace { -Constant *char2constant(char c) { - return ConstantInt::get(Type::getInt8Ty(getGlobalContext()), c); -} - - TEST(WaymarkTest, NativeArray) { + LLVMContext Context; static uint8_t tail[22] = "s02s33s30y2y0s1x0syxS"; Value * values[22]; - std::transform(tail, tail + 22, values, char2constant); - FunctionType *FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), true); + std::transform(tail, tail + 22, values, [&](char c) { + return ConstantInt::get(Type::getInt8Ty(Context), c); + }); + FunctionType *FT = FunctionType::get(Type::getVoidTy(Context), true); std::unique_ptr<Function> F( Function::Create(FT, GlobalValue::ExternalLinkage)); const CallInst *A = CallInst::Create(F.get(), makeArrayRef(values)); |