From 2a5675f11d3bc803a245c0e2a3b47491c8f8a065 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Mon, 13 Apr 2020 16:15:37 -0700 Subject: [PATCH] [MachineDebugify] Insert synthetic DBG_VALUE instructions Summary: Teach MachineDebugify how to insert DBG_VALUE instructions. This can help find bugs causing CodeGen differences when debug info is present. DBG_VALUE instructions are only emitted when -debugify-level is set to locations+variables. There is essentially no attempt made to match up DBG_VALUE register operands with the local variables they ought to correspond to. I'm not sure how to improve the situation. In some cases (MachineMemOperand?) it's possible to find the IR instruction a MachineInstr corresponds to, but in general this seems to call for "undoing" the work done by ISel. Reviewers: dsanders, aprantl Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78135 --- llvm/lib/CodeGen/MachineDebugify.cpp | 90 ++++++++++++++++- llvm/lib/Transforms/Utils/Debugify.cpp | 40 ++++++-- .../AArch64/GlobalISel/constant-mir-debugify.mir | 33 +++++++ .../GlobalISel/legalize-phi-insertpt-decrement.mir | 2 +- .../AArch64/GlobalISel/phi-mir-debugify.mir | 106 +++++++++++++++++++++ .../{locations.mir => locations-and-values.mir} | 17 +++- llvm/test/DebugInfo/debugify.ll | 6 +- 7 files changed, 274 insertions(+), 20 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/constant-mir-debugify.mir create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/phi-mir-debugify.mir rename llvm/test/CodeGen/Generic/MIRDebugify/{locations.mir => locations-and-values.mir} (68%) diff --git a/llvm/lib/CodeGen/MachineDebugify.cpp b/llvm/lib/CodeGen/MachineDebugify.cpp index bc607ca..bf57ec0 100644 --- a/llvm/lib/CodeGen/MachineDebugify.cpp +++ b/llvm/lib/CodeGen/MachineDebugify.cpp @@ -7,16 +7,23 @@ //===----------------------------------------------------------------------===// /// /// \file This pass attaches synthetic debug info to everything. It can be used -/// to create targeted tests for debug info preservation. +/// to create targeted tests for debug info preservation, or test for CodeGen +/// differences with vs. without debug info. /// /// This isn't intended to have feature parity with Debugify. //===----------------------------------------------------------------------===// +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/InitializePasses.h" #include "llvm/Transforms/Utils/Debugify.h" @@ -31,13 +38,15 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI, if (!MaybeMF) return false; MachineFunction &MF = *MaybeMF; + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); DISubprogram *SP = F.getSubprogram(); assert(SP && "IR Debugify just created it?"); - LLVMContext &Ctx = F.getParent()->getContext(); - unsigned NextLine = SP->getLine(); + Module &M = *F.getParent(); + LLVMContext &Ctx = M.getContext(); + unsigned NextLine = SP->getLine(); for (MachineBasicBlock &MBB : MF) { for (MachineInstr &MI : MBB) { // This will likely emit line numbers beyond the end of the imagined @@ -48,6 +57,81 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI, } } + // Find local variables defined by debugify. No attempt is made to match up + // MIR-level regs to the 'correct' IR-level variables: there isn't a simple + // way to do that, and it isn't necessary to find interesting CodeGen bugs. + // Instead, simply keep track of one variable per line. Later, we can insert + // DBG_VALUE insts that point to these local variables. Emitting DBG_VALUEs + // which cover a wide range of lines can help stress the debug info passes: + // if we can't do that, fall back to using the local variable which precedes + // all the others. + Function *DbgValF = M.getFunction("llvm.dbg.value"); + DbgValueInst *EarliestDVI = nullptr; + DenseMap Line2Var; + DIExpression *Expr = nullptr; + if (DbgValF) { + for (const Use &U : DbgValF->uses()) { + auto *DVI = dyn_cast(U.getUser()); + if (!DVI || DVI->getFunction() != &F) + continue; + unsigned Line = DVI->getDebugLoc().getLine(); + assert(Line != 0 && "debugify should not insert line 0 locations"); + Line2Var[Line] = DVI->getVariable(); + if (!EarliestDVI || Line < EarliestDVI->getDebugLoc().getLine()) + EarliestDVI = DVI; + Expr = DVI->getExpression(); + } + } + if (Line2Var.empty()) + return true; + + // Now, try to insert a DBG_VALUE instruction after each real instruction. + // 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; + 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; ) { + MachineInstr &MI = *I; + ++I; + + // `I` may point to a DBG_VALUE created in the previous loop iteration. + if (MI.isDebugInstr()) + continue; + + // It's not allowed to insert DBG_VALUEs after a terminator. + if (MI.isTerminator()) + continue; + + // Find a suitable insertion point for the DBG_VALUE. + auto InsertBeforeIt = MI.isPHI() ? FirstNonPHIIt : I; + + // Find a suitable local variable for the DBG_VALUE. + unsigned Line = MI.getDebugLoc().getLine(); + if (!Line2Var.count(Line)) + Line = EarliestDVI->getDebugLoc().getLine(); + DILocalVariable *LocalVar = Line2Var[Line]; + assert(LocalVar && "No variable for current line?"); + + // Emit DBG_VALUEs for register definitions. + SmallVector RegDefs; + for (MachineOperand &MO : MI.operands()) + if (MO.isReg() && MO.isDef() && MO.getReg()) + RegDefs.push_back(&MO); + for (MachineOperand *MO : RegDefs) + BuildMI(MBB, InsertBeforeIt, MI.getDebugLoc(), DbgValDesc, + /*IsIndirect=*/false, *MO, LocalVar, Expr); + + // OK, failing that, emit a constant DBG_VALUE. + if (RegDefs.empty()) { + auto ImmOp = MachineOperand::CreateImm(NextImm++); + BuildMI(MBB, InsertBeforeIt, MI.getDebugLoc(), DbgValDesc, + /*IsIndirect=*/false, ImmOp, LocalVar, Expr); + } + } + } + return true; } diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp b/llvm/lib/Transforms/Utils/Debugify.cpp index 57f1740..f2739a8 100644 --- a/llvm/lib/Transforms/Utils/Debugify.cpp +++ b/llvm/lib/Transforms/Utils/Debugify.cpp @@ -75,6 +75,7 @@ bool llvm::applyDebugifyMetadata( DIBuilder DIB(M); LLVMContext &Ctx = M.getContext(); + auto *Int32Ty = Type::getInt32Ty(Ctx); // Get a DIType which corresponds to Ty. DenseMap TypeCache; @@ -99,6 +100,7 @@ bool llvm::applyDebugifyMetadata( if (isFunctionSkipped(F)) continue; + bool InsertedDbgVal = false; auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized; @@ -107,6 +109,23 @@ bool llvm::applyDebugifyMetadata( auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, SPType, NextLine, DINode::FlagZero, SPFlags); F.setSubprogram(SP); + + // Helper that inserts a dbg.value before \p InsertBefore, copying the + // location (and possibly the type, if it's non-void) from \p TemplateInst. + auto insertDbgVal = [&](Instruction &TemplateInst, + Instruction *InsertBefore) { + std::string Name = utostr(NextVar++); + Value *V = &TemplateInst; + if (TemplateInst.getType()->isVoidTy()) + V = ConstantInt::get(Int32Ty, 0); + const DILocation *Loc = TemplateInst.getDebugLoc().get(); + auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(), + getCachedDIType(V->getType()), + /*AlwaysPreserve=*/true); + DIB.insertDbgValueIntrinsic(V, LocalVar, DIB.createExpression(), Loc, + InsertBefore); + }; + for (BasicBlock &BB : F) { // Attach debug locations. for (Instruction &I : BB) @@ -141,15 +160,19 @@ bool llvm::applyDebugifyMetadata( if (!isa(I) && !I->isEHPad()) InsertBefore = I->getNextNode(); - std::string Name = utostr(NextVar++); - const DILocation *Loc = I->getDebugLoc().get(); - auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(), - getCachedDIType(I->getType()), - /*AlwaysPreserve=*/true); - DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc, - InsertBefore); + insertDbgVal(*I, InsertBefore); + InsertedDbgVal = true; } } + // Make sure we emit at least one dbg.value, otherwise MachineDebugify may + // not have anything to work with as it goes about inserting DBG_VALUEs. + // (It's common for MIR tests to be written containing skeletal IR with + // empty functions -- we're still interested in debugifying the MIR within + // those tests, and this helps with that.) + if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) { + auto *Term = findTerminatingInstruction(F.getEntryBlock()); + insertDbgVal(*Term, Term); + } if (ApplyToMF) ApplyToMF(DIB, F); DIB.finalizeSubprogram(SP); @@ -158,10 +181,9 @@ bool llvm::applyDebugifyMetadata( // Track the number of distinct lines and variables. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify"); - auto *IntTy = Type::getInt32Ty(Ctx); auto addDebugifyOperand = [&](unsigned N) { NMD->addOperand(MDNode::get( - Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N)))); + Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N)))); }; addDebugifyOperand(NextLine - 1); // Original number of lines. addDebugifyOperand(NextVar - 1); // Original number of variables. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/constant-mir-debugify.mir b/llvm/test/CodeGen/AArch64/GlobalISel/constant-mir-debugify.mir new file mode 100644 index 0000000..362f4511 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/constant-mir-debugify.mir @@ -0,0 +1,33 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -debugify-and-strip-all-safe=0 -run-pass=mir-debugify -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s +... +--- +name: fconstant_to_constant_s32 +alignment: 4 +tracksRegLiveness: true +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: fconstant_to_constant_s32 + ; CHECK: liveins: $x0 + ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0, debug-location !10 + ; CHECK: DBG_VALUE [[COPY]](p0), $noreg, !8, !DIExpression(), debug-location !10 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 0x3FA99999A0000000, debug-location !DILocation(line: 2, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[C]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 2, column: 1, scope: !5) + ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 524, debug-location !DILocation(line: 3, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[C1]](s64), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 3, column: 1, scope: !5) + ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64), debug-location !DILocation(line: 4, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[PTR_ADD]](p0), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 4, column: 1, scope: !5) + ; CHECK: G_STORE [[C]](s32), [[PTR_ADD]](p0), debug-location !DILocation(line: 5, column: 1, scope: !5) :: (store 4) + ; CHECK: DBG_VALUE 0, $noreg, !8, !DIExpression(), debug-location !DILocation(line: 5, column: 1, scope: !5) + ; CHECK: RET_ReallyLR debug-location !DILocation(line: 6, column: 1, scope: !5) + %0:_(p0) = COPY $x0 + %3:_(s32) = G_FCONSTANT float 0x3FA99999A0000000 + %1:_(s64) = G_CONSTANT i64 524 + %2:_(p0) = G_PTR_ADD %0, %1(s64) + G_STORE %3(s32), %2(p0) :: (store 4) + RET_ReallyLR +... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-phi-insertpt-decrement.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-phi-insertpt-decrement.mir index a02a81c..e6d4030 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-phi-insertpt-decrement.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-phi-insertpt-decrement.mir @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py -# RUN: llc -O0 -mtriple=aarch64-unknown-unknown -verify-machineinstrs -run-pass=legalizer %s -o - | FileCheck %s +# RUN: llc -debugify-and-strip-all-safe -O0 -mtriple=aarch64-unknown-unknown -verify-machineinstrs -run-pass=legalizer %s -o - | FileCheck %s --- | target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/phi-mir-debugify.mir b/llvm/test/CodeGen/AArch64/GlobalISel/phi-mir-debugify.mir new file mode 100644 index 0000000..7d85afe --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/phi-mir-debugify.mir @@ -0,0 +1,106 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -debugify-and-strip-all-safe=0 -run-pass=mir-debugify -verify-machineinstrs %s -o - | FileCheck %s +--- | + target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + target triple = "aarch64-unknown-unknown" + + define i32 @legalize_phi(i32 %argc) { + entry: + ret i32 0 + } + +... +--- +name: legalize_phi +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _, preferred-register: '' } + - { id: 1, class: _, preferred-register: '' } + - { id: 2, class: _, preferred-register: '' } + - { id: 3, class: _, preferred-register: '' } + - { id: 4, class: _, preferred-register: '' } + - { id: 5, class: _, preferred-register: '' } + - { id: 6, class: _, preferred-register: '' } + - { id: 7, class: _, preferred-register: '' } + - { id: 8, class: _, preferred-register: '' } + - { id: 9, class: _, preferred-register: '' } + - { id: 10, class: _, preferred-register: '' } +liveins: +body: | + ; CHECK-LABEL: name: legalize_phi + ; CHECK: bb.0: + ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; CHECK: liveins: $w0 + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0, debug-location !10 + ; CHECK: DBG_VALUE [[COPY]](s32), $noreg, !8, !DIExpression(), debug-location !10 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0, debug-location !DILocation(line: 2, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[C]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 2, column: 1, scope: !5) + ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1, debug-location !DILocation(line: 3, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[C1]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 3, column: 1, scope: !5) + ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2, debug-location !DILocation(line: 4, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[C2]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 4, column: 1, scope: !5) + ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), [[COPY]](s32), [[C]], debug-location !DILocation(line: 5, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[ICMP]](s1), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 5, column: 1, scope: !5) + ; CHECK: G_BRCOND [[ICMP]](s1), %bb.1, debug-location !DILocation(line: 6, column: 1, scope: !5) + ; CHECK: G_BR %bb.2, debug-location !DILocation(line: 7, column: 1, scope: !5) + ; CHECK: bb.1: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C1]], debug-location !DILocation(line: 8, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[ADD]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 8, column: 1, scope: !5) + ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ADD]](s32), debug-location !DILocation(line: 9, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[TRUNC]](s1), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 9, column: 1, scope: !5) + ; CHECK: G_BR %bb.3, debug-location !DILocation(line: 10, column: 1, scope: !5) + ; CHECK: bb.2: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C2]], debug-location !DILocation(line: 11, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[ADD1]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 11, column: 1, scope: !5) + ; CHECK: [[TRUNC1:%[0-9]+]]:_(s1) = G_TRUNC [[ADD1]](s32), debug-location !DILocation(line: 12, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[TRUNC1]](s1), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 12, column: 1, scope: !5) + ; CHECK: bb.3: + ; CHECK: [[PHI:%[0-9]+]]:_(s1) = G_PHI [[TRUNC]](s1), %bb.1, [[TRUNC1]](s1), %bb.2, debug-location !DILocation(line: 13, column: 1, scope: !5) + ; CHECK: [[PHI1:%[0-9]+]]:_(s1) = G_PHI [[TRUNC]](s1), %bb.1, [[TRUNC1]](s1), %bb.2, debug-location !DILocation(line: 14, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[PHI]](s1), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 13, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[PHI1]](s1), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 14, column: 1, scope: !5) + ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[PHI]](s1), debug-location !DILocation(line: 15, column: 1, scope: !5) + ; CHECK: DBG_VALUE [[ZEXT]](s32), $noreg, !8, !DIExpression(), debug-location !DILocation(line: 15, column: 1, scope: !5) + ; CHECK: $w0 = COPY [[ZEXT]](s32), debug-location !DILocation(line: 16, column: 1, scope: !5) + ; CHECK: DBG_VALUE $w0, $noreg, !8, !DIExpression(), debug-location !DILocation(line: 16, column: 1, scope: !5) + ; CHECK: RET_ReallyLR implicit $w0, debug-location !DILocation(line: 17, column: 1, scope: !5) + bb.0: + successors: %bb.1(0x40000000), %bb.2(0x40000000) + liveins: $w0 + + %0(s32) = COPY $w0 + %1(s32) = G_CONSTANT i32 0 + %3(s32) = G_CONSTANT i32 1 + %6(s32) = G_CONSTANT i32 2 + %2(s1) = G_ICMP intpred(ugt), %0(s32), %1 + G_BRCOND %2(s1), %bb.1 + G_BR %bb.2 + + bb.1: + successors: %bb.3(0x80000000) + + %4(s32) = G_ADD %0, %3 + %5(s1) = G_TRUNC %4(s32) + G_BR %bb.3 + + bb.2: + successors: %bb.3(0x80000000) + + %7(s32) = G_ADD %0, %6 + %8(s1) = G_TRUNC %7(s32) + + bb.3: + %9(s1) = G_PHI %5(s1), %bb.1, %8(s1), %bb.2 + %11:_(s1) = G_PHI %5(s1), %bb.1, %8(s1), %bb.2 + %10(s32) = G_ZEXT %9(s1) + $w0 = COPY %10(s32) + RET_ReallyLR implicit $w0 + +... diff --git a/llvm/test/CodeGen/Generic/MIRDebugify/locations.mir b/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir similarity index 68% rename from llvm/test/CodeGen/Generic/MIRDebugify/locations.mir rename to llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir index cd51432..84e93f9 100644 --- a/llvm/test/CodeGen/Generic/MIRDebugify/locations.mir +++ b/llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir @@ -17,11 +17,13 @@ ret i32 %sub } - ; CHECK: !llvm.dbg.cu = !{!0} - ; CHECK: !llvm.debugify = - ; CHECK: !llvm.module.flags = !{![[VERSION:[0-9]+]]} - ; CHECK: !0 = distinct !DICompileUnit( - ; CHECK: ![[VERSION]] = !{i32 2, !"Debug Info Version", i32 3} + ; ALL: !llvm.dbg.cu = !{!0} + ; ALL: !llvm.debugify = + ; ALL: !llvm.module.flags = !{![[VERSION:[0-9]+]]} + ; ALL: !0 = 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" ... --- @@ -37,8 +39,13 @@ body: | ; source file anyway. These first three coincide with IR-level information ; and therefore use metadata references. ; ALL: %0:_(s32) = IMPLICIT_DEF debug-location [[L1]] + ; VALUE: DBG_VALUE %0(s32), $noreg, [[VAR1]], !DIExpression(), debug-location [[L1]] ; ALL: %1:_(s32) = IMPLICIT_DEF debug-location [[L2]] + ; 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) + ; 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) + ; VALUE: DBG_VALUE %4(s32), $noreg, [[VAR1]], !DIExpression(), debug-location !DILocation(line: 5 ... diff --git a/llvm/test/DebugInfo/debugify.ll b/llvm/test/DebugInfo/debugify.ll index 16dd6358..89f62e2 100644 --- a/llvm/test/DebugInfo/debugify.ll +++ b/llvm/test/DebugInfo/debugify.ll @@ -76,11 +76,13 @@ define i32 @boom() { ; --- DILocalVariables ; CHECK-DAG: ![[TY32:.*]] = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned) -; CHECK-DAG: !DILocalVariable(name: "1", scope: {{.*}}, file: {{.*}}, line: 3, type: ![[TY32]]) +; CHECK-DAG: !DILocalVariable(name: "1", scope: {{.*}}, file: {{.*}}, line: 1, type: ![[TY32]]) +; CHECK-DAG: !DILocalVariable(name: "2", scope: {{.*}}, file: {{.*}}, line: 3, type: ![[TY32]]) +; CHECK-DAG: !DILocalVariable(name: "3", scope: {{.*}}, file: {{.*}}, line: 5, type: ![[TY32]]) ; --- Metadata counts ; CHECK-DAG: ![[NUM_INSTS]] = !{i32 6} -; CHECK-DAG: ![[NUM_VARS]] = !{i32 1} +; CHECK-DAG: ![[NUM_VARS]] = !{i32 3} ; --- Repeat case ; CHECK-REPEAT: ModuleDebugify: Skipping module with debug info -- 2.7.4