[llvm] r348837 - [DeadArgElim] Fixes for dbg.values using dead arg/return values

David Stenberg via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 11 02:33:38 PST 2018


Author: dstenb
Date: Tue Dec 11 02:33:38 2018
New Revision: 348837

URL: http://llvm.org/viewvc/llvm-project?rev=348837&view=rev
Log:
[DeadArgElim] Fixes for dbg.values using dead arg/return values

Summary:
When eliminating a dead argument or return value in a function with
local linkage, all uses, including in dbg.value intrinsics, would be
replaced with null constants. This would mean that, for example for an
integer argument, the debug info would incorrectly express that the
value is 0. Instead, replace all uses with undef to indicate that the
argument/return value is optimized out.

Also, make sure that metadata uses of return values are rewritten even
if there are no non-metadata uses of the value.

As a bit of historical curiosity, the code that emitted null constants
was introduced in the initial check-in of the pass in 2003, before
'undef' values even existed in LLVM.

This fixes PR23260.

Reviewers: dblaikie, aprantl, vsk, djtodoro

Reviewed By: aprantl

Subscribers: llvm-commits

Tags: #debug-info

Differential Revision: https://reviews.llvm.org/D55513

Added:
    llvm/trunk/test/Transforms/DeadArgElim/dbginfo-update-dbgval-local.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp

Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=348837&r1=348836&r2=348837&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Tue Dec 11 02:33:38 2018
@@ -24,7 +24,6 @@
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CallSite.h"
-#include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
@@ -954,16 +953,16 @@ bool DeadArgumentEliminationPass::Remove
     ArgAttrVec.clear();
 
     Instruction *New = NewCS.getInstruction();
-    if (!Call->use_empty()) {
+    if (!Call->use_empty() || Call->isUsedByMetadata()) {
       if (New->getType() == Call->getType()) {
         // Return type not changed? Just replace users then.
         Call->replaceAllUsesWith(New);
         New->takeName(Call);
       } else if (New->getType()->isVoidTy()) {
-        // Our return value has uses, but they will get removed later on.
-        // Replace by null for now.
+        // If the return value is dead, replace any uses of it with undef
+        // (any non-debug value uses will get removed later on).
         if (!Call->getType()->isX86_MMXTy())
-          Call->replaceAllUsesWith(Constant::getNullValue(Call->getType()));
+          Call->replaceAllUsesWith(UndefValue::get(Call->getType()));
       } else {
         assert((RetTy->isStructTy() || RetTy->isArrayTy()) &&
                "Return type changed, but not into a void. The old return type"
@@ -1023,10 +1022,10 @@ bool DeadArgumentEliminationPass::Remove
       I2->takeName(&*I);
       ++I2;
     } else {
-      // If this argument is dead, replace any uses of it with null constants
-      // (these are guaranteed to become unused later on).
+      // If this argument is dead, replace any uses of it with undef
+      // (any non-debug value uses will get removed later on).
       if (!I->getType()->isX86_MMXTy())
-        I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
+        I->replaceAllUsesWith(UndefValue::get(I->getType()));
     }
 
   // If we change the return value of the function we must rewrite any return

Added: llvm/trunk/test/Transforms/DeadArgElim/dbginfo-update-dbgval-local.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadArgElim/dbginfo-update-dbgval-local.ll?rev=348837&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/DeadArgElim/dbginfo-update-dbgval-local.ll (added)
+++ llvm/trunk/test/Transforms/DeadArgElim/dbginfo-update-dbgval-local.ll Tue Dec 11 02:33:38 2018
@@ -0,0 +1,67 @@
+; RUN: opt -deadargelim -S < %s | FileCheck %s
+
+; Verify that the dbg.value intrinsics that use the dead argument and return
+; value are marked as undef to indicate that the values are optimized out.
+
+; Reproducer for PR23260.
+
+; CHECK-LABEL: define internal void @bar()
+; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata ![[LOCAL1:[0-9]+]]
+; CHECK: call void @sink()
+
+; Function Attrs: alwaysinline nounwind uwtable
+define internal i32 @bar(i32 %deadarg) #1 !dbg !10 {
+entry:
+  call void @llvm.dbg.value(metadata i32 %deadarg, metadata !15, metadata !DIExpression()), !dbg !17
+  call void @sink(), !dbg !17
+  ret i32 123, !dbg !17
+}
+
+; CHECK-LABEL: define void @foo()
+; CHECK: call void @bar()
+; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata ![[LOCAL2:[0-9]+]]
+; CHECK: call void @bar()
+
+; Function Attrs: nounwind uwtable
+define void @foo() #0 !dbg !6 {
+entry:
+  %deadret = call i32 @bar(i32 0), !dbg !9
+  call void @llvm.dbg.value(metadata i32 %deadret, metadata !16, metadata !DIExpression()), !dbg !9
+  call i32 @bar(i32 1), !dbg !9
+  ret void, !dbg !9
+}
+
+declare void @sink() local_unnamed_addr
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2
+
+attributes #0 = { nounwind uwtable }
+attributes #1 = { alwaysinline nounwind uwtable }
+attributes #2 = { nounwind readnone speculatable }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+!llvm.ident = !{!5}
+
+; CHECK: ![[LOCAL1]] = !DILocalVariable(name: "local1"
+; CHECK: ![[LOCAL2]] = !DILocalVariable(name: "local2"
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "pr23260.c", directory: "/")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{!"clang version 8.0.0"}
+!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !7, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!7 = !DISubroutineType(types: !8)
+!8 = !{null}
+!9 = !DILocation(line: 4, column: 3, scope: !6)
+!10 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !14)
+!11 = !DISubroutineType(types: !12)
+!12 = !{!13, !13}
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!14 = !{!15}
+!15 = !DILocalVariable(name: "local1", arg: 1, scope: !10, file: !1, line: 2, type: !13)
+!16 = !DILocalVariable(name: "local2", arg: 1, scope: !6, file: !1, line: 2, type: !13)
+!17 = !DILocation(line: 2, column: 52, scope: !10)




More information about the llvm-commits mailing list