[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