diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -792,19 +792,81 @@ 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); + 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; + SmallVector StoreInsts; + if((SI = dyn_cast(this))) + StoreInsts.push_back(SI); + else { + for (auto &AIUse : uses()) { + User *U = AIUse.getUser(); + if ((SI = dyn_cast(U)) && SI->getOperand(1) == this) + StoreInsts.push_back(SI); + } + } + + for (auto *SI : StoreInsts) { + Value *ValAddr = SI->getOperand(1); + Value *ReplVal = SI->getOperand(0); + SmallVector DbgUsers; + ValAddr->findDbgUsers(DbgUsers); + for (auto *DII : DbgUsers) { + auto &Ctx = getContext(); + DIExpression *DIExpr = DII->getExpression(); + DIVariable *Var = DII->getVariable(); + SmallVector Ops; + if (DIExpr->getNumElements() == 0) { + DIBuilder DIB(*getModule(), /*AllowUnresolved*/ false); + + DIType *Type = Var->getType(); + + if (DIDerivedType *DT = dyn_cast(Type)) + Type = DT->getBaseType(); + + auto *tmpVar = DIB.createAutoVariable(Var->getScope(), + llvm::StringRef(""), + Var->getFile(), Var->getLine(), + Type, false, + llvm::DINode::FlagArtificial, + Var->getAlignInBytes()); + + DIB.insertDbgValueIntrinsic( + ReplVal, tmpVar, DIExpression::get(DIExpr->getContext(), Ops), + DII->getDebugLoc(), SI); + + Ops.push_back(dwarf::DW_OP_LLVM_implicit_pointer); + Ops.push_back(dwarf::DW_OP_LLVM_arg0); + Ops.push_back(0); + DIExpression *DIExprNew = + DIExpression::get(DIExpr->getContext(), Ops); + DIB.insertDbgDerefValueIntrinsic(MetadataAsValue::get(Ctx, tmpVar), + DII->getVariable(), DIExprNew, + DII->getDebugLoc(), DII); + + DII->eraseFromParent(); + Changed = true; } - break; + } } + if (Changed) + return Changed; } - if (!DebugDeclareAddress) - DebugDeclareAddress = getModule()->findVarAddressMap(this); } for (auto *DII : DbgUsers) { diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2442,6 +2442,7 @@ C->isFalseWhenEqual())); } else if (isa(I) || isa(I) || isa(I)) { + I->salvageDebugInfo(); replaceInstUsesWith(*I, UndefValue::get(I->getType())); } else if (auto *SI = dyn_cast(I)) { for (auto *DII : DIIs) diff --git a/llvm/test/DebugInfo/implicit_pointer_temp_dyn_alloc.cc b/llvm/test/DebugInfo/implicit_pointer_temp_dyn_alloc.cc new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/implicit_pointer_temp_dyn_alloc.cc @@ -0,0 +1,11 @@ +// 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) + +int main() { + int *i = new int(3); + delete i; + + return 0; +} diff --git a/llvm/test/DebugInfo/implicit_pointer_temp_reference.cc b/llvm/test/DebugInfo/implicit_pointer_temp_reference.cc new file mode 100644 --- /dev/null +++ b/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()); +}