xref: /llvm-project/llvm/unittests/IR/DroppedVariableStatsIRTest.cpp (revision 12903fb3c73ad549c89585097f24d8b9952d849c)
1e7e622f1SShubham Sandeep Rastogi //===- unittests/IR/DroppedVariableStatsIRTest.cpp ------------------------===//
2e7e622f1SShubham Sandeep Rastogi //
3e7e622f1SShubham Sandeep Rastogi // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e7e622f1SShubham Sandeep Rastogi // See https://llvm.org/LICENSE.txt for license information.
5e7e622f1SShubham Sandeep Rastogi // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e7e622f1SShubham Sandeep Rastogi //
7e7e622f1SShubham Sandeep Rastogi //===----------------------------------------------------------------------===//
8e7e622f1SShubham Sandeep Rastogi 
9e7e622f1SShubham Sandeep Rastogi #include "llvm/AsmParser/Parser.h"
10e7e622f1SShubham Sandeep Rastogi #include "llvm/IR/Function.h"
11e7e622f1SShubham Sandeep Rastogi #include "llvm/IR/InstIterator.h"
12e7e622f1SShubham Sandeep Rastogi #include "llvm/IR/LegacyPassManager.h"
13e7e622f1SShubham Sandeep Rastogi #include "llvm/IR/Module.h"
14e7e622f1SShubham Sandeep Rastogi #include "llvm/Pass.h"
15e7e622f1SShubham Sandeep Rastogi #include "llvm/PassRegistry.h"
16e7e622f1SShubham Sandeep Rastogi #include "llvm/Passes/StandardInstrumentations.h"
17e7e622f1SShubham Sandeep Rastogi #include "llvm/Support/SourceMgr.h"
18e7e622f1SShubham Sandeep Rastogi #include "gtest/gtest.h"
19e7e622f1SShubham Sandeep Rastogi #include <gtest/gtest.h>
20e7e622f1SShubham Sandeep Rastogi #include <llvm/ADT/SmallString.h>
21e7e622f1SShubham Sandeep Rastogi #include <llvm/IR/LLVMContext.h>
22e7e622f1SShubham Sandeep Rastogi #include <llvm/IR/Module.h>
23e7e622f1SShubham Sandeep Rastogi #include <llvm/IR/PassInstrumentation.h>
24e7e622f1SShubham Sandeep Rastogi #include <llvm/IR/PassManager.h>
25e7e622f1SShubham Sandeep Rastogi #include <llvm/IR/PassTimingInfo.h>
26e7e622f1SShubham Sandeep Rastogi #include <llvm/Support/raw_ostream.h>
27e7e622f1SShubham Sandeep Rastogi 
28e7e622f1SShubham Sandeep Rastogi using namespace llvm;
29e7e622f1SShubham Sandeep Rastogi namespace llvm {
30e7e622f1SShubham Sandeep Rastogi void initializePassTest1Pass(PassRegistry &);
31e7e622f1SShubham Sandeep Rastogi 
32e7e622f1SShubham Sandeep Rastogi static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
33e7e622f1SShubham Sandeep Rastogi   SMDiagnostic Err;
34e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
35e7e622f1SShubham Sandeep Rastogi   if (!Mod)
36e7e622f1SShubham Sandeep Rastogi     Err.print("AbstractCallSiteTests", errs());
37e7e622f1SShubham Sandeep Rastogi   return Mod;
38e7e622f1SShubham Sandeep Rastogi }
39e7e622f1SShubham Sandeep Rastogi } // namespace llvm
40e7e622f1SShubham Sandeep Rastogi 
41e7e622f1SShubham Sandeep Rastogi namespace {
42e7e622f1SShubham Sandeep Rastogi 
43e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value and an instruction that exists in the
44e7e622f1SShubham Sandeep Rastogi // same scope as that #dbg_value are both deleted as a result of an optimization
45e7e622f1SShubham Sandeep Rastogi // pass, debug information is considered not dropped.
46e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, BothDeleted) {
47e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
48e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
49e7e622f1SShubham Sandeep Rastogi 
50e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
51e7e622f1SShubham Sandeep Rastogi 
52e7e622f1SShubham Sandeep Rastogi   const char *IR =
53e7e622f1SShubham Sandeep Rastogi       R"(
54e7e622f1SShubham Sandeep Rastogi       ; Function Attrs: mustprogress nounwind ssp uwtable(sync)
55e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
56e7e622f1SShubham Sandeep Rastogi       entry:
57e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
58e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
59e7e622f1SShubham Sandeep Rastogi         ret i32 0
60e7e622f1SShubham Sandeep Rastogi       }
61e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
62e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
63e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
64e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
65e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
66e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
67e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
68e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
69e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
70e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
71e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
72e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
73e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
74e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
75e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9)
76e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !9))";
77e7e622f1SShubham Sandeep Rastogi 
78e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
79e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
80e7e622f1SShubham Sandeep Rastogi 
81e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
82*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
83e7e622f1SShubham Sandeep Rastogi 
84e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
85e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
86e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
87e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
88e7e622f1SShubham Sandeep Rastogi       I.eraseFromParent();
89e7e622f1SShubham Sandeep Rastogi       break;
90e7e622f1SShubham Sandeep Rastogi     }
91e7e622f1SShubham Sandeep Rastogi     break;
92e7e622f1SShubham Sandeep Rastogi   }
93e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
94e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
95e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), false);
96e7e622f1SShubham Sandeep Rastogi }
97e7e622f1SShubham Sandeep Rastogi 
98e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value is dropped after an optimization pass,
99e7e622f1SShubham Sandeep Rastogi // but an instruction that shares the same scope as the #dbg_value still exists,
100e7e622f1SShubham Sandeep Rastogi // debug information is conisdered dropped.
101e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, DbgValLost) {
102e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
103e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
104e7e622f1SShubham Sandeep Rastogi 
105e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
106e7e622f1SShubham Sandeep Rastogi 
107e7e622f1SShubham Sandeep Rastogi   const char *IR =
108e7e622f1SShubham Sandeep Rastogi       R"(
109e7e622f1SShubham Sandeep Rastogi       ; Function Attrs: mustprogress nounwind ssp uwtable(sync)
110e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
111e7e622f1SShubham Sandeep Rastogi       entry:
112e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
113e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
114e7e622f1SShubham Sandeep Rastogi         ret i32 0
115e7e622f1SShubham Sandeep Rastogi       }
116e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
117e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
118e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
119e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
120e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
121e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
122e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
123e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
124e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
125e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
126e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
127e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
128e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
129e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
130e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9)
131e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !9))";
132e7e622f1SShubham Sandeep Rastogi 
133e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
134e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
135e7e622f1SShubham Sandeep Rastogi 
136e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
137*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
138e7e622f1SShubham Sandeep Rastogi 
139e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
140e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
141e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
142e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
143e7e622f1SShubham Sandeep Rastogi       break;
144e7e622f1SShubham Sandeep Rastogi     }
145e7e622f1SShubham Sandeep Rastogi     break;
146e7e622f1SShubham Sandeep Rastogi   }
147e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
148e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
149e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), true);
150e7e622f1SShubham Sandeep Rastogi }
151e7e622f1SShubham Sandeep Rastogi 
152e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value is dropped after an optimization pass,
153e7e622f1SShubham Sandeep Rastogi // but an instruction that has an unrelated scope as the #dbg_value still
154e7e622f1SShubham Sandeep Rastogi // exists, debug information is conisdered not dropped.
155e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, UnrelatedScopes) {
156e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
157e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
158e7e622f1SShubham Sandeep Rastogi 
159e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
160e7e622f1SShubham Sandeep Rastogi 
161e7e622f1SShubham Sandeep Rastogi   const char *IR =
162e7e622f1SShubham Sandeep Rastogi       R"(
163e7e622f1SShubham Sandeep Rastogi       ; Function Attrs: mustprogress nounwind ssp uwtable(sync)
164e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
165e7e622f1SShubham Sandeep Rastogi       entry:
166e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
167e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
168e7e622f1SShubham Sandeep Rastogi         ret i32 0
169e7e622f1SShubham Sandeep Rastogi       }
170e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
171e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
172e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
173e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
174e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
175e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
176e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
177e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
178e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
179e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
180e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
181e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
182e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
183e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
184e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9)
185e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !18)
186e7e622f1SShubham Sandeep Rastogi       !18 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bari", scope: !10, file: !10, line: 11, type: !11, scopeLine: 1,  unit: !0, retainedNodes: !14))";
187e7e622f1SShubham Sandeep Rastogi 
188e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
189e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
190e7e622f1SShubham Sandeep Rastogi 
191e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
192*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
193e7e622f1SShubham Sandeep Rastogi 
194e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
195e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
196e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
197e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
198e7e622f1SShubham Sandeep Rastogi       break;
199e7e622f1SShubham Sandeep Rastogi     }
200e7e622f1SShubham Sandeep Rastogi     break;
201e7e622f1SShubham Sandeep Rastogi   }
202e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
203e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
204e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), false);
205e7e622f1SShubham Sandeep Rastogi }
206e7e622f1SShubham Sandeep Rastogi 
207e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value is dropped after an optimization pass,
208e7e622f1SShubham Sandeep Rastogi // but an instruction that has a scope which is a child of the #dbg_value scope
209e7e622f1SShubham Sandeep Rastogi // still exists, debug information is conisdered dropped.
210e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, ChildScopes) {
211e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
212e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
213e7e622f1SShubham Sandeep Rastogi 
214e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
215e7e622f1SShubham Sandeep Rastogi 
216e7e622f1SShubham Sandeep Rastogi   const char *IR =
217e7e622f1SShubham Sandeep Rastogi       R"(
218e7e622f1SShubham Sandeep Rastogi       ; Function Attrs: mustprogress nounwind ssp uwtable(sync)
219e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
220e7e622f1SShubham Sandeep Rastogi       entry:
221e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
222e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
223e7e622f1SShubham Sandeep Rastogi         ret i32 0
224e7e622f1SShubham Sandeep Rastogi       }
225e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
226e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
227e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
228e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
229e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
230e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
231e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
232e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
233e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
234e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
235e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
236e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
237e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
238e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
239e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9)
240e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !18)
241e7e622f1SShubham Sandeep Rastogi       !18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28))";
242e7e622f1SShubham Sandeep Rastogi 
243e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
244e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
245e7e622f1SShubham Sandeep Rastogi 
246e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
247*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
248e7e622f1SShubham Sandeep Rastogi 
249e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
250e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
251e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
252e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
253e7e622f1SShubham Sandeep Rastogi       break;
254e7e622f1SShubham Sandeep Rastogi     }
255e7e622f1SShubham Sandeep Rastogi     break;
256e7e622f1SShubham Sandeep Rastogi   }
257e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
258e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
259e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), true);
260e7e622f1SShubham Sandeep Rastogi }
261e7e622f1SShubham Sandeep Rastogi 
262e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value is dropped after an optimization pass,
263e7e622f1SShubham Sandeep Rastogi // but an instruction that has a scope which is a child of the #dbg_value scope
264e7e622f1SShubham Sandeep Rastogi // still exists, and the #dbg_value is inlined at another location, debug
265e7e622f1SShubham Sandeep Rastogi // information is conisdered not dropped.
266e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, InlinedAt) {
267e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
268e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
269e7e622f1SShubham Sandeep Rastogi 
270e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
271e7e622f1SShubham Sandeep Rastogi 
272e7e622f1SShubham Sandeep Rastogi   const char *IR =
273e7e622f1SShubham Sandeep Rastogi       R"(; Function Attrs: mustprogress nounwind ssp uwtable(sync)
274e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
275e7e622f1SShubham Sandeep Rastogi       entry:
276e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
277e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
278e7e622f1SShubham Sandeep Rastogi         ret i32 0
279e7e622f1SShubham Sandeep Rastogi       }
280e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
281e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
282e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
283e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
284e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
285e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
286e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
287e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
288e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
289e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
290e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
291e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
292e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
293e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
294e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9, inlinedAt: !19)
295e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !18)
296e7e622f1SShubham Sandeep Rastogi       !18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28)
297e7e622f1SShubham Sandeep Rastogi       !19 = !DILocation(line: 3, column: 2, scope: !9))";
298e7e622f1SShubham Sandeep Rastogi 
299e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
300e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
301e7e622f1SShubham Sandeep Rastogi 
302e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
303*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
304e7e622f1SShubham Sandeep Rastogi 
305e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
306e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
307e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
308e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
309e7e622f1SShubham Sandeep Rastogi       break;
310e7e622f1SShubham Sandeep Rastogi     }
311e7e622f1SShubham Sandeep Rastogi     break;
312e7e622f1SShubham Sandeep Rastogi   }
313e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
314e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
315e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), false);
316e7e622f1SShubham Sandeep Rastogi }
317e7e622f1SShubham Sandeep Rastogi 
318e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value is dropped after an optimization pass,
319e7e622f1SShubham Sandeep Rastogi // but an instruction that has a scope which is a child of the #dbg_value scope
320e7e622f1SShubham Sandeep Rastogi // still exists, and the #dbg_value and the instruction are inlined at another
321e7e622f1SShubham Sandeep Rastogi // location, debug information is conisdered dropped.
322e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, InlinedAtShared) {
323e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
324e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
325e7e622f1SShubham Sandeep Rastogi 
326e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
327e7e622f1SShubham Sandeep Rastogi 
328e7e622f1SShubham Sandeep Rastogi   const char *IR =
329e7e622f1SShubham Sandeep Rastogi       R"(; Function Attrs: mustprogress nounwind ssp uwtable(sync)
330e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
331e7e622f1SShubham Sandeep Rastogi       entry:
332e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
333e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
334e7e622f1SShubham Sandeep Rastogi         ret i32 0
335e7e622f1SShubham Sandeep Rastogi       }
336e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
337e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
338e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
339e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
340e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
341e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
342e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
343e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
344e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
345e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
346e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
347e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
348e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
349e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
350e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9, inlinedAt: !19)
351e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !18, inlinedAt: !19)
352e7e622f1SShubham Sandeep Rastogi       !18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28)
353e7e622f1SShubham Sandeep Rastogi       !19 = !DILocation(line: 3, column: 2, scope: !9))";
354e7e622f1SShubham Sandeep Rastogi 
355e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
356e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
357e7e622f1SShubham Sandeep Rastogi 
358e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
359*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
360e7e622f1SShubham Sandeep Rastogi 
361e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
362e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
363e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
364e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
365e7e622f1SShubham Sandeep Rastogi       break;
366e7e622f1SShubham Sandeep Rastogi     }
367e7e622f1SShubham Sandeep Rastogi     break;
368e7e622f1SShubham Sandeep Rastogi   }
369e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
370e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
371e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), true);
372e7e622f1SShubham Sandeep Rastogi }
373e7e622f1SShubham Sandeep Rastogi 
374e7e622f1SShubham Sandeep Rastogi // This test ensures that if a #dbg_value is dropped after an optimization pass,
375e7e622f1SShubham Sandeep Rastogi // but an instruction that has a scope which is a child of the #dbg_value scope
376e7e622f1SShubham Sandeep Rastogi // still exists, and the instruction is inlined at a location that is the
377e7e622f1SShubham Sandeep Rastogi // #dbg_value's inlined at location, debug information is conisdered dropped.
378e7e622f1SShubham Sandeep Rastogi TEST(DroppedVariableStatsIR, InlinedAtChild) {
379e7e622f1SShubham Sandeep Rastogi   PassInstrumentationCallbacks PIC;
380e7e622f1SShubham Sandeep Rastogi   PassInstrumentation PI(&PIC);
381e7e622f1SShubham Sandeep Rastogi 
382e7e622f1SShubham Sandeep Rastogi   LLVMContext C;
383e7e622f1SShubham Sandeep Rastogi 
384e7e622f1SShubham Sandeep Rastogi   const char *IR =
385e7e622f1SShubham Sandeep Rastogi       R"(; Function Attrs: mustprogress nounwind ssp uwtable(sync)
386e7e622f1SShubham Sandeep Rastogi       define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
387e7e622f1SShubham Sandeep Rastogi       entry:
388e7e622f1SShubham Sandeep Rastogi         #dbg_value(i32 %x, !15, !DIExpression(), !16)
389e7e622f1SShubham Sandeep Rastogi         %add = add nsw i32 %x, 1, !dbg !17
390e7e622f1SShubham Sandeep Rastogi         ret i32 0
391e7e622f1SShubham Sandeep Rastogi       }
392e7e622f1SShubham Sandeep Rastogi       !llvm.dbg.cu = !{!0}
393e7e622f1SShubham Sandeep Rastogi       !llvm.module.flags = !{!3}
394e7e622f1SShubham Sandeep Rastogi       !llvm.ident = !{!8}
395e7e622f1SShubham Sandeep Rastogi       !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
396e7e622f1SShubham Sandeep Rastogi       !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
397e7e622f1SShubham Sandeep Rastogi       !3 = !{i32 2, !"Debug Info Version", i32 3}
398e7e622f1SShubham Sandeep Rastogi       !8 = !{!"clang"}
399e7e622f1SShubham Sandeep Rastogi       !9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
400e7e622f1SShubham Sandeep Rastogi       !10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
401e7e622f1SShubham Sandeep Rastogi       !11 = !DISubroutineType(types: !12)
402e7e622f1SShubham Sandeep Rastogi       !12 = !{!13, !13}
403e7e622f1SShubham Sandeep Rastogi       !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
404e7e622f1SShubham Sandeep Rastogi       !14 = !{!15}
405e7e622f1SShubham Sandeep Rastogi       !15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
406e7e622f1SShubham Sandeep Rastogi       !16 = !DILocation(line: 0, scope: !9, inlinedAt: !19)
407e7e622f1SShubham Sandeep Rastogi       !17 = !DILocation(line: 2, column: 11, scope: !18, inlinedAt: !20)
408e7e622f1SShubham Sandeep Rastogi       !18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28)
409e7e622f1SShubham Sandeep Rastogi       !19 = !DILocation(line: 3, column: 2, scope: !9);
410e7e622f1SShubham Sandeep Rastogi       !20 = !DILocation(line: 4, column: 5, scope: !18, inlinedAt: !19))";
411e7e622f1SShubham Sandeep Rastogi 
412e7e622f1SShubham Sandeep Rastogi   std::unique_ptr<llvm::Module> M = parseIR(C, IR);
413e7e622f1SShubham Sandeep Rastogi   ASSERT_TRUE(M);
414e7e622f1SShubham Sandeep Rastogi 
415e7e622f1SShubham Sandeep Rastogi   DroppedVariableStatsIR Stats(true);
416*12903fb3SShubham Sandeep Rastogi   Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
417e7e622f1SShubham Sandeep Rastogi 
418e7e622f1SShubham Sandeep Rastogi   // This loop simulates an IR pass that drops debug information.
419e7e622f1SShubham Sandeep Rastogi   for (auto &F : *M) {
420e7e622f1SShubham Sandeep Rastogi     for (auto &I : instructions(&F)) {
421e7e622f1SShubham Sandeep Rastogi       I.dropDbgRecords();
422e7e622f1SShubham Sandeep Rastogi       break;
423e7e622f1SShubham Sandeep Rastogi     }
424e7e622f1SShubham Sandeep Rastogi     break;
425e7e622f1SShubham Sandeep Rastogi   }
426e7e622f1SShubham Sandeep Rastogi   Stats.runAfterPass("Test",
427e7e622f1SShubham Sandeep Rastogi                      llvm::Any(const_cast<const llvm::Module *>(M.get())));
428e7e622f1SShubham Sandeep Rastogi   ASSERT_EQ(Stats.getPassDroppedVariables(), true);
429e7e622f1SShubham Sandeep Rastogi }
430e7e622f1SShubham Sandeep Rastogi 
431e7e622f1SShubham Sandeep Rastogi } // end anonymous namespace
432