[Lldb-commits] [PATCH] D70644: [DebugInfo] Support for DW_OP_implicit_pointer (llvm.dbg_derefval)
alok created this revision. alok added reviewers: aprantl, probinson, dblaikie, jmorse, jini.susan.george, SouraVX, awpandey. alok added projects: LLVM, debug-info. Herald added a reviewer: bollu. Herald added subscribers: llvm-commits, lldb-commits, jdoerfert, asbirlea, george.burgess.iv, hiraditya. Herald added a project: LLDB. alok added a child revision: D6: [DebugInfo] Support for DW_OP_implicit_pointer (IR Verifier and Bitcode). alok added a parent revision: D70643: [DebugInfo] Support for DW_OP_implicit_pointer (DW_OP_LLVM_implicit_pointer). This patch (3/N) stems from D69787 as suggested by This is suggested by @jmorse. New intrinsic llvm.dbg.derefval is introduced. Summary: Since dbg.value currently represents (VAR=VALUE), the new intrinsic dbg.derefval will represent de-referenced value (*VAR = VAL) - Below represents ptr=null call void @llvm.dbg.value(metadata i32* null, metadata !21, metadata !DIExpression()) - And below represents *ptr=var call void @llvm.dbg.derefval(metadata !16, metadata !21, metadata !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0)) - And below represents *ptr=arr[1] call void @llvm.dbg.derefval(metadata !16, metadata !21, metadata !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 4)) - We should be able to represent the case when a variable points to temporary (initialized by constant) and temporary is optimized out. tmp=[CONST]; ptr=&tmp; call void @llvm.dbg.derefval(metadata [CONST], metadata !21, metadata !DIExpression(DW_OP_LLVM_arg0)) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D70644 Files: lldb/source/Expression/IRInterpreter.cpp llvm/docs/SourceLevelDebugging.rst llvm/include/llvm/Analysis/TargetTransformInfoImpl.h llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h llvm/include/llvm/CodeGen/MachineInstrBuilder.h llvm/include/llvm/IR/DIBuilder.h llvm/include/llvm/IR/InstVisitor.h llvm/include/llvm/IR/IntrinsicInst.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/MemorySSA.cpp llvm/lib/Analysis/ObjCARCInstKind.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp llvm/lib/CodeGen/LiveDebugValues.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h llvm/lib/IR/DIBuilder.cpp llvm/lib/IR/IntrinsicInst.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Transforms/Utils/Local.cpp llvm/lib/Transforms/Utils/SimplifyCFG.cpp polly/lib/Support/ScopHelper.cpp Index: polly/lib/Support/ScopHelper.cpp === --- polly/lib/Support/ScopHelper.cpp +++ polly/lib/Support/ScopHelper.cpp @@ -624,6 +624,7 @@ case llvm::Intrinsic::assume: // Some debug info intrinsics are supported/ignored. case llvm::Intrinsic::dbg_value: +case llvm::Intrinsic::dbg_derefval: case llvm::Intrinsic::dbg_declare: return true; default: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp === --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4010,6 +4010,7 @@ switch (IntrinsicID) { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: +case Intrinsic::dbg_derefval: case Intrinsic::dbg_label: case Intrinsic::lifetime_end: break; Index: llvm/lib/Transforms/Utils/Local.cpp === --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -385,6 +385,11 @@ return false; return true; } + if (DbgDerefValueInst *DVI = dyn_cast(I)) { +if (DVI->getDerefVariable()) + return false; +return true; + } if (DbgLabelInst *DLI = dyn_cast(I)) { if (DLI->getLabel()) return false; Index: llvm/lib/IR/Verifier.cpp === --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -4314,6 +4314,9 @@ case Intrinsic::dbg_value: // llvm.dbg.value visitDbgIntrinsic("value", cast(Call)); break; + case Intrinsic::dbg_derefval: // llvm.dbg.derefval +visitDbgIntrinsic("derefval", cast(Call)); +break; case Intrinsic::dbg_label: // llvm.dbg.label visitDbgLabelIntrinsic("label", cast(Call)); break; @@ -4836,8 +4839,9 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) { auto *MD = cast(DII.getArgOperand(0))->getMetadata(); AssertDI(isa(MD) || - (isa(MD) && !cast(MD)->getNumOperands()), - "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); + (isa(MD) && !cast(MD)->getNumOperands()) || +
[Lldb-commits] [PATCH] D70644: [DebugInfo] Support for DW_OP_implicit_pointer (llvm.dbg_derefval)
alok marked 12 inline comments as done. alok added inline comments. Comment at: llvm/docs/SourceLevelDebugging.rst:261 +This intrinsic is identical to `llvm.dbg.value`, except that it is used to +describe dereferenced value of pointer variable. The first argument is metadata. +The second argument is a `local variable `_ jmorse wrote: > I'd add some motivation to the first sentence, such as: "it it used to > describe the dereferenced value of a pointer variable, when the pointer > itself is no longer available in the program". Thanks for comment. It will be incorporated in next version. Comment at: llvm/docs/SourceLevelDebugging.rst:266-267 +interpreted based on the third argument. If the third argument represents +DW_OP_LLVM_implicit_pointer, the first argument is + `local variable `_ , otherwise it is the value +(wrapped as metadata). jmorse wrote: > IMO "is" should read "must", i.e. "the first argument must be a local > variable", to indicate this is required for correctness. Thanks for your comment. It will be included in next version. Comment at: llvm/docs/SourceLevelDebugging.rst:270 + +An `llvm.dbg.derefval` intrinsic is usefull when location which the variable +points to is optimized out, but the dereferenced value is known. StephenTozer wrote: > Correct usefull -> useful Thanks for your comment. It will be incorporated in next version. Comment at: llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h:369 + /// Build and insert a DBG_VALUE instructions specifying that dereferenced + /// value of \p Variable is given by \p V (suitably modified by \p Expr). jmorse wrote: > "that the dereferenced"? Thanks for your comment. It will be incorporated in next version. Comment at: llvm/include/llvm/CodeGen/MachineInstrBuilder.h:227-238 + const MachineInstrBuilder &addMetadata(const MDNode *MD, + bool IsImplicitPointer = false) const { MI->addOperand(*MF, MachineOperand::CreateMetadata(MD)); -assert((MI->isDebugValue() ? static_cast(MI->getDebugVariable()) - : true) && +assert(((MI->isDebugValue() && !IsImplicitPointer) +? static_cast(MI->getDebugVariable()) +: true) && "first MDNode argument of a DBG_VALUE not a variable"); jmorse wrote: > Perhaps it's worth adding a new "add" method, i.e. "addImplicitPtrMetadata"? > That avoids the extra argument, and in the call sites below it will be a > little clearer what's happening, as a "true" argument isn't especially > helpful. > > Plus, then you can assert that only DILocalVariables (or whatever) are added > as the implicit pointer metadata. Thanks for your comment. It will be incorporated in next version. Comment at: llvm/lib/CodeGen/LiveDebugValues.cpp:717-718 if (isDbgValueDescribedByReg(MI) || MI.getOperand(0).isImm() || - MI.getOperand(0).isFPImm() || MI.getOperand(0).isCImm()) { + MI.getOperand(0).isFPImm() || MI.getOperand(0).isCImm() || + MI.getOperand(0).isMetadata()) { // Use normal VarLoc constructor for registers and immediates. jmorse wrote: > The main VarLoc constructor called on line 720 is going to not recognise the > metadata operand and leave some fields uninitialized (it should probably > actually assert in this case). I reckon you'll need to add a new location > "Kind", and have it emitted in the BuildDbgValue method. > > The LiveDebugValues algorithm should (TM) handle and propagate this kind of > location fine. Thanks for pointing this out. This will be incorporated in next version. Comment at: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp:1447 } + case Intrinsic::dbg_derefval: { +// This form of DBG_VALUE is target-independent. jmorse wrote: > Perhaps easier here instead to have dbg_derefval and dbg_value share code, > with an additional assertion that MetadataAsValue operands can only come from > dbg_value's? Thanks for your comment. It will be incorporated in next version. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70644/new/ https://reviews.llvm.org/D70644 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D70644: [DebugInfo] Support for DW_OP_implicit_pointer (llvm.dbg_derefval)
alok updated this revision to Diff 234356. alok added a comment. This version is updated to rebase and to incorporate comments from @jmorse and @StephenTozer. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70644/new/ https://reviews.llvm.org/D70644 Files: lldb/source/Expression/IRInterpreter.cpp llvm/docs/SourceLevelDebugging.rst llvm/include/llvm/Analysis/TargetTransformInfoImpl.h llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h llvm/include/llvm/CodeGen/MachineInstr.h llvm/include/llvm/CodeGen/MachineInstrBuilder.h llvm/include/llvm/IR/DIBuilder.h llvm/include/llvm/IR/InstVisitor.h llvm/include/llvm/IR/IntrinsicInst.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/MemorySSA.cpp llvm/lib/Analysis/ObjCARCInstKind.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp llvm/lib/CodeGen/LiveDebugValues.cpp llvm/lib/CodeGen/MachineInstr.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/IR/DIBuilder.cpp llvm/lib/IR/IntrinsicInst.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Transforms/Utils/Local.cpp llvm/lib/Transforms/Utils/SimplifyCFG.cpp polly/lib/Support/ScopHelper.cpp Index: polly/lib/Support/ScopHelper.cpp === --- polly/lib/Support/ScopHelper.cpp +++ polly/lib/Support/ScopHelper.cpp @@ -624,6 +624,7 @@ case llvm::Intrinsic::assume: // Some debug info intrinsics are supported/ignored. case llvm::Intrinsic::dbg_value: +case llvm::Intrinsic::dbg_derefval: case llvm::Intrinsic::dbg_declare: return true; default: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp === --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4010,6 +4010,7 @@ switch (IntrinsicID) { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: +case Intrinsic::dbg_derefval: case Intrinsic::dbg_label: case Intrinsic::lifetime_end: break; Index: llvm/lib/Transforms/Utils/Local.cpp === --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -385,6 +385,11 @@ return false; return true; } + if (DbgDerefValueInst *DVI = dyn_cast(I)) { +if (DVI->getDerefVariable()) + return false; +return true; + } if (DbgLabelInst *DLI = dyn_cast(I)) { if (DLI->getLabel()) return false; Index: llvm/lib/IR/Verifier.cpp === --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -4322,6 +4322,9 @@ case Intrinsic::dbg_value: // llvm.dbg.value visitDbgIntrinsic("value", cast(Call)); break; + case Intrinsic::dbg_derefval: // llvm.dbg.derefval +visitDbgIntrinsic("derefval", cast(Call)); +break; case Intrinsic::dbg_label: // llvm.dbg.label visitDbgLabelIntrinsic("label", cast(Call)); break; @@ -4877,8 +4880,9 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) { auto *MD = cast(DII.getArgOperand(0))->getMetadata(); AssertDI(isa(MD) || - (isa(MD) && !cast(MD)->getNumOperands()), - "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); + (isa(MD) && !cast(MD)->getNumOperands()) || + isa(DII), + "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); AssertDI(isa(DII.getRawVariable()), "invalid llvm.dbg." + Kind + " intrinsic variable", &DII, DII.getRawVariable()); Index: llvm/lib/IR/IntrinsicInst.cpp === --- llvm/lib/IR/IntrinsicInst.cpp +++ llvm/lib/IR/IntrinsicInst.cpp @@ -50,6 +50,14 @@ return nullptr; } +Value *DbgVariableIntrinsic::getDerefVariable(bool AllowNullOp) const { + Value *Op = getArgOperand(0); + if (AllowNullOp && !Op) +return nullptr; + + return Op; +} + Optional DbgVariableIntrinsic::getFragmentSizeInBits() const { if (auto Fragment = getExpression()->getFragmentInfo()) return Fragment->SizeInBits; Index: llvm/lib/IR/DIBuilder.cpp === --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -887,6 +887,14 @@ InsertBefore); } +Instruction *DIBuilder::insertDbgDerefValueIntrinsic( +Value *V, DILocalVariable *VarInfo, DIExpression *Expr, +const DILocation *DL, Instruction *InsertBefore) { + return insertDbgDerefValueIntrinsic( + V, VarInfo, Expr, DL, InsertBefore ? InsertBefore->getParent() : nullptr, + InsertBefore); +} + Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, DI
[Lldb-commits] [PATCH] D70644: [DebugInfo] Support for DW_OP_implicit_pointer (llvm.dbg_derefval)
alok updated this revision to Diff 235919. alok added a comment. Rebased and updated. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70644/new/ https://reviews.llvm.org/D70644 Files: lldb/source/Expression/IRInterpreter.cpp llvm/docs/SourceLevelDebugging.rst llvm/include/llvm/Analysis/TargetTransformInfoImpl.h llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h llvm/include/llvm/CodeGen/MachineInstr.h llvm/include/llvm/CodeGen/MachineInstrBuilder.h llvm/include/llvm/IR/DIBuilder.h llvm/include/llvm/IR/InstVisitor.h llvm/include/llvm/IR/IntrinsicInst.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/MemorySSA.cpp llvm/lib/Analysis/ObjCARCInstKind.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp llvm/lib/CodeGen/LiveDebugValues.cpp llvm/lib/CodeGen/MachineInstr.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/IR/DIBuilder.cpp llvm/lib/IR/IntrinsicInst.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Transforms/Utils/Local.cpp llvm/lib/Transforms/Utils/SimplifyCFG.cpp polly/lib/Support/ScopHelper.cpp Index: polly/lib/Support/ScopHelper.cpp === --- polly/lib/Support/ScopHelper.cpp +++ polly/lib/Support/ScopHelper.cpp @@ -624,6 +624,7 @@ case llvm::Intrinsic::assume: // Some debug info intrinsics are supported/ignored. case llvm::Intrinsic::dbg_value: +case llvm::Intrinsic::dbg_derefval: case llvm::Intrinsic::dbg_declare: return true; default: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp === --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4010,6 +4010,7 @@ switch (IntrinsicID) { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: +case Intrinsic::dbg_derefval: case Intrinsic::dbg_label: case Intrinsic::lifetime_end: break; Index: llvm/lib/Transforms/Utils/Local.cpp === --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -385,6 +385,11 @@ return false; return true; } + if (DbgDerefValueInst *DVI = dyn_cast(I)) { +if (DVI->getDerefVariable()) + return false; +return true; + } if (DbgLabelInst *DLI = dyn_cast(I)) { if (DLI->getLabel()) return false; Index: llvm/lib/IR/Verifier.cpp === --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -4322,6 +4322,9 @@ case Intrinsic::dbg_value: // llvm.dbg.value visitDbgIntrinsic("value", cast(Call)); break; + case Intrinsic::dbg_derefval: // llvm.dbg.derefval +visitDbgIntrinsic("derefval", cast(Call)); +break; case Intrinsic::dbg_label: // llvm.dbg.label visitDbgLabelIntrinsic("label", cast(Call)); break; @@ -4877,8 +4880,9 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) { auto *MD = cast(DII.getArgOperand(0))->getMetadata(); AssertDI(isa(MD) || - (isa(MD) && !cast(MD)->getNumOperands()), - "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); + (isa(MD) && !cast(MD)->getNumOperands()) || + isa(DII), + "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); AssertDI(isa(DII.getRawVariable()), "invalid llvm.dbg." + Kind + " intrinsic variable", &DII, DII.getRawVariable()); Index: llvm/lib/IR/IntrinsicInst.cpp === --- llvm/lib/IR/IntrinsicInst.cpp +++ llvm/lib/IR/IntrinsicInst.cpp @@ -50,6 +50,14 @@ return nullptr; } +Value *DbgVariableIntrinsic::getDerefVariable(bool AllowNullOp) const { + Value *Op = getArgOperand(0); + if (AllowNullOp && !Op) +return nullptr; + + return Op; +} + Optional DbgVariableIntrinsic::getFragmentSizeInBits() const { if (auto Fragment = getExpression()->getFragmentInfo()) return Fragment->SizeInBits; Index: llvm/lib/IR/DIBuilder.cpp === --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -33,7 +33,7 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU) : M(m), VMContext(M.getContext()), CUNode(CU), - DeclareFn(nullptr), ValueFn(nullptr), LabelFn(nullptr), + DeclareFn(nullptr), ValueFn(nullptr), DerefvalFn(nullptr), LabelFn(nullptr), AllowUnresolvedNodes(AllowUnresolvedNodes) {} void DIBuilder::trackIfUnresolved(MDNode *N) { @@ -887,6 +887,22 @@ InsertBefore); } +Instruction *DIBuilder::insertDbgDerefValueIntrinsic( +Value *V, DILocalVariable *VarInfo, DIExpression *Expr, +const DILocation *DL, In
[Lldb-commits] [PATCH] D70644: [DebugInfo] Support for DW_OP_implicit_pointer (llvm.dbg_derefval)
alok updated this revision to Diff 235772. alok added a comment. Update to re-base and minor correction. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70644/new/ https://reviews.llvm.org/D70644 Files: lldb/source/Expression/IRInterpreter.cpp llvm/docs/SourceLevelDebugging.rst llvm/include/llvm/Analysis/TargetTransformInfoImpl.h llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h llvm/include/llvm/CodeGen/MachineInstr.h llvm/include/llvm/CodeGen/MachineInstrBuilder.h llvm/include/llvm/IR/DIBuilder.h llvm/include/llvm/IR/InstVisitor.h llvm/include/llvm/IR/IntrinsicInst.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/MemorySSA.cpp llvm/lib/Analysis/ObjCARCInstKind.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp llvm/lib/CodeGen/LiveDebugValues.cpp llvm/lib/CodeGen/MachineInstr.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/IR/DIBuilder.cpp llvm/lib/IR/IntrinsicInst.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Transforms/Utils/Local.cpp llvm/lib/Transforms/Utils/SimplifyCFG.cpp polly/lib/Support/ScopHelper.cpp Index: polly/lib/Support/ScopHelper.cpp === --- polly/lib/Support/ScopHelper.cpp +++ polly/lib/Support/ScopHelper.cpp @@ -624,6 +624,7 @@ case llvm::Intrinsic::assume: // Some debug info intrinsics are supported/ignored. case llvm::Intrinsic::dbg_value: +case llvm::Intrinsic::dbg_derefval: case llvm::Intrinsic::dbg_declare: return true; default: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp === --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4010,6 +4010,7 @@ switch (IntrinsicID) { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: +case Intrinsic::dbg_derefval: case Intrinsic::dbg_label: case Intrinsic::lifetime_end: break; Index: llvm/lib/Transforms/Utils/Local.cpp === --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -385,6 +385,11 @@ return false; return true; } + if (DbgDerefValueInst *DVI = dyn_cast(I)) { +if (DVI->getDerefVariable()) + return false; +return true; + } if (DbgLabelInst *DLI = dyn_cast(I)) { if (DLI->getLabel()) return false; Index: llvm/lib/IR/Verifier.cpp === --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -4322,6 +4322,9 @@ case Intrinsic::dbg_value: // llvm.dbg.value visitDbgIntrinsic("value", cast(Call)); break; + case Intrinsic::dbg_derefval: // llvm.dbg.derefval +visitDbgIntrinsic("derefval", cast(Call)); +break; case Intrinsic::dbg_label: // llvm.dbg.label visitDbgLabelIntrinsic("label", cast(Call)); break; @@ -4877,8 +4880,9 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) { auto *MD = cast(DII.getArgOperand(0))->getMetadata(); AssertDI(isa(MD) || - (isa(MD) && !cast(MD)->getNumOperands()), - "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); + (isa(MD) && !cast(MD)->getNumOperands()) || + isa(DII), + "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); AssertDI(isa(DII.getRawVariable()), "invalid llvm.dbg." + Kind + " intrinsic variable", &DII, DII.getRawVariable()); Index: llvm/lib/IR/IntrinsicInst.cpp === --- llvm/lib/IR/IntrinsicInst.cpp +++ llvm/lib/IR/IntrinsicInst.cpp @@ -50,6 +50,14 @@ return nullptr; } +Value *DbgVariableIntrinsic::getDerefVariable(bool AllowNullOp) const { + Value *Op = getArgOperand(0); + if (AllowNullOp && !Op) +return nullptr; + + return Op; +} + Optional DbgVariableIntrinsic::getFragmentSizeInBits() const { if (auto Fragment = getExpression()->getFragmentInfo()) return Fragment->SizeInBits; Index: llvm/lib/IR/DIBuilder.cpp === --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -33,7 +33,7 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU) : M(m), VMContext(M.getContext()), CUNode(CU), - DeclareFn(nullptr), ValueFn(nullptr), LabelFn(nullptr), + DeclareFn(nullptr), ValueFn(nullptr), DerefvalFn(nullptr), LabelFn(nullptr), AllowUnresolvedNodes(AllowUnresolvedNodes) {} void DIBuilder::trackIfUnresolved(MDNode *N) { @@ -887,6 +887,14 @@ InsertBefore); } +Instruction *DIBuilder::insertDbgDerefValueIntrinsic( +Value *V, DILocalVariable *VarInfo, DIExpression *Expr, +const