[PATCH] D34874: [ArgPromotion] Remove llvm.dbg.value on removed argument

Mikael Holmén via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 30 04:45:34 PDT 2017


uabelho created this revision.
Herald added a subscriber: wdng.

This solves PR33641.

When removing a dead argument we must also remove possibly existing calls
to llvm.dbg.value that use the removed argument.

If the calls are left, they will later on cause errors:
 "function-local metadata used in wrong function"
since the ArgumentPromotion rewrites the code by creating a new function
with the wanted signature, but the metadata is not recreated so the new
function may then erroneously use metadata from the old function.


https://reviews.llvm.org/D34874

Files:
  lib/Transforms/IPO/ArgumentPromotion.cpp
  test/Transforms/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll


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: }
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<Instruction*, 8> InstrsToRemove;
+      for (Instruction &U : BB) {
+        DbgValueInst *DI = dyn_cast<DbgValueInst>(&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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34874.104844.patch
Type: text/x-patch
Size: 2799 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170630/de1aecf5/attachment.bin>


More information about the llvm-commits mailing list