[llvm-branch-commits] [llvm] c4d2d43 - [Debugify] Support checking Machine IR debug info
Xiang1 Zhang via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 14 17:58:22 PST 2020
Author: Xiang1 Zhang
Date: 2020-12-14T17:53:46-08:00
New Revision: c4d2d4337d50bed3cafd564daece1a197005b22b
URL: https://github.com/llvm/llvm-project/commit/c4d2d4337d50bed3cafd564daece1a197005b22b
DIFF: https://github.com/llvm/llvm-project/commit/c4d2d4337d50bed3cafd564daece1a197005b22b.diff
LOG: [Debugify] Support checking Machine IR debug info
Add mir-check-debug pass to check MIR-level debug info.
For IR-level, currently, LLVM have debugify + check-debugify to generate
and check debug IR. Much like the IR-level pass debugify, mir-debugify
inserts sequentially increasing line locations to each MachineInstr in a
Module, But there is no equivalent MIR-level check-debugify pass, So now
we support it at "mir-check-debug".
Reviewed By: djtodoro
Differential Revision: https://reviews.llvm.org/D91595
Added:
llvm/lib/CodeGen/MachineCheckDebugify.cpp
llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables-x.mir
llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.ll
llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.mir
Modified:
llvm/docs/HowToUpdateDebugInfo.rst
llvm/include/llvm/CodeGen/Passes.h
llvm/include/llvm/CodeGen/TargetPassConfig.h
llvm/include/llvm/InitializePasses.h
llvm/lib/CodeGen/CMakeLists.txt
llvm/lib/CodeGen/CodeGen.cpp
llvm/lib/CodeGen/MachineDebugify.cpp
llvm/lib/CodeGen/TargetPassConfig.cpp
llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
Removed:
################################################################################
diff --git a/llvm/docs/HowToUpdateDebugInfo.rst b/llvm/docs/HowToUpdateDebugInfo.rst
index 7df2a8a25827..fff0cdbe59c8 100644
--- a/llvm/docs/HowToUpdateDebugInfo.rst
+++ b/llvm/docs/HowToUpdateDebugInfo.rst
@@ -342,8 +342,8 @@ A variant of the ``debugify`` utility described in
:ref:`Mutation testing for IR-level transformations<IRDebugify>` can be used
for MIR-level transformations as well: much like the IR-level pass,
``mir-debugify`` inserts sequentially increasing line locations to each
-``MachineInstr`` in a ``Module`` (although there is no equivalent MIR-level
-``check-debugify`` pass).
+``MachineInstr`` in a ``Module``. And the MIR-level ``mir-check-debugify`` is
+similar to IR-level ``check-debugify`` pass.
For example, here is a snippet before:
@@ -403,16 +403,32 @@ and ``-start-after``. For example:
$ llc -debugify-and-strip-all-safe -run-pass=... <other llc args>
$ llc -debugify-and-strip-all-safe -O1 <other llc args>
+If you want to check it after each pass in a pipeline, use
+``-debugify-check-and-strip-all-safe``. This can also be combined with
+``-start-before`` and ``-start-after``. For example:
+
+.. code-block:: bash
+
+ $ llc -debugify-check-and-strip-all-safe -run-pass=... <other llc args>
+ $ llc -debugify-check-and-strip-all-safe -O1 <other llc args>
+
+To check all debug info from a test, use ``mir-check-debugify``, like:
+
+.. code-block:: bash
+
+ $ llc -run-pass=mir-debugify,other-pass,mir-check-debugify
+
To strip out all debug info from a test, use ``mir-strip-debug``, like:
.. code-block:: bash
$ llc -run-pass=mir-debugify,other-pass,mir-strip-debug
-It can be useful to combine ``mir-debugify`` and ``mir-strip-debug`` to
-identify backend transformations which break in the presence of debug info.
-For example, to run the AArch64 backend tests with all normal passes
-"sandwiched" in between MIRDebugify and MIRStripDebugify mutation passes, run:
+It can be useful to combine ``mir-debugify``, ``mir-check-debugify`` and/or
+``mir-strip-debug`` to identify backend transformations which break in
+the presence of debug info. For example, to run the AArch64 backend tests
+with all normal passes "sandwiched" in between MIRDebugify and
+MIRStripDebugify mutation passes, run:
.. code-block:: bash
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index 47037bac6270..676ed2c65eb1 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -482,6 +482,9 @@ namespace llvm {
/// info was generated by another source such as clang.
ModulePass *createStripDebugMachineModulePass(bool OnlyDebugified);
+ /// Creates MIR Check Debug pass. \see MachineCheckDebugify.cpp
+ ModulePass *createCheckDebugMachineModulePass();
+
/// The pass fixups statepoint machine instruction to replace usage of
/// caller saved registers with stack slots.
extern char &FixupStatepointCallerSavedID;
diff --git a/llvm/include/llvm/CodeGen/TargetPassConfig.h b/llvm/include/llvm/CodeGen/TargetPassConfig.h
index fc5245216941..9b42b0756d41 100644
--- a/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -313,6 +313,9 @@ class TargetPassConfig : public ImmutablePass {
/// Add a pass to remove debug info from the MIR.
void addStripDebugPass();
+ /// Add a pass to check synthesized debug info for MIR.
+ void addCheckDebugPass();
+
/// Add standard passes before a pass that's about to be added. For example,
/// the DebugifyMachineModulePass if it is enabled.
void addMachinePrePasses(bool AllowDebugify = true);
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index b8420ade06a7..e1b3a8dd3f3a 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -112,6 +112,7 @@ void initializeCallGraphViewerPass(PassRegistry&);
void initializeCallGraphWrapperPassPass(PassRegistry&);
void initializeCallSiteSplittingLegacyPassPass(PassRegistry&);
void initializeCalledValuePropagationLegacyPassPass(PassRegistry &);
+void initializeCheckDebugMachineModulePass(PassRegistry &);
void initializeCodeGenPreparePass(PassRegistry&);
void initializeConstantHoistingLegacyPassPass(PassRegistry&);
void initializeConstantMergeLegacyPassPass(PassRegistry&);
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 7dc854cbbf20..d50349c514a3 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -74,6 +74,7 @@ add_llvm_component_library(LLVMCodeGen
MachineCombiner.cpp
MachineCopyPropagation.cpp
MachineCSE.cpp
+ MachineCheckDebugify.cpp
MachineDebugify.cpp
MachineDominanceFrontier.cpp
MachineDominators.cpp
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index 92a2b73f52e3..94925498b01c 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -25,6 +25,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeBranchRelaxationPass(Registry);
initializeCFGuardLongjmpPass(Registry);
initializeCFIInstrInserterPass(Registry);
+ initializeCheckDebugMachineModulePass(Registry);
initializeCodeGenPreparePass(Registry);
initializeDeadMachineInstructionElimPass(Registry);
initializeDebugifyMachineModulePass(Registry);
diff --git a/llvm/lib/CodeGen/MachineCheckDebugify.cpp b/llvm/lib/CodeGen/MachineCheckDebugify.cpp
new file mode 100644
index 000000000000..bd7f0f862947
--- /dev/null
+++ b/llvm/lib/CodeGen/MachineCheckDebugify.cpp
@@ -0,0 +1,126 @@
+//===- MachineCheckDebugify.cpp - Check debug info ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This checks debug info after mir-debugify (+ pass-to-test). Currently
+/// it simply checks the integrity of line info in DILocation and
+/// DILocalVariable which mir-debugifiy generated before.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils/Debugify.h"
+
+#define DEBUG_TYPE "mir-check-debugify"
+
+using namespace llvm;
+
+namespace {
+
+struct CheckDebugMachineModule : public ModulePass {
+ bool runOnModule(Module &M) override {
+ MachineModuleInfo &MMI =
+ getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+
+ NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
+ if (!NMD) {
+ errs() << "WARNING: Please run mir-debugify to generate "
+ "llvm.mir.debugify metadata first.\n";
+ return false;
+ }
+
+ auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
+ return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
+ ->getZExtValue();
+ };
+ assert(NMD->getNumOperands() == 2 &&
+ "llvm.mir.debugify should have exactly 2 operands!");
+ unsigned NumLines = getDebugifyOperand(0);
+ unsigned NumVars = getDebugifyOperand(1);
+ BitVector MissingLines{NumLines, true};
+ BitVector MissingVars{NumVars, true};
+
+ for (Function &F : M.functions()) {
+ MachineFunction *MF = MMI.getMachineFunction(F);
+ if (!MF)
+ continue;
+ for (MachineBasicBlock &MBB : *MF) {
+ // Find missing lines.
+ // TODO: Avoid meta instructions other than dbg_val.
+ for (MachineInstr &MI : MBB) {
+ if (MI.isDebugValue())
+ continue;
+ const DebugLoc DL = MI.getDebugLoc();
+ if (DL && DL.getLine() != 0) {
+ MissingLines.reset(DL.getLine() - 1);
+ continue;
+ }
+
+ if (!DL) {
+ errs() << "WARNING: Instruction with empty DebugLoc in function ";
+ errs() << F.getName() << " --";
+ MI.print(errs());
+ }
+ }
+
+ // Find missing variables.
+ // TODO: Handle DBG_INSTR_REF which is under an experimental option now.
+ for (MachineInstr &MI : MBB) {
+ if (!MI.isDebugValue())
+ continue;
+ const DILocalVariable *LocalVar = MI.getDebugVariable();
+ unsigned Var = ~0U;
+
+ (void)to_integer(LocalVar->getName(), Var, 10);
+ assert(Var <= NumVars && "Unexpected name for DILocalVariable");
+ MissingVars.reset(Var - 1);
+ }
+ }
+ }
+
+ bool Fail = false;
+ for (unsigned Idx : MissingLines.set_bits()) {
+ errs() << "WARNING: Missing line " << Idx + 1 << "\n";
+ Fail = true;
+ }
+
+ for (unsigned Idx : MissingVars.set_bits()) {
+ errs() << "WARNING: Missing variable " << Idx + 1 << "\n";
+ Fail = true;
+ }
+ errs() << "Machine IR debug info check: ";
+ errs() << (Fail ? "FAIL" : "PASS") << "\n";
+
+ return false;
+ }
+
+ CheckDebugMachineModule() : ModulePass(ID) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<MachineModuleInfoWrapperPass>();
+ AU.addPreserved<MachineModuleInfoWrapperPass>();
+ AU.setPreservesCFG();
+ }
+
+ static char ID; // Pass identification.
+};
+char CheckDebugMachineModule::ID = 0;
+
+} // end anonymous namespace
+
+INITIALIZE_PASS_BEGIN(CheckDebugMachineModule, DEBUG_TYPE,
+ "Machine Check Debug Module", false, false)
+INITIALIZE_PASS_END(CheckDebugMachineModule, DEBUG_TYPE,
+ "Machine Check Debug Module", false, false)
+
+ModulePass *llvm::createCheckDebugMachineModulePass() {
+ return new CheckDebugMachineModule();
+}
diff --git a/llvm/lib/CodeGen/MachineDebugify.cpp b/llvm/lib/CodeGen/MachineDebugify.cpp
index bf57ec0e8c28..599a81847592 100644
--- a/llvm/lib/CodeGen/MachineDebugify.cpp
+++ b/llvm/lib/CodeGen/MachineDebugify.cpp
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -89,10 +90,11 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
// Do this by introducing debug uses of each register definition. If that is
// not possible (e.g. we have a phi or a meta instruction), emit a constant.
uint64_t NextImm = 0;
+ SmallSet<DILocalVariable *, 16> VarSet;
const MCInstrDesc &DbgValDesc = TII.get(TargetOpcode::DBG_VALUE);
for (MachineBasicBlock &MBB : MF) {
MachineBasicBlock::iterator FirstNonPHIIt = MBB.getFirstNonPHI();
- for (auto I = MBB.begin(), E = MBB.end(); I != E; ) {
+ for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
MachineInstr &MI = *I;
++I;
@@ -113,6 +115,7 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
Line = EarliestDVI->getDebugLoc().getLine();
DILocalVariable *LocalVar = Line2Var[Line];
assert(LocalVar && "No variable for current line?");
+ VarSet.insert(LocalVar);
// Emit DBG_VALUEs for register definitions.
SmallVector<MachineOperand *, 4> RegDefs;
@@ -132,6 +135,33 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
}
}
+ // Here we save the number of lines and variables into "llvm.mir.debugify".
+ // It is useful for mir-check-debugify.
+ NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
+ IntegerType *Int32Ty = Type::getInt32Ty(Ctx);
+ if (!NMD) {
+ NMD = M.getOrInsertNamedMetadata("llvm.mir.debugify");
+ auto addDebugifyOperand = [&](unsigned N) {
+ NMD->addOperand(MDNode::get(
+ Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N))));
+ };
+ // Add number of lines.
+ addDebugifyOperand(NextLine - 1);
+ // Add number of variables.
+ addDebugifyOperand(VarSet.size());
+ } else {
+ assert(NMD->getNumOperands() == 2 &&
+ "llvm.mir.debugify should have exactly 2 operands!");
+ auto setDebugifyOperand = [&](unsigned Idx, unsigned N) {
+ NMD->setOperand(Idx, MDNode::get(Ctx, ValueAsMetadata::getConstant(
+ ConstantInt::get(Int32Ty, N))));
+ };
+ // Set number of lines.
+ setDebugifyOperand(0, NextLine - 1);
+ // Set number of variables.
+ setDebugifyOperand(1, VarSet.size());
+ }
+
return true;
}
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 48686b9e04f8..10c1ff988ac5 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -120,6 +120,12 @@ static cl::opt<cl::boolOrDefault> DebugifyAndStripAll(
"Debugify MIR before and Strip debug after "
"each pass except those known to be unsafe when debug info is present"),
cl::ZeroOrMore);
+static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
+ "debugify-check-and-strip-all-safe", cl::Hidden,
+ cl::desc(
+ "Debugify MIR before, by checking and stripping the debug info after, "
+ "each pass except those known to be unsafe when debug info is present"),
+ cl::ZeroOrMore);
enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };
// Enable or disable the MachineOutliner.
static cl::opt<RunOutliner> EnableMachineOutliner(
@@ -625,15 +631,26 @@ void TargetPassConfig::addStripDebugPass() {
PM->add(createStripDebugMachineModulePass(/*OnlyDebugified=*/true));
}
+void TargetPassConfig::addCheckDebugPass() {
+ PM->add(createCheckDebugMachineModulePass());
+}
+
void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) {
- if (AllowDebugify && DebugifyAndStripAll == cl::BOU_TRUE && DebugifyIsSafe)
+ if (AllowDebugify && DebugifyIsSafe &&
+ (DebugifyAndStripAll == cl::BOU_TRUE ||
+ DebugifyCheckAndStripAll == cl::BOU_TRUE))
addDebugifyPass();
}
void TargetPassConfig::addMachinePostPasses(const std::string &Banner,
bool AllowVerify, bool AllowStrip) {
- if (DebugifyAndStripAll == cl::BOU_TRUE && DebugifyIsSafe)
- addStripDebugPass();
+ if (DebugifyIsSafe) {
+ if (DebugifyCheckAndStripAll == cl::BOU_TRUE) {
+ addCheckDebugPass();
+ addStripDebugPass();
+ } else if (DebugifyAndStripAll == cl::BOU_TRUE)
+ addStripDebugPass();
+ }
if (AllowVerify)
addVerifyPass(Banner);
}
diff --git a/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables-x.mir b/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables-x.mir
new file mode 100644
index 000000000000..47e78bc8a3f0
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables-x.mir
@@ -0,0 +1,79 @@
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-check-debugify -o - %s 2>&1 | FileCheck %s
+--- |
+ ; ModuleID = 'check-line-and-variables.mir'
+ source_filename = "check-line-and-variables.c"
+
+ @ga = dso_local local_unnamed_addr global i32 2, align 4
+
+ ; Function Attrs: nofree norecurse nounwind uwtable writeonly
+ define dso_local i32 @foo(i32 %a, i32 %b) local_unnamed_addr #0 !dbg !9 {
+ entry:
+ %add = add nsw i32 %b, %a, !dbg !15
+ call void @llvm.dbg.value(metadata i32 %add, metadata !12, metadata !DIExpression()), !dbg !15
+ %mul = shl nsw i32 %add, 1, !dbg !16
+ call void @llvm.dbg.value(metadata i32 %mul, metadata !14, metadata !DIExpression()), !dbg !16
+ store i32 %mul, i32* @ga, align 4, !dbg !17
+ ret i32 %add, !dbg !18
+ }
+
+ declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+ !llvm.module.flags = !{!0, !1}
+ !llvm.ident = !{!2}
+ !llvm.dbg.cu = !{!3}
+ !llvm.mir.debugify = !{!6, !7}
+ !llvm.debugify = !{!8, !7}
+
+ !0 = !{i32 1, !"wchar_size", i32 4}
+ !1 = !{i32 2, !"Debug Info Version", i32 3}
+ !2 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git c0a922b3db2d39f36c0c01776cce90cc160a7d62)"}
+ !3 = distinct !DICompileUnit(language: DW_LANG_C, file: !4, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !5)
+ !4 = !DIFile(filename: "main.mir", directory: "/")
+ !5 = !{}
+ !6 = !{i32 6}
+ !7 = !{i32 2}
+ !8 = !{i32 4}
+ !9 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !4, line: 1, type: !10, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !11)
+ !10 = !DISubroutineType(types: !5)
+ !11 = !{!12, !14}
+ !12 = !DILocalVariable(name: "1", scope: !9, file: !4, line: 1, type: !13)
+ !13 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
+ !14 = !DILocalVariable(name: "2", scope: !9, file: !4, line: 2, type: !13)
+ !15 = !DILocation(line: 1, column: 1, scope: !9)
+ !16 = !DILocation(line: 2, column: 1, scope: !9)
+ !17 = !DILocation(line: 3, column: 1, scope: !9)
+ !18 = !DILocation(line: 4, column: 1, scope: !9)
+
+...
+---
+name: foo
+body: |
+ bb.0.entry:
+ liveins: $edi, $esi
+
+ %1:gr32 = COPY $esi, debug-location !15
+ DBG_VALUE %1, $noreg, !12, !DIExpression(), debug-location !15
+ ; Let it missing !14 and debug-location !16
+ ; %0:gr32 = COPY $edi, debug-location !16
+ ; DBG_VALUE %0, $noreg, !14, !DIExpression(), debug-location !16
+ %0:gr32 = COPY $edi
+ %2:gr32 = nsw ADD32rr %1, %0, implicit-def dead $eflags, debug-location !17
+ DBG_VALUE %2, $noreg, !12, !DIExpression(), debug-location !17
+ DBG_VALUE $eflags, $noreg, !12, !DIExpression(), debug-location !17
+ %3:gr32 = nsw ADD32rr %2, %2, implicit-def dead $eflags, debug-location !18
+ DBG_VALUE %3, $noreg, !12, !DIExpression(), debug-location !18
+ DBG_VALUE $eflags, $noreg, !12, !DIExpression(), debug-location !18
+ MOV32mr $rip, 1, $noreg, @ga, $noreg, killed %3, debug-location !DILocation(line: 5, column: 1, scope: !9) :: (store 4 into @ga, !tbaa !18)
+ DBG_VALUE 0, $noreg, !12, !DIExpression(), debug-location !DILocation(line: 5, column: 1, scope: !9)
+ ; Let it miss Line 6: Change "!DILocation(line: 6, ..." to "!DILocation(line: 5, ..."
+ $eax = COPY %2, debug-location !DILocation(line: 5, column: 1, scope: !9)
+ DBG_VALUE $eax, $noreg, !12, !DIExpression(), debug-location !DILocation(line: 6, column: 1, scope: !9)
+ RET 0, $eax, debug-location !DILocation(line: 7, column: 1, scope: !9)
+
+ ;CHECK: WARNING: Instruction with empty DebugLoc in function foo --%1:gr32 = COPY $edi
+ ;CHECK-NEXT: WARNING: Missing line 2
+ ;CHECK-NEXT: WARNING: Missing line 6
+ ;CHECK-NEXT: WARNING: Missing variable 2
+ ;CHECK-NEXT: Machine IR debug info check: FAIL
+
+...
diff --git a/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.ll b/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.ll
new file mode 100644
index 000000000000..1b859907db0e
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.ll
@@ -0,0 +1,29 @@
+; RUN: llc -debugify-check-and-strip-all-safe -o - %s 2>&1 | FileCheck %s
+
+; ModuleID = 'main.c'
+source_filename = "main.c"
+
+ at ga = dso_local global i32 2, align 4
+
+define dso_local i32 @foo(i32 %a, i32 %b) {
+entry:
+ %a.addr = alloca i32, align 4
+ %b.addr = alloca i32, align 4
+ %c = alloca i32, align 4
+ store i32 %a, i32* %a.addr, align 4
+ store i32 %b, i32* %b.addr, align 4
+ %0 = load i32, i32* %a.addr, align 4
+ %1 = load i32, i32* %b.addr, align 4
+ %add = add nsw i32 %0, %1
+ store i32 %add, i32* %c, align 4
+ %2 = load i32, i32* %c, align 4
+ %mul = mul nsw i32 %2, 2
+ store i32 %mul, i32* @ga, align 4
+ %3 = load i32, i32* %c, align 4
+ ret i32 %3
+}
+
+; Different Back-Ends may have
diff erent number of passes, here we only
+; check two of them to make sure -debugify-check-and-strip-all-safe works.
+;CHECK: Machine IR debug info check: PASS
+;CHECK: Machine IR debug info check: PASS
diff --git a/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.mir b/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.mir
new file mode 100644
index 000000000000..1deb4fe5db09
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.mir
@@ -0,0 +1,69 @@
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-debugify,dead-mi-elimination,mir-check-debugify -o - %s 2>&1 | FileCheck %s
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-debugify,mir-check-debugify -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-PASS
+--- |
+ ; ModuleID = 'check-line-and-variables.mir'
+ source_filename = "check-line-and-variables.ll"
+
+ @ga = dso_local global i32 2, align 4
+
+ ; Function Attrs: noinline nounwind optnone uwtable
+ define dso_local i32 @foo(i32 %a, i32 %b) {
+ entry:
+ %a.addr = alloca i32, align 4
+ %b.addr = alloca i32, align 4
+ %c = alloca i32, align 4
+ store i32 %a, i32* %a.addr, align 4
+ store i32 %b, i32* %b.addr, align 4
+ %0 = load i32, i32* %a.addr, align 4
+ %1 = load i32, i32* %b.addr, align 4
+ %add = add nsw i32 %0, %1
+ store i32 %add, i32* %c, align 4
+ %2 = load i32, i32* %c, align 4
+ %mul = mul nsw i32 %2, 2
+ store i32 %mul, i32* @ga, align 4
+ %3 = load i32, i32* %c, align 4
+ ; dead-mi-elimination will remove %4 = ...
+ %4 = load i32, i32* %a.addr, align 4
+ ret i32 %3
+ }
+
+...
+---
+name: foo
+alignment: 16
+stack:
+ - { id: 0, name: a.addr, type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, name: b.addr, type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 2, name: c, type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.0.entry:
+ liveins: $edi, $esi
+
+ %2:gr32 = COPY $esi
+ %0:gr32 = COPY $edi
+ %1:gr32 = COPY killed %0
+ %3:gr32 = COPY killed %2
+ MOV32mr %stack.0.a.addr, 1, $noreg, 0, $noreg, %1 :: (store 4 into %ir.a.addr)
+ MOV32mr %stack.1.b.addr, 1, $noreg, 0, $noreg, %3 :: (store 4 into %ir.b.addr)
+ %14:gr32 = MOV32rm %stack.0.a.addr, 1, $noreg, 0, $noreg :: (load 4 from %ir.a.addr)
+ %13:gr32 = ADD32rm killed %14, %stack.1.b.addr, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load 4 from %ir.b.addr)
+ ; dead-mi-elimination will remove %15:gr32 = ...
+ %15:gr32 = MOV32rm %stack.0.a.addr, 1, $noreg, 0, $noreg :: (load 4 from %ir.a.addr)
+ MOV32mr %stack.2.c, 1, $noreg, 0, $noreg, killed %13 :: (store 4 into %ir.c)
+ %9:gr32 = MOV32rm %stack.2.c, 1, $noreg, 0, $noreg :: (load 4 from %ir.c)
+ %8:gr32 = SHL32ri killed %9, 1, implicit-def $eflags
+ MOV32mr $noreg, 1, $noreg, @ga, $noreg, killed %8 :: (store 4 into @ga)
+ %5:gr32 = MOV32rm %stack.2.c, 1, $noreg, 0, $noreg :: (load 4 from %ir.c)
+ $eax = COPY %5
+ RETQ implicit $eax
+
+ ;CHECK: WARNING: Missing line 9
+ ;CHECK-NEXT: Machine IR debug info check: FAIL
+ ;CHECK-PASS: Machine IR debug info check: PASS
+...
diff --git a/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir b/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
index 84e93f9474b8..79dc90f017c1 100644
--- a/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
+++ b/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir
@@ -17,10 +17,10 @@
ret i32 %sub
}
- ; ALL: !llvm.dbg.cu = !{!0}
+ ; ALL: !llvm.dbg.cu = !{![[CU:[0-9]+]]}
; ALL: !llvm.debugify =
; ALL: !llvm.module.flags = !{![[VERSION:[0-9]+]]}
- ; ALL: !0 = distinct !DICompileUnit(
+ ; ALL: ![[CU]] = distinct !DICompileUnit(
; ALL: ![[VERSION]] = !{i32 2, !"Debug Info Version", i32 3}
; VALUE: [[VAR1:![0-9]+]] = !DILocalVariable(name: "1"
; VALUE: [[VAR2:![0-9]+]] = !DILocalVariable(name: "2"
@@ -44,8 +44,8 @@ body: |
; VALUE: DBG_VALUE %1(s32), $noreg, [[VAR2]], !DIExpression(), debug-location [[L2]]
; ALL: %2:_(s32) = G_CONSTANT i32 2, debug-location [[L3]]
; VALUE: DBG_VALUE %2(s32), $noreg, [[VAR1]], !DIExpression(), debug-location [[L3]]
- ; ALL: %3:_(s32) = G_ADD %0, %2, debug-location !DILocation(line: 4, column: 1, scope: !6)
+ ; ALL: %3:_(s32) = G_ADD %0, %2, debug-location !DILocation(line: 4, column: 1, scope: [[SP:![0-9]+]])
; VALUE: DBG_VALUE %3(s32), $noreg, [[VAR1]], !DIExpression(), debug-location !DILocation(line: 4
- ; ALL: %4:_(s32) = G_SUB %3, %1, debug-location !DILocation(line: 5, column: 1, scope: !6)
+ ; ALL: %4:_(s32) = G_SUB %3, %1, debug-location !DILocation(line: 5, column: 1, scope: [[SP]])
; VALUE: DBG_VALUE %4(s32), $noreg, [[VAR1]], !DIExpression(), debug-location !DILocation(line: 5
...
diff --git a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
index a1e117bb716e..961cb0b0bc46 100644
--- a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
@@ -99,6 +99,7 @@ static_library("CodeGen") {
"MachineBlockPlacement.cpp",
"MachineBranchProbabilityInfo.cpp",
"MachineCSE.cpp",
+ "MachineCheckDebugify.cpp",
"MachineCombiner.cpp",
"MachineCopyPropagation.cpp",
"MachineDebugify.cpp",
More information about the llvm-branch-commits
mailing list