blob: 900823a1d16e44fcd87fed719eca3c37eeaeb23a [file] [log] [blame]
Duncan P. N. Exon Smith176b6912014-10-03 20:01:09 +00001//===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Duncan P. N. Exon Smith176b6912014-10-03 20:01:09 +00006//
7//===----------------------------------------------------------------------===//
8
Vedant Kumar93507922020-04-30 13:22:22 -07009#include "llvm/IR/DebugInfo.h"
10#include "llvm/AsmParser/Parser.h"
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +000011#include "llvm/IR/DebugInfoMetadata.h"
Vedant Kumar77ffce62020-05-19 18:03:22 -070012#include "llvm/IR/IntrinsicInst.h"
Vedant Kumar93507922020-04-30 13:22:22 -070013#include "llvm/IR/LLVMContext.h"
14#include "llvm/IR/Module.h"
15#include "llvm/IR/Verifier.h"
16#include "llvm/Support/SourceMgr.h"
Vedant Kumar77ffce62020-05-19 18:03:22 -070017#include "llvm/Transforms/Utils/Local.h"
Duncan P. N. Exon Smith176b6912014-10-03 20:01:09 +000018#include "gtest/gtest.h"
19
20using namespace llvm;
21
Vedant Kumar93507922020-04-30 13:22:22 -070022static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
23 SMDiagnostic Err;
24 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
25 if (!Mod)
26 Err.print("DebugInfoTest", errs());
27 return Mod;
28}
29
Duncan P. N. Exon Smith176b6912014-10-03 20:01:09 +000030namespace {
31
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000032TEST(DINodeTest, getFlag) {
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000033 // Some valid flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000034 EXPECT_EQ(DINode::FlagPublic, DINode::getFlag("DIFlagPublic"));
35 EXPECT_EQ(DINode::FlagProtected, DINode::getFlag("DIFlagProtected"));
36 EXPECT_EQ(DINode::FlagPrivate, DINode::getFlag("DIFlagPrivate"));
37 EXPECT_EQ(DINode::FlagVector, DINode::getFlag("DIFlagVector"));
38 EXPECT_EQ(DINode::FlagRValueReference,
39 DINode::getFlag("DIFlagRValueReference"));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000040
41 // FlagAccessibility shouldn't work.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000042 EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility"));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000043
44 // Some other invalid strings.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000045 EXPECT_EQ(0u, DINode::getFlag("FlagVector"));
46 EXPECT_EQ(0u, DINode::getFlag("Vector"));
47 EXPECT_EQ(0u, DINode::getFlag("other things"));
48 EXPECT_EQ(0u, DINode::getFlag("DIFlagOther"));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000049}
50
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000051TEST(DINodeTest, getFlagString) {
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000052 // Some valid flags.
53 EXPECT_EQ(StringRef("DIFlagPublic"),
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000054 DINode::getFlagString(DINode::FlagPublic));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000055 EXPECT_EQ(StringRef("DIFlagProtected"),
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000056 DINode::getFlagString(DINode::FlagProtected));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000057 EXPECT_EQ(StringRef("DIFlagPrivate"),
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000058 DINode::getFlagString(DINode::FlagPrivate));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000059 EXPECT_EQ(StringRef("DIFlagVector"),
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000060 DINode::getFlagString(DINode::FlagVector));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000061 EXPECT_EQ(StringRef("DIFlagRValueReference"),
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000062 DINode::getFlagString(DINode::FlagRValueReference));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000063
64 // FlagAccessibility actually equals FlagPublic.
65 EXPECT_EQ(StringRef("DIFlagPublic"),
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000066 DINode::getFlagString(DINode::FlagAccessibility));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000067
68 // Some other invalid flags.
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000069 EXPECT_EQ(StringRef(),
70 DINode::getFlagString(DINode::FlagPublic | DINode::FlagVector));
71 EXPECT_EQ(StringRef(), DINode::getFlagString(DINode::FlagFwdDecl |
72 DINode::FlagArtificial));
Leny Kholodov5fcc4182016-09-06 10:46:28 +000073 EXPECT_EQ(StringRef(),
74 DINode::getFlagString(static_cast<DINode::DIFlags>(0xffff)));
Duncan P. N. Exon Smithc22a5c22015-02-21 00:43:09 +000075}
76
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000077TEST(DINodeTest, splitFlags) {
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +000078// Some valid flags.
Duncan P. N. Exon Smith269e38d2015-02-21 00:45:26 +000079#define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \
80 { \
Leny Kholodov5fcc4182016-09-06 10:46:28 +000081 SmallVector<DINode::DIFlags, 8> V; \
Duncan P. N. Exon Smitha9308c42015-04-29 16:38:44 +000082 EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V)); \
Duncan P. N. Exon Smith5261e4b2015-04-07 01:21:40 +000083 EXPECT_TRUE(makeArrayRef(V).equals(VECTOR)); \
Duncan P. N. Exon Smith269e38d2015-02-21 00:45:26 +000084 }
Leny Kholodov5fcc4182016-09-06 10:46:28 +000085 CHECK_SPLIT(DINode::FlagPublic, {DINode::FlagPublic}, DINode::FlagZero);
86 CHECK_SPLIT(DINode::FlagProtected, {DINode::FlagProtected}, DINode::FlagZero);
87 CHECK_SPLIT(DINode::FlagPrivate, {DINode::FlagPrivate}, DINode::FlagZero);
88 CHECK_SPLIT(DINode::FlagVector, {DINode::FlagVector}, DINode::FlagZero);
Leny Kholodov40c62352016-09-06 17:03:02 +000089 CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference},
90 DINode::FlagZero);
Leny Kholodov5fcc4182016-09-06 10:46:28 +000091 DINode::DIFlags Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector};
Leny Kholodov40c62352016-09-06 17:03:02 +000092 CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags,
93 DINode::FlagZero);
Leny Kholodov5fcc4182016-09-06 10:46:28 +000094 CHECK_SPLIT(DINode::FlagZero, {}, DINode::FlagZero);
Duncan P. N. Exon Smith269e38d2015-02-21 00:45:26 +000095#undef CHECK_SPLIT
96}
97
Vedant Kumar93507922020-04-30 13:22:22 -070098TEST(StripTest, LoopMetadata) {
99 LLVMContext C;
100 std::unique_ptr<Module> M = parseIR(C, R"(
101 define void @f() !dbg !5 {
102 ret void, !dbg !10, !llvm.loop !11
103 }
104
105 !llvm.dbg.cu = !{!0}
106 !llvm.debugify = !{!3, !3}
107 !llvm.module.flags = !{!4}
108
109 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
110 !1 = !DIFile(filename: "loop.ll", directory: "/")
111 !2 = !{}
112 !3 = !{i32 1}
113 !4 = !{i32 2, !"Debug Info Version", i32 3}
114 !5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !7)
115 !6 = !DISubroutineType(types: !2)
116 !7 = !{!8}
117 !8 = !DILocalVariable(name: "1", scope: !5, file: !1, line: 1, type: !9)
118 !9 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
119 !10 = !DILocation(line: 1, column: 1, scope: !5)
120 !11 = distinct !{!11, !10, !10}
121)");
122
123 // Look up the debug info emission kind for the CU via the loop metadata
124 // attached to the terminator. If, when stripping non-line table debug info,
125 // we update the terminator's metadata correctly, we should be able to
126 // observe the change in emission kind for the CU.
127 auto getEmissionKind = [&]() {
128 Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI();
129 MDNode *LoopMD = I.getMetadata(LLVMContext::MD_loop);
130 return cast<DILocation>(LoopMD->getOperand(1))
131 ->getScope()
132 ->getSubprogram()
133 ->getUnit()
134 ->getEmissionKind();
135 };
136
137 EXPECT_EQ(getEmissionKind(), DICompileUnit::FullDebug);
138
139 bool Changed = stripNonLineTableDebugInfo(*M);
140 EXPECT_TRUE(Changed);
141
142 EXPECT_EQ(getEmissionKind(), DICompileUnit::LineTablesOnly);
143
144 bool BrokenDebugInfo = false;
145 bool HardError = verifyModule(*M, &errs(), &BrokenDebugInfo);
146 EXPECT_FALSE(HardError);
147 EXPECT_FALSE(BrokenDebugInfo);
148}
149
Vedant Kumar77ffce62020-05-19 18:03:22 -0700150TEST(MetadataTest, DeleteInstUsedByDbgValue) {
151 LLVMContext C;
152 std::unique_ptr<Module> M = parseIR(C, R"(
153 define i16 @f(i16 %a) !dbg !6 {
154 %b = add i16 %a, 1, !dbg !11
155 call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
156 ret i16 0, !dbg !11
157 }
158 declare void @llvm.dbg.value(metadata, metadata, metadata) #0
159 attributes #0 = { nounwind readnone speculatable willreturn }
160
161 !llvm.dbg.cu = !{!0}
162 !llvm.module.flags = !{!5}
163
164 !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
165 !1 = !DIFile(filename: "t.ll", directory: "/")
166 !2 = !{}
167 !5 = !{i32 2, !"Debug Info Version", i32 3}
168 !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
169 !7 = !DISubroutineType(types: !2)
170 !8 = !{!9}
171 !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
172 !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
173 !11 = !DILocation(line: 1, column: 1, scope: !6)
174)");
175
176 // Find %b = add ...
177 Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI();
178
179 // Find the dbg.value using %b.
180 SmallVector<DbgValueInst *, 1> DVIs;
181 findDbgValues(DVIs, &I);
182
183 // Delete %b. The dbg.value should now point to undef.
184 I.eraseFromParent();
185 EXPECT_TRUE(isa<UndefValue>(DVIs[0]->getValue()));
186}
187
Duncan P. N. Exon Smith176b6912014-10-03 20:01:09 +0000188} // end namespace