Index: llvm/lib/IR/Instruction.cpp =================================================================== --- llvm/lib/IR/Instruction.cpp +++ llvm/lib/IR/Instruction.cpp @@ -791,20 +791,35 @@ }; bool Changed = false; Value *DebugDeclareAddress = nullptr; - - if ((getModule()->getDwarfVersion() >= 5) && isa(*this)) { - for (auto *DII : DbgUsers) { - if (DII->isAddressOfVariable()) { - if (const llvm::MetadataAsValue *MDV = - dyn_cast(DII->getOperand(1))) - if (isa(MDV->getMetadata())) { - DebugDeclareAddress = DII->getOperand(1); - } - break; + SmallVector StoreInsts; + DenseMap ScopeTmpMap; + static unsigned TmpCount = 0; + + if (getModule()->getDwarfVersion() >= 5) { + if(isa(*this)) { + for (auto *DII : DbgUsers) { + if (DII->isAddressOfVariable()) { + if (const llvm::MetadataAsValue *MDV = + dyn_cast(DII->getOperand(1))) + if (isa(MDV->getMetadata())) { + DebugDeclareAddress = DII->getOperand(1); + } + break; + } } } + if (!DebugDeclareAddress) DebugDeclareAddress = getModule()->findVarAddressMap(this); + + if (!DebugDeclareAddress) { + StoreInst *SI; + for (auto &AIUse : uses()) { + User *U = AIUse.getUser(); + if ((SI = dyn_cast(U)) && SI->getOperand(1) == this) + StoreInsts.push_back(SI); + } + } } for (auto *DII : DbgUsers) { @@ -827,12 +842,57 @@ // - We failed to get the variable description, or // - Current instruction is not llvm.dbg.value, or // - Current instruction doesnt have constant offset - if (isa(this) && + if (!StoreInsts.empty()) { + if(!DII->getExpression()->extractIfOffset(ExprOffset)) + continue; + } else if (isa(this) && (!DebugDeclareAddress || DII->isAddressOfVariable() || !DII->getExpression()->extractIfOffset(ExprOffset))) continue; - if (isa(this)) { + if (!StoreInsts.empty()) { + DIBuilder DIB(*getModule(), /*AllowUnresolved*/ false); + + DIExpression *DIExpr = DII->getExpression(); + DIScope *Scope = DII->getDebugLoc()->getScope(); + + // If this is new Scope lets insert dbg.value before Store Inst + if (ScopeTmpMap.find(Scope) == ScopeTmpMap.end()) { + std::string SName("__implicit_ptr_tmp_"); + SName.append(std::to_string(TmpCount++)); + llvm::StringRef Name(SName); + uint32_t AlignInBits = DII->getVariable()->getAlignInBytes(); + DIType *Type = DII->getVariable()->getType(); + if (DIDerivedType *DT = dyn_cast(Type)) + Type = DT->getBaseType(); + + ScopeTmpMap[Scope] = DIB.createAutoVariable(Scope, Name, nullptr, 0, + Type, false, + llvm::DINode::FlagArtificial, + AlignInBits); + + for (auto *SI : StoreInsts) { + Value *ReplVal = SI->getOperand(0); + DIB.insertDbgValueIntrinsic(ReplVal, ScopeTmpMap[Scope], + DIExpression::get(DIExpr->getContext(), {}), + DII->getDebugLoc(), SI); + } + } + + // lets replace dbg.value with dbg.derefval + SmallVector Ops; + Ops.push_back(dwarf::DW_OP_LLVM_implicit_pointer); + Ops.push_back(dwarf::DW_OP_LLVM_arg0); + Ops.push_back(ExprOffset); + DIExpression *DIExprNew = DIExpression::get(DIExpr->getContext(), Ops); + + DIB.insertDbgDerefValueIntrinsic(ScopeTmpMap[Scope], + DII->getVariable(), DIExprNew, + DII->getDebugLoc(), DII); + + DII->eraseFromParent(); + Changed = true; + } else if (isa(this)) { // It will cause below transformation // // Before transformation Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2456,6 +2456,7 @@ } else { // Casts, GEP, or anything else: we're about to delete this instruction, // so it can not have any valid uses. + I->salvageDebugInfo(); replaceInstUsesWith(*I, UndefValue::get(I->getType())); } eraseInstFromFunction(*I); Index: llvm/test/DebugInfo/implicit_pointer_temp_dyn_alloc.cc =================================================================== --- /dev/null +++ llvm/test/DebugInfo/implicit_pointer_temp_dyn_alloc.cc @@ -0,0 +1,14 @@ +// RUN: clang %s -O2 -gdwarf-5 -S -emit-llvm -o %t.ll +// RUN: FileCheck %s --input-file=%t.ll + +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) + +int main() { + int *i = new int(3); + int *j = new int(4); + delete i; + delete j; + + return 0; +} Index: llvm/test/DebugInfo/implicit_pointer_temp_reference.cc =================================================================== --- /dev/null +++ llvm/test/DebugInfo/implicit_pointer_temp_reference.cc @@ -0,0 +1,16 @@ +// RUN: clang %s -O2 -gdwarf-5 -S -emit-llvm -o %t.ll +// RUN: FileCheck %s --input-file=%t.ll + +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) + +__attribute__((optnone)) int source() { + return 3; +} +__attribute__((optnone)) void f(int i) { +} +inline void sink(const int& p) { + f(p); +} +int main() { + sink(source()); +}