summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/IR/IRBuilderTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/IR/IRBuilderTest.cpp')
-rw-r--r--llvm/unittests/IR/IRBuilderTest.cpp152
1 files changed, 133 insertions, 19 deletions
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index d15ff9dd51a4..139e8832c97b 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -871,25 +871,139 @@ TEST_F(IRBuilderTest, createFunction) {
}
TEST_F(IRBuilderTest, DIBuilder) {
- IRBuilder<> Builder(BB);
- DIBuilder DIB(*M);
- auto File = DIB.createFile("F.CBL", "/");
- auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74,
- DIB.createFile("F.CBL", "/"), "llvm-cobol74",
- true, "", 0);
- auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(std::nullopt));
- auto SP = DIB.createFunction(
- CU, "foo", "", File, 1, Type, 1, DINode::FlagZero,
- DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
- F->setSubprogram(SP);
- AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
- auto BarSP = DIB.createFunction(
- CU, "bar", "", File, 1, Type, 1, DINode::FlagZero,
- DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
- auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
- I->setDebugLoc(DILocation::get(Ctx, 2, 0, BadScope));
- DIB.finalize();
- EXPECT_TRUE(verifyModule(*M));
+ auto GetLastDbgRecord = [](const Instruction *I) -> DbgRecord * {
+ if (I->getDbgRecordRange().empty())
+ return nullptr;
+ return &*std::prev(I->getDbgRecordRange().end());
+ };
+
+ auto ExpectOrder = [&](DbgInstPtr First, BasicBlock::iterator Second) {
+ if (M->IsNewDbgInfoFormat) {
+ EXPECT_TRUE(First.is<DbgRecord *>());
+ EXPECT_FALSE(Second->getDbgRecordRange().empty());
+ EXPECT_EQ(GetLastDbgRecord(&*Second), First.get<DbgRecord *>());
+ } else {
+ EXPECT_TRUE(First.is<Instruction *>());
+ EXPECT_EQ(&*std::prev(Second), First.get<Instruction *>());
+ }
+ };
+
+ auto RunTest = [&]() {
+ IRBuilder<> Builder(BB);
+ DIBuilder DIB(*M);
+ auto File = DIB.createFile("F.CBL", "/");
+ auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74,
+ DIB.createFile("F.CBL", "/"),
+ "llvm-cobol74", true, "", 0);
+ auto Type =
+ DIB.createSubroutineType(DIB.getOrCreateTypeArray(std::nullopt));
+ auto SP = DIB.createFunction(
+ CU, "foo", "", File, 1, Type, 1, DINode::FlagZero,
+ DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
+ F->setSubprogram(SP);
+ AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
+ auto BarSP = DIB.createFunction(
+ CU, "bar", "", File, 1, Type, 1, DINode::FlagZero,
+ DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
+ auto BarScope = DIB.createLexicalBlockFile(BarSP, File, 0);
+ I->setDebugLoc(DILocation::get(Ctx, 2, 0, BarScope));
+
+ // Create another instruction so that there's one before the alloca we're
+ // inserting debug intrinsics before, to make end-checking easier.
+ I = Builder.CreateAlloca(Builder.getInt1Ty());
+
+ // Label metadata and records
+ // --------------------------
+ DILocation *LabelLoc = DILocation::get(Ctx, 1, 0, BarScope);
+ DILabel *AlwaysPreserveLabel = DIB.createLabel(
+ BarScope, "meles_meles", File, 1, /*AlwaysPreserve*/ true);
+ DILabel *Label =
+ DIB.createLabel(BarScope, "badger", File, 1, /*AlwaysPreserve*/ false);
+
+ { /* dbg.label | DPLabel */
+ // Insert before I and check order.
+ ExpectOrder(DIB.insertLabel(Label, LabelLoc, I), I->getIterator());
+
+ // We should be able to insert at the end of the block, even if there's
+ // no terminator yet. Note that in RemoveDIs mode this record won't get
+ // inserted into the block untill another instruction is added.
+ DbgInstPtr LabelRecord = DIB.insertLabel(Label, LabelLoc, BB);
+ // Specifically do not insert a terminator, to check this works. `I`
+ // should have absorbed the DPLabel in the new debug info mode.
+ I = Builder.CreateAlloca(Builder.getInt32Ty());
+ ExpectOrder(LabelRecord, I->getIterator());
+ }
+
+ // Variable metadata and records
+ // -----------------------------
+ DILocation *VarLoc = DILocation::get(Ctx, 2, 0, BarScope);
+ auto *IntType = DIB.createBasicType("int", 32, dwarf::DW_ATE_signed);
+ DILocalVariable *VarX =
+ DIB.createAutoVariable(BarSP, "X", File, 2, IntType, true);
+ DILocalVariable *VarY =
+ DIB.createAutoVariable(BarSP, "Y", File, 2, IntType, true);
+ { /* dbg.value | DPValue::Value */
+ ExpectOrder(DIB.insertDbgValueIntrinsic(I, VarX, DIB.createExpression(),
+ VarLoc, I),
+ I->getIterator());
+ // Check inserting at end of the block works as with labels.
+ DbgInstPtr VarXValue = DIB.insertDbgValueIntrinsic(
+ I, VarX, DIB.createExpression(), VarLoc, BB);
+ I = Builder.CreateAlloca(Builder.getInt32Ty());
+ ExpectOrder(VarXValue, I->getIterator());
+ EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr);
+ }
+ { /* dbg.declare | DPValue::Declare */
+ ExpectOrder(DIB.insertDeclare(I, VarY, DIB.createExpression(), VarLoc, I),
+ I->getIterator());
+ // Check inserting at end of the block works as with labels.
+ DbgInstPtr VarYDeclare =
+ DIB.insertDeclare(I, VarY, DIB.createExpression(), VarLoc, BB);
+ I = Builder.CreateAlloca(Builder.getInt32Ty());
+ ExpectOrder(VarYDeclare, I->getIterator());
+ EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr);
+ }
+ { /* dbg.assign | DPValue::Assign */
+ I = Builder.CreateAlloca(Builder.getInt32Ty());
+ I->setMetadata(LLVMContext::MD_DIAssignID, DIAssignID::getDistinct(Ctx));
+ // DbgAssign interface is slightly different - it always inserts after the
+ // linked instr. Check we can do this with no instruction to insert
+ // before.
+ DbgInstPtr VarXAssign =
+ DIB.insertDbgAssign(I, I, VarX, DIB.createExpression(), I,
+ DIB.createExpression(), VarLoc);
+ I = Builder.CreateAlloca(Builder.getInt32Ty());
+ ExpectOrder(VarXAssign, I->getIterator());
+ EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr);
+ }
+
+ Builder.CreateRet(nullptr);
+ DIB.finalize();
+ // Check the labels are not/are added to Bar's retainedNodes array
+ // (AlwaysPreserve).
+ EXPECT_EQ(find(BarSP->getRetainedNodes(), Label),
+ BarSP->getRetainedNodes().end());
+ EXPECT_NE(find(BarSP->getRetainedNodes(), AlwaysPreserveLabel),
+ BarSP->getRetainedNodes().end());
+ EXPECT_NE(find(BarSP->getRetainedNodes(), VarX),
+ BarSP->getRetainedNodes().end());
+ EXPECT_NE(find(BarSP->getRetainedNodes(), VarY),
+ BarSP->getRetainedNodes().end());
+ EXPECT_TRUE(verifyModule(*M));
+ };
+
+ // Test in old-debug mode.
+ EXPECT_FALSE(M->IsNewDbgInfoFormat);
+ RunTest();
+
+ // Test in new-debug mode.
+ // Reset the test then call convertToNewDbgValues to flip the flag
+ // on the test's Module, Function and BasicBlock.
+ TearDown();
+ SetUp();
+ M->convertToNewDbgValues();
+ EXPECT_TRUE(M->IsNewDbgInfoFormat);
+ RunTest();
}
TEST_F(IRBuilderTest, createArtificialSubprogram) {