diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -135,14 +135,14 @@ assert(NewValue && "Values must be non-null"); auto Locations = location_ops(); auto OldIt = find(Locations, OldValue); - assert((OldIt != Locations.end() || DbgAssignAddrReplaced) && - "OldValue must be a current location"); + if (OldIt == Locations.end()) { + assert(DbgAssignAddrReplaced && + "OldValue must be dbg.assign addr if unused in DIArgList"); + return; + } + + assert(OldIt != Locations.end() && "OldValue must be a current location"); if (!hasArgList()) { - // Additional check necessary to avoid unconditionally replacing this - // operand when a dbg.assign address is replaced (DbgAssignAddrReplaced is - // true). - if (OldValue != getVariableLocationOp(0)) - return; Value *NewOperand = isa(NewValue) ? NewValue : MetadataAsValue::get( diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp --- a/llvm/unittests/IR/DebugInfoTest.cpp +++ b/llvm/unittests/IR/DebugInfoTest.cpp @@ -370,6 +370,12 @@ // Replace both. TEST_REPLACE(/*Old*/ P2, /*New*/ P1, /*Value*/ P1, /*Address*/ P1); + // Replace address only, value uses a DIArgList. + // Value = {DIArgList(V1)}, Addr = P1. + DAI->setRawLocation(DIArgList::get(C, ValueAsMetadata::get(V1))); + DAI->setExpression(DIExpression::get( + C, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value})); + TEST_REPLACE(/*Old*/ P1, /*New*/ P2, /*Value*/ V1, /*Address*/ P2); #undef TEST_REPLACE }