Index: lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- lib/Transforms/IPO/ArgumentPromotion.cpp +++ lib/Transforms/IPO/ArgumentPromotion.cpp @@ -49,6 +49,7 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" @@ -124,6 +125,23 @@ } else if (I->use_empty()) { // Dead argument (which are always marked as promotable) ++NumArgumentsDead; + + // Calls to llvm.dbg.value do not exist in the use list of the function + // arguments even if the argument is used in the call. Therefore we need + // to handle them separately. Find the ones associated with the current + // function argument and erase them. If they exist, they do so in the + // first basic block of the function. + + BasicBlock &BB = F->getEntryBlock(); + SmallVector InstrsToRemove; + for (Instruction &U : BB) { + DbgValueInst *DI = dyn_cast(&U); + if (DI && (DI->getValue() == I)) + InstrsToRemove.push_back(&U); + } + + for (auto U : InstrsToRemove) + U->eraseFromParent(); } else { // Okay, this is being promoted. This means that the only uses are loads // or GEPs which are only used by loads Index: test/Transforms/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll =================================================================== --- /dev/null +++ test/Transforms/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll @@ -0,0 +1,36 @@ +; RUN: opt -argpromotion -verify -dse -S %s -o - | FileCheck %s + +; Fix for PR33641. ArgumentPromotion removed the argument to bar but left the call to +; dbg.value which still used the removed argument. + +%p_t = type i16* +%fun_t = type void (%p_t)* + +define void @foo() { + %tmp = alloca %fun_t + store %fun_t @bar, %fun_t* %tmp + ret void +} + +define internal void @bar(%p_t %p) { + call void @llvm.dbg.value(metadata %p_t %p, i64 0, metadata !4, metadata !5), !dbg !6 + ret void +} + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1) +!1 = !DIFile(filename: "test.c", directory: "") +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = distinct !DISubprogram(name: "bar", unit: !0) +!4 = !DILocalVariable(name: "p", scope: !3) +!5 = !DIExpression() +!6 = !DILocation(line: 1, column: 1, scope: !3) + +; Both the %p argument and the dbg.value should be removed from bar. +; CHECK: define internal void @bar() { +; CHECK-NEXT: ret void +; CHECK-NEXT: }