<div dir="ltr">Hello Reid,<br><br>It looks like this commit broke one of our builders:<br><a href="http://lab.llvm.org:8011/builders/ubuntu-gcc7.1-werror/builds/1617">http://lab.llvm.org:8011/builders/ubuntu-gcc7.1-werror/builds/1617</a><br><br>Please have a look?<br><br>Thanks<br><br>Galina<br><br>. . . <br><br>FAILED: /usr/local/gcc-7.1/bin/g++-7.1   -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib/IR -I/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR -Iinclude -I/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/include -Wno-noexcept-type -fPIC -fvisibility-inlines-hidden -Werror -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O3  -fPIC   -UNDEBUG  -fno-exceptions -fno-rtti -MD -MT lib/IR/CMakeFiles/LLVMCore.dir/Verifier.cpp.o -MF lib/IR/CMakeFiles/LLVMCore.dir/Verifier.cpp.o.d -o lib/IR/CMakeFiles/LLVMCore.dir/Verifier.cpp.o -c /home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR/Verifier.cpp<br>/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR/Verifier.cpp: In member function ‘void {anonymous}::Verifier::visitIntrinsicCallSite(llvm::Intrinsic::ID, llvm::CallSite)’:<br>/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR/Verifier.cpp:4005:22: error: this statement may fall through [-Werror=implicit-fallthrough=]<br>     visitDbgIntrinsic("addr", cast<DbgInfoIntrinsic>(*CS.getInstruction()));<br>     ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR/Verifier.cpp:4006:3: note: here<br>   case Intrinsic::dbg_value: // llvm.dbg.value<br>   ^~~~<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 21, 2017 at 12:52 PM, Reid Kleckner via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Thu Sep 21 12:52:03 2017<br>
New Revision: 313905<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=313905&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=313905&view=rev</a><br>
Log:<br>
Re-land r313825: "[IR] Add llvm.dbg.addr, a control-dependent version of llvm.dbg.declare"<br>
<br>
The fix is to avoid invalidating our insertion point in<br>
replaceDbgDeclare:<br>
     Builder.insertDeclare(<wbr>NewAddress, DIVar, DIExpr, Loc, InsertBefore);<br>
+    if (DII == InsertBefore)<br>
+      InsertBefore = &*std::next(InsertBefore-><wbr>getIterator());<br>
     DII->eraseFromParent();<br>
<br>
I had to write a unit tests for this instead of a lit test because the<br>
use list order matters in order to trigger the bug.<br>
<br>
The reduced C test case for this was:<br>
  void useit(int*);<br>
  static inline void inlineme() {<br>
    int x[2];<br>
    useit(x);<br>
  }<br>
  void f() {<br>
    inlineme();<br>
    inlineme();<br>
  }<br>
<br>
Added:<br>
    llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr-dse.ll<br>
    llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr.ll<br>
    llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-dbg-declare.ll<br>
    llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr-inline-dse.ll<br>
    llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr.ll<br>
    llvm/trunk/test/Transforms/<wbr>SROA/dbg-addr-diamond.ll<br>
Modified:<br>
    llvm/trunk/docs/<wbr>SourceLevelDebugging.rst<br>
    llvm/trunk/include/llvm/IR/<wbr>IntrinsicInst.h<br>
    llvm/trunk/include/llvm/IR/<wbr>Intrinsics.td<br>
    llvm/trunk/include/llvm/<wbr>Transforms/Utils/Local.h<br>
    llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/<wbr>SelectionDAGBuilder.cpp<br>
    llvm/trunk/lib/IR/DIBuilder.<wbr>cpp<br>
    llvm/trunk/lib/IR/Verifier.cpp<br>
    llvm/trunk/lib/Transforms/<wbr>InstCombine/<wbr>InstructionCombining.cpp<br>
    llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp<br>
    llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp<br>
    llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp<br>
    llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-5.ll<br>
    llvm/trunk/unittests/<wbr>Transforms/Utils/CMakeLists.<wbr>txt<br>
    llvm/trunk/unittests/<wbr>Transforms/Utils/Local.cpp<br>
<br>
Modified: llvm/trunk/docs/<wbr>SourceLevelDebugging.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.rst?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/docs/<wbr>SourceLevelDebugging.rst?rev=<wbr>313905&r1=313904&r2=313905&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/docs/<wbr>SourceLevelDebugging.rst (original)<br>
+++ llvm/trunk/docs/<wbr>SourceLevelDebugging.rst Thu Sep 21 12:52:03 2017<br>
@@ -171,35 +171,64 @@ Debugger intrinsic functions<br>
 ----------------------------<br>
<br>
 LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to<br>
-provide debug information at various points in generated code.<br>
+track source local variables through optimization and code generation.<br>
<br>
-``llvm.dbg.declare``<br>
+``llvm.dbg.addr``<br>
 ^^^^^^^^^^^^^^^^^^^^<br>
<br>
 .. code-block:: llvm<br>
<br>
-  void @llvm.dbg.declare(metadata, metadata, metadata)<br>
+  void @llvm.dbg.addr(metadata, metadata, metadata)<br>
<br>
-This intrinsic provides information about a local element (e.g., variable).  The<br>
-first argument is metadata holding the alloca for the variable.  The second<br>
-argument is a `local variable <LangRef.html#dilocalvariable><wbr>`_ containing a<br>
-description of the variable.  The third argument is a `complex expression<br>
-<LangRef.html#diexpression>`_<wbr>.  An `llvm.dbg.declare` instrinsic describes the<br>
-*location* of a source variable.<br>
+This intrinsic provides information about a local element (e.g., variable).<br>
+The first argument is metadata holding the address of variable, typically a<br>
+static alloca in the function entry block.  The second argument is a<br>
+`local variable <LangRef.html#dilocalvariable><wbr>`_ containing a description of<br>
+the variable.  The third argument is a `complex expression<br>
+<LangRef.html#diexpression>`_<wbr>.  An `llvm.dbg.addr` intrinsic describes the<br>
+*address* of a source variable.<br>
<br>
 .. code-block:: llvm<br>
<br>
     %i.addr = alloca i32, align 4<br>
-    call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1, metadata !2), !dbg !3<br>
+    call void @llvm.dbg.addr(metadata i32* %i.addr, metadata !1,<br>
+                             metadata !DIExpression()), !dbg !2<br>
     !1 = !DILocalVariable(name: "i", ...) ; int i<br>
-    !2 = !DIExpression()<br>
-    !3 = !DILocation(...)<br>
+    !2 = !DILocation(...)<br>
     ...<br>
     %buffer = alloca [256 x i8], align 8<br>
     ; The address of i is buffer+64.<br>
-    call void @llvm.dbg.declare(metadata [256 x i8]* %buffer, metadata !1, metadata !2)<br>
-    !1 = !DILocalVariable(name: "i", ...) ; int i<br>
-    !2 = !DIExpression(DW_OP_plus, 64)<br>
+    call void @llvm.dbg.addr(metadata [256 x i8]* %buffer, metadata !3,<br>
+                             metadata !DIExpression(DW_OP_plus, 64)), !dbg !4<br>
+    !3 = !DILocalVariable(name: "i", ...) ; int i<br>
+    !4 = !DILocation(...)<br>
+<br>
+A frontend should generate exactly one call to ``llvm.dbg.addr`` at the point<br>
+of declaration of a source variable. Optimization passes that fully promote the<br>
+variable from memory to SSA values will replace this call with possibly<br>
+multiple calls to `llvm.dbg.value`. Passes that delete stores are effectively<br>
+partial promotion, and they will insert a mix of calls to ``llvm.dbg.value``<br>
+and ``llvm.dbg.addr`` to track the source variable value when it is available.<br>
+After optimization, there may be multiple calls to ``llvm.dbg.addr`` describing<br>
+the program points where the variables lives in memory. All calls for the same<br>
+concrete source variable must agree on the memory location.<br>
+<br>
+<br>
+``llvm.dbg.declare``<br>
+^^^^^^^^^^^^^^^^^^^^<br>
+<br>
+.. code-block:: llvm<br>
+<br>
+  void @llvm.dbg.declare(metadata, metadata, metadata)<br>
+<br>
+This intrinsic is identical to `llvm.dbg.addr`, except that there can only be<br>
+one call to `llvm.dbg.declare` for a given concrete `local variable<br>
+<LangRef.html#<wbr>dilocalvariable>`_. It is not control-dependent, meaning that if<br>
+a call to `llvm.dbg.declare` exists and has a valid location argument, that<br>
+address is considered to be the true home of the variable across its entire<br>
+lifetime. This makes it hard for optimizations to preserve accurate debug info<br>
+in the presence of ``llvm.dbg.declare``, so we are transitioning away from it,<br>
+and we plan to deprecate it in future LLVM releases.<br>
<br>
<br>
 ``llvm.dbg.value``<br>
@@ -242,6 +271,9 @@ following C fragment, for example:<br>
   8.    X = Y;<br>
   9.  }<br>
<br>
+.. FIXME: Update the following example to use llvm.dbg.addr once that is the<br>
+   default in clang.<br>
+<br>
 Compiled to LLVM, this function would be represented like this:<br>
<br>
 .. code-block:: text<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<wbr>IntrinsicInst.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicInst.h?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/IR/IntrinsicInst.h?rev=<wbr>313905&r1=313904&r2=313905&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/IR/<wbr>IntrinsicInst.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<wbr>IntrinsicInst.h Thu Sep 21 12:52:03 2017<br>
@@ -71,6 +71,12 @@ namespace llvm {<br>
     /// variable's value or its address.<br>
     Value *getVariableLocation(bool AllowNullOp = true) const;<br>
<br>
+    /// Does this describe the address of a local variable. True for dbg.addr<br>
+    /// and dbg.declare, but not dbg.value, which describes its value.<br>
+    bool isAddressOfVariable() const {<br>
+      return getIntrinsicID() != Intrinsic::dbg_value;<br>
+    }<br>
+<br>
     DILocalVariable *getVariable() const {<br>
       return cast<DILocalVariable>(<wbr>getRawVariable());<br>
     }<br>
@@ -87,11 +93,13 @@ namespace llvm {<br>
       return cast<MetadataAsValue>(<wbr>getArgOperand(2))-><wbr>getMetadata();<br>
     }<br>
<br>
-    // Methods for support type inquiry through isa, cast, and dyn_cast:<br>
+    /// \name Casting methods<br>
+    /// @{<br>
     static bool classof(const IntrinsicInst *I) {<br>
       switch (I->getIntrinsicID()) {<br>
       case Intrinsic::dbg_declare:<br>
       case Intrinsic::dbg_value:<br>
+      case Intrinsic::dbg_addr:<br>
         return true;<br>
       default: return false;<br>
       }<br>
@@ -99,6 +107,7 @@ namespace llvm {<br>
     static bool classof(const Value *V) {<br>
       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)<wbr>);<br>
     }<br>
+    /// @}<br>
   };<br>
<br>
   /// This represents the llvm.dbg.declare instruction.<br>
@@ -106,13 +115,30 @@ namespace llvm {<br>
   public:<br>
     Value *getAddress() const { return getVariableLocation(); }<br>
<br>
-    // Methods for support type inquiry through isa, cast, and dyn_cast:<br>
+    /// \name Casting methods<br>
+    /// @{<br>
     static bool classof(const IntrinsicInst *I) {<br>
       return I->getIntrinsicID() == Intrinsic::dbg_declare;<br>
     }<br>
     static bool classof(const Value *V) {<br>
       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)<wbr>);<br>
     }<br>
+    /// @}<br>
+  };<br>
+<br>
+  /// This represents the llvm.dbg.addr instruction.<br>
+  class DbgAddrIntrinsic : public DbgInfoIntrinsic {<br>
+  public:<br>
+    Value *getAddress() const { return getVariableLocation(); }<br>
+<br>
+    /// \name Casting methods<br>
+    /// @{<br>
+    static bool classof(const IntrinsicInst *I) {<br>
+      return I->getIntrinsicID() == Intrinsic::dbg_addr;<br>
+    }<br>
+    static bool classof(const Value *V) {<br>
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)<wbr>);<br>
+    }<br>
   };<br>
<br>
   /// This represents the llvm.dbg.value instruction.<br>
@@ -122,13 +148,15 @@ namespace llvm {<br>
       return getVariableLocation(/* AllowNullOp = */ false);<br>
     }<br>
<br>
-    // Methods for support type inquiry through isa, cast, and dyn_cast:<br>
+    /// \name Casting methods<br>
+    /// @{<br>
     static bool classof(const IntrinsicInst *I) {<br>
       return I->getIntrinsicID() == Intrinsic::dbg_value;<br>
     }<br>
     static bool classof(const Value *V) {<br>
       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)<wbr>);<br>
     }<br>
+    /// @}<br>
   };<br>
<br>
   /// This is the common base class for constrained floating point intrinsics.<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<wbr>Intrinsics.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/IR/Intrinsics.td?rev=<wbr>313905&r1=313904&r2=313905&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/IR/<wbr>Intrinsics.td (original)<br>
+++ llvm/trunk/include/llvm/IR/<wbr>Intrinsics.td Thu Sep 21 12:52:03 2017<br>
@@ -583,12 +583,16 @@ let IntrProperties = [IntrNoMem, IntrSpe<br>
 let IntrProperties = [IntrNoMem, IntrSpeculatable] in {<br>
   def int_dbg_declare      : Intrinsic<[],<br>
                                        [llvm_metadata_ty,<br>
-                                       llvm_metadata_ty,<br>
-                                       llvm_metadata_ty]>;<br>
+                                        llvm_metadata_ty,<br>
+                                        llvm_metadata_ty]>;<br>
   def int_dbg_value        : Intrinsic<[],<br>
                                        [llvm_metadata_ty,<br>
                                         llvm_metadata_ty,<br>
                                         llvm_metadata_ty]>;<br>
+  def int_dbg_addr         : Intrinsic<[],<br>
+                                       [llvm_metadata_ty,<br>
+                                        llvm_metadata_ty,<br>
+                                        llvm_metadata_ty]>;<br>
 }<br>
<br>
 //===------------------ Exception Handling Intrinsics--------------------<wbr>--===//<br>
<br>
Modified: llvm/trunk/include/llvm/<wbr>Transforms/Utils/Local.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/Transforms/Utils/Local.h?<wbr>rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/<wbr>Transforms/Utils/Local.h (original)<br>
+++ llvm/trunk/include/llvm/<wbr>Transforms/Utils/Local.h Thu Sep 21 12:52:03 2017<br>
@@ -16,6 +16,7 @@<br>
 #define LLVM_TRANSFORMS_UTILS_LOCAL_H<br>
<br>
 #include "llvm/ADT/SmallPtrSet.h"<br>
+#include "llvm/ADT/TinyPtrVector.h"<br>
 #include "llvm/Analysis/AliasAnalysis.<wbr>h"<br>
 #include "llvm/IR/DataLayout.h"<br>
 #include "llvm/IR/Dominators.h"<br>
@@ -32,6 +33,7 @@ class BranchInst;<br>
 class Instruction;<br>
 class CallInst;<br>
 class DbgDeclareInst;<br>
+class DbgInfoIntrinsic;<br>
 class DbgValueInst;<br>
 class StoreInst;<br>
 class LoadInst;<br>
@@ -262,26 +264,28 @@ Value *EmitGEPOffset(IRBuilderTy *Builde<br>
 ///<br>
<br>
 /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value<br>
-/// that has an associated llvm.dbg.decl intrinsic.<br>
-void ConvertDebugDeclareToDebugValu<wbr>e(DbgDeclareInst *DDI,<br>
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.<br>
+void ConvertDebugDeclareToDebugValu<wbr>e(DbgInfoIntrinsic *DII,<br>
                                      StoreInst *SI, DIBuilder &Builder);<br>
<br>
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value<br>
-/// that has an associated llvm.dbg.decl intrinsic.<br>
-void ConvertDebugDeclareToDebugValu<wbr>e(DbgDeclareInst *DDI,<br>
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.<br>
+void ConvertDebugDeclareToDebugValu<wbr>e(DbgInfoIntrinsic *DII,<br>
                                      LoadInst *LI, DIBuilder &Builder);<br>
<br>
-/// Inserts a llvm.dbg.value intrinsic after a phi of an alloca'd value<br>
-/// that has an associated llvm.dbg.decl intrinsic.<br>
-void ConvertDebugDeclareToDebugValu<wbr>e(DbgDeclareInst *DDI,<br>
+/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated<br>
+/// llvm.dbg.declare or llvm.dbg.addr intrinsic.<br>
+void ConvertDebugDeclareToDebugValu<wbr>e(DbgInfoIntrinsic *DII,<br>
                                      PHINode *LI, DIBuilder &Builder);<br>
<br>
 /// Lowers llvm.dbg.declare intrinsics into appropriate set of<br>
 /// llvm.dbg.value intrinsics.<br>
 bool LowerDbgDeclare(Function &F);<br>
<br>
-/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca, if any.<br>
-DbgDeclareInst *FindAllocaDbgDeclare(Value *V);<br>
+/// Finds all intrinsics declaring local variables as living in the memory that<br>
+/// 'V' points to. This may include a mix of dbg.declare and<br>
+/// dbg.addr intrinsics.<br>
+TinyPtrVector<<wbr>DbgInfoIntrinsic *> FindDbgAddrUses(Value *V);<br>
<br>
 /// Finds the llvm.dbg.value intrinsics describing a value.<br>
 void findDbgValues(SmallVectorImpl<<wbr>DbgValueInst *> &DbgValues, Value *V);<br>
<br>
Modified: llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/<wbr>SelectionDAGBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>CodeGen/SelectionDAG/<wbr>SelectionDAGBuilder.cpp?rev=<wbr>313905&r1=313904&r2=313905&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/<wbr>SelectionDAGBuilder.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/<wbr>SelectionDAGBuilder.cpp Thu Sep 21 12:52:03 2017<br>
@@ -5109,37 +5109,48 @@ SelectionDAGBuilder::<wbr>visitIntrinsicCall(<br>
     DAG.setRoot(CallResult.second)<wbr>;<br>
     return nullptr;<br>
   }<br>
+  case Intrinsic::dbg_addr:<br>
   case Intrinsic::dbg_declare: {<br>
-    const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);<br>
+    const DbgInfoIntrinsic &DI = cast<DbgInfoIntrinsic>(I);<br>
     DILocalVariable *Variable = DI.getVariable();<br>
     DIExpression *Expression = DI.getExpression();<br>
-    const Value *Address = DI.getAddress();<br>
     assert(Variable && "Missing variable");<br>
-    if (!Address) {<br>
-      DEBUG(dbgs() << "Dropping debug info for " << DI << "\n");<br>
-      return nullptr;<br>
-    }<br>
<br>
     // Check if address has undef value.<br>
-    if (isa<UndefValue>(Address) ||<br>
+    const Value *Address = DI.getVariableLocation();<br>
+    if (!Address || isa<UndefValue>(Address) ||<br>
         (Address->use_empty() && !isa<Argument>(Address))) {<br>
       DEBUG(dbgs() << "Dropping debug info for " << DI << "\n");<br>
       return nullptr;<br>
     }<br>
<br>
-    // Static allocas are handled more efficiently in the variable frame index<br>
-    // side table.<br>
+    bool isParameter = Variable->isParameter() || isa<Argument>(Address);<br>
+<br>
+    // Check if this variable can be described by a frame index, typically<br>
+    // either as a static alloca or a byval parameter.<br>
+    int FI = INT_MAX;<br>
     if (const auto *AI =<br>
-            dyn_cast<AllocaInst>(Address-><wbr>stripInBoundsConstantOffsets()<wbr>))<br>
-      if (AI->isStaticAlloca() && FuncInfo.StaticAllocaMap.<wbr>count(AI))<br>
-        return nullptr;<br>
+            dyn_cast<AllocaInst>(Address-><wbr>stripInBoundsConstantOffsets()<wbr>)) {<br>
+      if (AI->isStaticAlloca()) {<br>
+        auto I = FuncInfo.StaticAllocaMap.find(<wbr>AI);<br>
+        if (I != FuncInfo.StaticAllocaMap.end()<wbr>)<br>
+          FI = I->second;<br>
+      }<br>
+    } else if (const auto *Arg = dyn_cast<Argument>(<br>
+                   Address-><wbr>stripInBoundsConstantOffsets()<wbr>)) {<br>
+      FI = FuncInfo.<wbr>getArgumentFrameIndex(Arg);<br>
+    }<br>
<br>
-    // Byval arguments with frame indices were already handled after argument<br>
-    // lowering and before isel.<br>
-    if (const auto *Arg =<br>
-            dyn_cast<Argument>(Address-><wbr>stripInBoundsConstantOffsets()<wbr>))<br>
-      if (FuncInfo.<wbr>getArgumentFrameIndex(Arg) != INT_MAX)<br>
-        return nullptr;<br>
+    // llvm.dbg.addr is control dependent and always generates indirect<br>
+    // DBG_VALUE instructions. llvm.dbg.declare is handled as a frame index in<br>
+    // the MachineFunction variable table.<br>
+    if (FI != INT_MAX) {<br>
+      if (Intrinsic == Intrinsic::dbg_addr)<br>
+        DAG.AddDbgValue(DAG.<wbr>getFrameIndexDbgValue(<wbr>Variable, Expression, FI, dl,<br>
+                                                  SDNodeOrder),<br>
+                        getRoot().getNode(), isParameter);<br>
+      return nullptr;<br>
+    }<br>
<br>
     SDValue &N = NodeMap[Address];<br>
     if (!N.getNode() && isa<Argument>(Address))<br>
@@ -5150,7 +5161,6 @@ SelectionDAGBuilder::<wbr>visitIntrinsicCall(<br>
       if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Address)<wbr>)<br>
         Address = BCI->getOperand(0);<br>
       // Parameters are handled specially.<br>
-      bool isParameter = Variable->isParameter() || isa<Argument>(Address);<br>
       auto FINode = dyn_cast<FrameIndexSDNode>(N.<wbr>getNode());<br>
       if (isParameter && FINode) {<br>
         // Byval parameter. We have a frame index at this point.<br>
<br>
Modified: llvm/trunk/lib/IR/DIBuilder.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/IR/<wbr>DIBuilder.cpp?rev=313905&r1=<wbr>313904&r2=313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/IR/DIBuilder.<wbr>cpp (original)<br>
+++ llvm/trunk/lib/IR/DIBuilder.<wbr>cpp Thu Sep 21 12:52:03 2017<br>
@@ -24,6 +24,11 @@<br>
 using namespace llvm;<br>
 using namespace llvm::dwarf;<br>
<br>
+cl::opt<bool><br>
+    UseDbgAddr("use-dbg-addr",<br>
+                llvm::cl::desc("Use llvm.dbg.addr for all local variables"),<br>
+                cl::init(false));<br>
+<br>
 DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes)<br>
   : M(m), VMContext(M.getContext()), CUNode(nullptr),<br>
       DeclareFn(nullptr), ValueFn(nullptr),<br>
@@ -776,6 +781,11 @@ static Instruction *withDebugLoc(Instruc<br>
   return I;<br>
 }<br>
<br>
+static Function *getDeclareIntrin(Module &M) {<br>
+  return Intrinsic::getDeclaration(&M, UseDbgAddr ? Intrinsic::dbg_addr<br>
+                                                  : Intrinsic::dbg_declare);<br>
+}<br>
+<br>
 Instruction *DIBuilder::insertDeclare(<wbr>Value *Storage, DILocalVariable *VarInfo,<br>
                                       DIExpression *Expr, const DILocation *DL,<br>
                                       Instruction *InsertBefore) {<br>
@@ -785,7 +795,7 @@ Instruction *DIBuilder::insertDeclare(Va<br>
              VarInfo->getScope()-><wbr>getSubprogram() &&<br>
          "Expected matching subprograms");<br>
   if (!DeclareFn)<br>
-    DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);<br>
+    DeclareFn = getDeclareIntrin(M);<br>
<br>
   trackIfUnresolved(VarInfo);<br>
   trackIfUnresolved(Expr);<br>
@@ -804,7 +814,7 @@ Instruction *DIBuilder::insertDeclare(Va<br>
              VarInfo->getScope()-><wbr>getSubprogram() &&<br>
          "Expected matching subprograms");<br>
   if (!DeclareFn)<br>
-    DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);<br>
+    DeclareFn = getDeclareIntrin(M);<br>
<br>
   trackIfUnresolved(VarInfo);<br>
   trackIfUnresolved(Expr);<br>
<br>
Modified: llvm/trunk/lib/IR/Verifier.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/IR/<wbr>Verifier.cpp?rev=313905&r1=<wbr>313904&r2=313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/IR/Verifier.cpp (original)<br>
+++ llvm/trunk/lib/IR/Verifier.cpp Thu Sep 21 12:52:03 2017<br>
@@ -4001,6 +4001,8 @@ void Verifier::<wbr>visitIntrinsicCallSite(In<br>
            "invalid llvm.dbg.declare intrinsic call 1", CS);<br>
     visitDbgIntrinsic("declare", cast<DbgInfoIntrinsic>(*CS.<wbr>getInstruction()));<br>
     break;<br>
+  case Intrinsic::dbg_addr: // llvm.dbg.addr<br>
+    visitDbgIntrinsic("addr", cast<DbgInfoIntrinsic>(*CS.<wbr>getInstruction()));<br>
   case Intrinsic::dbg_value: // llvm.dbg.value<br>
     visitDbgIntrinsic("value", cast<DbgInfoIntrinsic>(*CS.<wbr>getInstruction()));<br>
     break;<br>
<br>
Modified: llvm/trunk/lib/Transforms/<wbr>InstCombine/<wbr>InstructionCombining.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/InstCombine/<wbr>InstructionCombining.cpp?rev=<wbr>313905&r1=313904&r2=313905&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/<wbr>InstCombine/<wbr>InstructionCombining.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/<wbr>InstCombine/<wbr>InstructionCombining.cpp Thu Sep 21 12:52:03 2017<br>
@@ -2106,10 +2106,10 @@ Instruction *InstCombiner::visitAllocSit<br>
<br>
   // If we are removing an alloca with a dbg.declare, insert dbg.value calls<br>
   // before each store.<br>
-  DbgDeclareInst *DDI = nullptr;<br>
+  TinyPtrVector<DbgInfoIntrinsic *> DIIs;<br>
   std::unique_ptr<DIBuilder> DIB;<br>
   if (isa<AllocaInst>(MI)) {<br>
-    DDI = FindAllocaDbgDeclare(&MI);<br>
+    DIIs = FindDbgAddrUses(&MI);<br>
     DIB.reset(new DIBuilder(*MI.getModule(), /*AllowUnresolved=*/false));<br>
   }<br>
<br>
@@ -2145,8 +2145,9 @@ Instruction *InstCombiner::visitAllocSit<br>
       } else if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I) ||<br>
                  isa<AddrSpaceCastInst>(I)) {<br>
         replaceInstUsesWith(*I, UndefValue::get(I->getType()))<wbr>;<br>
-      } else if (DDI && isa<StoreInst>(I)) {<br>
-        ConvertDebugDeclareToDebugValu<wbr>e(DDI, cast<StoreInst>(I), *DIB);<br>
+      } else if (auto *SI = dyn_cast<StoreInst>(I)) {<br>
+        for (auto *DII : DIIs)<br>
+          ConvertDebugDeclareToDebugValu<wbr>e(DII, SI, *DIB);<br>
       }<br>
       eraseInstFromFunction(*I);<br>
     }<br>
@@ -2159,8 +2160,8 @@ Instruction *InstCombiner::visitAllocSit<br>
                          None, "", II->getParent());<br>
     }<br>
<br>
-    if (DDI)<br>
-      eraseInstFromFunction(*DDI);<br>
+    for (auto *DII : DIIs)<br>
+      eraseInstFromFunction(*DII);<br>
<br>
     return eraseInstFromFunction(MI);<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/Scalar/SROA.cpp?<wbr>rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/<wbr>Scalar/SROA.cpp Thu Sep 21 12:52:03 2017<br>
@@ -4102,9 +4102,10 @@ bool SROA::splitAlloca(AllocaInst &AI, A<br>
<br>
   // Migrate debug information from the old alloca to the new alloca(s)<br>
   // and the individual partitions.<br>
-  if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(&AI)) {<br>
-    auto *Var = DbgDecl->getVariable();<br>
-    auto *Expr = DbgDecl->getExpression();<br>
+  TinyPtrVector<DbgInfoIntrinsic *> DbgDeclares = FindDbgAddrUses(&AI);<br>
+  if (!DbgDeclares.empty()) {<br>
+    auto *Var = DbgDeclares.front()-><wbr>getVariable();<br>
+    auto *Expr = DbgDeclares.front()-><wbr>getExpression();<br>
     DIBuilder DIB(*AI.getModule(), /*AllowUnresolved*/ false);<br>
     uint64_t AllocaSize = DL.getTypeSizeInBits(AI.<wbr>getAllocatedType());<br>
     for (auto Fragment : Fragments) {<br>
@@ -4136,12 +4137,12 @@ bool SROA::splitAlloca(AllocaInst &AI, A<br>
             DIExpression::<wbr>createFragmentExpression(Expr, Start, Size);<br>
       }<br>
<br>
-      // Remove any existing dbg.declare intrinsic describing the same alloca.<br>
-      if (DbgDeclareInst *OldDDI = FindAllocaDbgDeclare(Fragment.<wbr>Alloca))<br>
-        OldDDI->eraseFromParent();<br>
+      // Remove any existing intrinsics describing the same alloca.<br>
+      for (DbgInfoIntrinsic *OldDII : FindDbgAddrUses(Fragment.<wbr>Alloca))<br>
+        OldDII->eraseFromParent();<br>
<br>
       DIB.insertDeclare(Fragment.<wbr>Alloca, Var, FragmentExpr,<br>
-                        DbgDecl->getDebugLoc(), &AI);<br>
+                        DbgDeclares.front()-><wbr>getDebugLoc(), &AI);<br>
     }<br>
   }<br>
   return Changed;<br>
@@ -4246,6 +4247,15 @@ void SROA::deleteDeadInstructions(<br>
     Instruction *I = DeadInsts.pop_back_val();<br>
     DEBUG(dbgs() << "Deleting dead instruction: " << *I << "\n");<br>
<br>
+    // If the instruction is an alloca, find the possible dbg.declare connected<br>
+    // to it, and remove it too. We must do this before calling RAUW or we will<br>
+    // not be able to find it.<br>
+    if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {<br>
+      DeletedAllocas.insert(AI);<br>
+      for (DbgInfoIntrinsic *OldDII : FindDbgAddrUses(AI))<br>
+        OldDII->eraseFromParent();<br>
+    }<br>
+<br>
     I->replaceAllUsesWith(<wbr>UndefValue::get(I->getType()))<wbr>;<br>
<br>
     for (Use &Operand : I->operands())<br>
@@ -4256,12 +4266,6 @@ void SROA::deleteDeadInstructions(<br>
           DeadInsts.insert(U);<br>
       }<br>
<br>
-    if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {<br>
-      DeletedAllocas.insert(AI);<br>
-      if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(AI))<br>
-        DbgDecl->eraseFromParent();<br>
-    }<br>
-<br>
     ++NumDeleted;<br>
     I->eraseFromParent();<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/Utils/Local.cpp?<wbr>rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/<wbr>Utils/Local.cpp Thu Sep 21 12:52:03 2017<br>
@@ -1098,12 +1098,13 @@ static bool PhiHasDebugValue(DILocalVari<br>
 }<br>
<br>
 /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value<br>
-/// that has an associated llvm.dbg.decl intrinsic.<br>
-void llvm::<wbr>ConvertDebugDeclareToDebugValu<wbr>e(DbgDeclareInst *DDI,<br>
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.<br>
+void llvm::<wbr>ConvertDebugDeclareToDebugValu<wbr>e(DbgInfoIntrinsic *DII,<br>
                                            StoreInst *SI, DIBuilder &Builder) {<br>
-  auto *DIVar = DDI->getVariable();<br>
+  assert(DII-><wbr>isAddressOfVariable());<br>
+  auto *DIVar = DII->getVariable();<br>
   assert(DIVar && "Missing variable");<br>
-  auto *DIExpr = DDI->getExpression();<br>
+  auto *DIExpr = DII->getExpression();<br>
   Value *DV = SI->getOperand(0);<br>
<br>
   // If an argument is zero extended then use argument directly. The ZExt<br>
@@ -1114,7 +1115,7 @@ void llvm::<wbr>ConvertDebugDeclareToDebugVal<br>
   if (SExtInst *SExt = dyn_cast<SExtInst>(SI-><wbr>getOperand(0)))<br>
     ExtendedArg = dyn_cast<Argument>(SExt-><wbr>getOperand(0));<br>
   if (ExtendedArg) {<br>
-    // If this DDI was already describing only a fragment of a variable, ensure<br>
+    // If this DII was already describing only a fragment of a variable, ensure<br>
     // that fragment is appropriately narrowed here.<br>
     // But if a fragment wasn't used, describe the value as the original<br>
     // argument (rather than the zext or sext) so that it remains described even<br>
@@ -1127,23 +1128,23 @@ void llvm::<wbr>ConvertDebugDeclareToDebugVal<br>
                                    DIExpr->elements_end() - 3);<br>
       Ops.push_back(dwarf::DW_OP_<wbr>LLVM_fragment);<br>
       Ops.push_back(FragmentOffset);<br>
-      const DataLayout &DL = DDI->getModule()-><wbr>getDataLayout();<br>
+      const DataLayout &DL = DII->getModule()-><wbr>getDataLayout();<br>
       Ops.push_back(DL.<wbr>getTypeSizeInBits(ExtendedArg-<wbr>>getType()));<br>
       DIExpr = Builder.createExpression(Ops);<br>
     }<br>
     DV = ExtendedArg;<br>
   }<br>
   if (!LdStHasDebugValue(DIVar, DIExpr, SI))<br>
-    Builder.<wbr>insertDbgValueIntrinsic(DV, DIVar, DIExpr, DDI->getDebugLoc(),<br>
+    Builder.<wbr>insertDbgValueIntrinsic(DV, DIVar, DIExpr, DII->getDebugLoc(),<br>
                                     SI);<br>
 }<br>
<br>
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value<br>
-/// that has an associated llvm.dbg.decl intrinsic.<br>
-void llvm::<wbr>ConvertDebugDeclareToDebugValu<wbr>e(DbgDeclareInst *DDI,<br>
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.<br>
+void llvm::<wbr>ConvertDebugDeclareToDebugValu<wbr>e(DbgInfoIntrinsic *DII,<br>
                                            LoadInst *LI, DIBuilder &Builder) {<br>
-  auto *DIVar = DDI->getVariable();<br>
-  auto *DIExpr = DDI->getExpression();<br>
+  auto *DIVar = DII->getVariable();<br>
+  auto *DIExpr = DII->getExpression();<br>
   assert(DIVar && "Missing variable");<br>
<br>
   if (LdStHasDebugValue(DIVar, DIExpr, LI))<br>
@@ -1154,16 +1155,16 @@ void llvm::<wbr>ConvertDebugDeclareToDebugVal<br>
   // preferable to keep tracking both the loaded value and the original<br>
   // address in case the alloca can not be elided.<br>
   Instruction *DbgValue = Builder.<wbr>insertDbgValueIntrinsic(<br>
-      LI, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr);<br>
+      LI, DIVar, DIExpr, DII->getDebugLoc(), (Instruction *)nullptr);<br>
   DbgValue->insertAfter(LI);<br>
 }<br>
<br>
-/// Inserts a llvm.dbg.value intrinsic after a phi<br>
-/// that has an associated llvm.dbg.decl intrinsic.<br>
-void llvm::<wbr>ConvertDebugDeclareToDebugValu<wbr>e(DbgDeclareInst *DDI,<br>
+/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated<br>
+/// llvm.dbg.declare or llvm.dbg.addr intrinsic.<br>
+void llvm::<wbr>ConvertDebugDeclareToDebugValu<wbr>e(DbgInfoIntrinsic *DII,<br>
                                            PHINode *APN, DIBuilder &Builder) {<br>
-  auto *DIVar = DDI->getVariable();<br>
-  auto *DIExpr = DDI->getExpression();<br>
+  auto *DIVar = DII->getVariable();<br>
+  auto *DIExpr = DII->getExpression();<br>
   assert(DIVar && "Missing variable");<br>
<br>
   if (PhiHasDebugValue(DIVar, DIExpr, APN))<br>
@@ -1176,7 +1177,7 @@ void llvm::<wbr>ConvertDebugDeclareToDebugVal<br>
   // insertion point.<br>
   // FIXME: Insert dbg.value markers in the successors when appropriate.<br>
   if (InsertionPt != BB->end())<br>
-    Builder.<wbr>insertDbgValueIntrinsic(APN, DIVar, DIExpr, DDI->getDebugLoc(),<br>
+    Builder.<wbr>insertDbgValueIntrinsic(APN, DIVar, DIExpr, DII->getDebugLoc(),<br>
                                     &*InsertionPt);<br>
 }<br>
<br>
@@ -1231,16 +1232,25 @@ bool llvm::LowerDbgDeclare(Function &F)<br>
   return true;<br>
 }<br>
<br>
-/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic describing the<br>
-/// alloca 'V', if any.<br>
-DbgDeclareInst *llvm::FindAllocaDbgDeclare(<wbr>Value *V) {<br>
-  if (auto *L = LocalAsMetadata::getIfExists(<wbr>V))<br>
-    if (auto *MDV = MetadataAsValue::getIfExists(<wbr>V->getContext(), L))<br>
-      for (User *U : MDV->users())<br>
-        if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(U))<br>
-          return DDI;<br>
+/// Finds all intrinsics declaring local variables as living in the memory that<br>
+/// 'V' points to. This may include a mix of dbg.declare and<br>
+/// dbg.addr intrinsics.<br>
+TinyPtrVector<<wbr>DbgInfoIntrinsic *> llvm::FindDbgAddrUses(Value *V) {<br>
+  auto *L = LocalAsMetadata::getIfExists(<wbr>V);<br>
+  if (!L)<br>
+    return {};<br>
+  auto *MDV = MetadataAsValue::getIfExists(<wbr>V->getContext(), L);<br>
+  if (!MDV)<br>
+    return {};<br>
+<br>
+  TinyPtrVector<DbgInfoIntrinsic *> Declares;<br>
+  for (User *U : MDV->users()) {<br>
+    if (auto *DII = dyn_cast<DbgInfoIntrinsic>(U))<br>
+      if (DII->isAddressOfVariable())<br>
+        Declares.push_back(DII);<br>
+  }<br>
<br>
-  return nullptr;<br>
+  return Declares;<br>
 }<br>
<br>
 void llvm::findDbgValues(<wbr>SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {<br>
@@ -1251,23 +1261,24 @@ void llvm::findDbgValues(<wbr>SmallVectorImpl<br>
           DbgValues.push_back(DVI);<br>
 }<br>
<br>
-<br>
 bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,<br>
                              Instruction *InsertBefore, DIBuilder &Builder,<br>
                              bool Deref, int Offset) {<br>
-  DbgDeclareInst *DDI = FindAllocaDbgDeclare(Address);<br>
-  if (!DDI)<br>
-    return false;<br>
-  DebugLoc Loc = DDI->getDebugLoc();<br>
-  auto *DIVar = DDI->getVariable();<br>
-  auto *DIExpr = DDI->getExpression();<br>
-  assert(DIVar && "Missing variable");<br>
-  DIExpr = DIExpression::prepend(DIExpr, Deref, Offset);<br>
-  // Insert llvm.dbg.declare immediately after the original alloca, and remove<br>
-  // old llvm.dbg.declare.<br>
-  Builder.insertDeclare(<wbr>NewAddress, DIVar, DIExpr, Loc, InsertBefore);<br>
-  DDI->eraseFromParent();<br>
-  return true;<br>
+  auto DbgAddrs = FindDbgAddrUses(Address);<br>
+  for (DbgInfoIntrinsic *DII : DbgAddrs) {<br>
+    DebugLoc Loc = DII->getDebugLoc();<br>
+    auto *DIVar = DII->getVariable();<br>
+    auto *DIExpr = DII->getExpression();<br>
+    assert(DIVar && "Missing variable");<br>
+    DIExpr = DIExpression::prepend(DIExpr, Deref, Offset);<br>
+    // Insert llvm.dbg.declare immediately after InsertBefore, and remove old<br>
+    // llvm.dbg.declare.<br>
+    Builder.insertDeclare(<wbr>NewAddress, DIVar, DIExpr, Loc, InsertBefore);<br>
+    if (DII == InsertBefore)<br>
+      InsertBefore = &*std::next(InsertBefore-><wbr>getIterator());<br>
+    DII->eraseFromParent();<br>
+  }<br>
+  return !DbgAddrs.empty();<br>
 }<br>
<br>
 bool llvm::<wbr>replaceDbgDeclareForAlloca(<wbr>AllocaInst *AI, Value *NewAllocaAddress,<br>
<br>
Modified: llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/Utils/<wbr>PromoteMemoryToRegister.cpp?<wbr>rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp (original)<br>
+++ llvm/trunk/lib/Transforms/<wbr>Utils/PromoteMemoryToRegister.<wbr>cpp Thu Sep 21 12:52:03 2017<br>
@@ -103,7 +103,7 @@ struct AllocaInfo {<br>
   bool OnlyUsedInOneBlock;<br>
<br>
   Value *AllocaPointerVal;<br>
-  DbgDeclareInst *DbgDeclare;<br>
+  TinyPtrVector<<wbr>DbgInfoIntrinsic*> DbgDeclares;<br>
<br>
   void clear() {<br>
     DefiningBlocks.clear();<br>
@@ -112,7 +112,7 @@ struct AllocaInfo {<br>
     OnlyBlock = nullptr;<br>
     OnlyUsedInOneBlock = true;<br>
     AllocaPointerVal = nullptr;<br>
-    DbgDeclare = nullptr;<br>
+    DbgDeclares.clear();<br>
   }<br>
<br>
   /// Scan the uses of the specified alloca, filling in the AllocaInfo used<br>
@@ -147,7 +147,7 @@ struct AllocaInfo {<br>
       }<br>
     }<br>
<br>
-    DbgDeclare = FindAllocaDbgDeclare(AI);<br>
+    DbgDeclares = FindDbgAddrUses(AI);<br>
   }<br>
 };<br>
<br>
@@ -245,7 +245,7 @@ struct PromoteMem2Reg {<br>
   /// For each alloca, we keep track of the dbg.declare intrinsic that<br>
   /// describes it, if any, so that we can convert it to a dbg.value<br>
   /// intrinsic if the alloca gets promoted.<br>
-  SmallVector<DbgDeclareInst *, 8> AllocaDbgDeclares;<br>
+  SmallVector<TinyPtrVector<<wbr>DbgInfoIntrinsic *>, 8> AllocaDbgDeclares;<br>
<br>
   /// The set of basic blocks the renamer has already visited.<br>
   ///<br>
@@ -409,11 +409,11 @@ static bool rewriteSingleStoreAlloca(All<br>
<br>
   // Record debuginfo for the store and remove the declaration's<br>
   // debuginfo.<br>
-  if (DbgDeclareInst *DDI = Info.DbgDeclare) {<br>
+  for (DbgInfoIntrinsic *DII : Info.DbgDeclares) {<br>
     DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);<br>
-    ConvertDebugDeclareToDebugValu<wbr>e(DDI, Info.OnlyStore, DIB);<br>
-    DDI->eraseFromParent();<br>
-    LBI.deleteValue(DDI);<br>
+    ConvertDebugDeclareToDebugValu<wbr>e(DII, Info.OnlyStore, DIB);<br>
+    DII->eraseFromParent();<br>
+    LBI.deleteValue(DII);<br>
   }<br>
   // Remove the (now dead) store and alloca.<br>
   Info.OnlyStore-><wbr>eraseFromParent();<br>
@@ -505,9 +505,9 @@ static bool promoteSingleBlockAlloca(All<br>
   while (!AI->use_empty()) {<br>
     StoreInst *SI = cast<StoreInst>(AI->user_back(<wbr>));<br>
     // Record debuginfo for the store before removing it.<br>
-    if (DbgDeclareInst *DDI = Info.DbgDeclare) {<br>
+    for (DbgInfoIntrinsic *DII : Info.DbgDeclares) {<br>
       DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);<br>
-      ConvertDebugDeclareToDebugValu<wbr>e(DDI, SI, DIB);<br>
+      ConvertDebugDeclareToDebugValu<wbr>e(DII, SI, DIB);<br>
     }<br>
     SI->eraseFromParent();<br>
     LBI.deleteValue(SI);<br>
@@ -517,9 +517,9 @@ static bool promoteSingleBlockAlloca(All<br>
   LBI.deleteValue(AI);<br>
<br>
   // The alloca's debuginfo can be removed as well.<br>
-  if (DbgDeclareInst *DDI = Info.DbgDeclare) {<br>
-    DDI->eraseFromParent();<br>
-    LBI.deleteValue(DDI);<br>
+  for (DbgInfoIntrinsic *DII : Info.DbgDeclares) {<br>
+    DII->eraseFromParent();<br>
+    LBI.deleteValue(DII);<br>
   }<br>
<br>
   ++NumLocalPromoted;<br>
@@ -587,8 +587,8 @@ void PromoteMem2Reg::run() {<br>
     }<br>
<br>
     // Remember the dbg.declare intrinsic describing this alloca, if any.<br>
-    if (Info.DbgDeclare)<br>
-      AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;<br>
+    if (!Info.DbgDeclares.empty())<br>
+      AllocaDbgDeclares[AllocaNum] = Info.DbgDeclares;<br>
<br>
     // Keep the reverse mapping of the 'Allocas' array for the rename pass.<br>
     AllocaLookup[Allocas[<wbr>AllocaNum]] = AllocaNum;<br>
@@ -666,9 +666,9 @@ void PromoteMem2Reg::run() {<br>
   }<br>
<br>
   // Remove alloca's dbg.declare instrinsics from the function.<br>
-  for (DbgDeclareInst *DDI : AllocaDbgDeclares)<br>
-    if (DDI)<br>
-      DDI->eraseFromParent();<br>
+  for (auto &Declares : AllocaDbgDeclares)<br>
+    for (auto *DII : Declares)<br>
+      DII->eraseFromParent();<br>
<br>
   // Loop over all of the PHI nodes and see if there are any that we can get<br>
   // rid of because they merge all of the same incoming values.  This can<br>
@@ -895,8 +895,8 @@ NextIteration:<br>
<br>
         // The currently active variable for this block is now the PHI.<br>
         IncomingVals[AllocaNo] = APN;<br>
-        if (DbgDeclareInst *DDI = AllocaDbgDeclares[AllocaNo])<br>
-          ConvertDebugDeclareToDebugValu<wbr>e(DDI, APN, DIB);<br>
+        for (DbgInfoIntrinsic *DII : AllocaDbgDeclares[AllocaNo])<br>
+          ConvertDebugDeclareToDebugValu<wbr>e(DII, APN, DIB);<br>
<br>
         // Get the next phi node.<br>
         ++PNI;<br>
@@ -952,8 +952,8 @@ NextIteration:<br>
       // what value were we writing?<br>
       IncomingVals[ai->second] = SI->getOperand(0);<br>
       // Record debuginfo for the store before removing it.<br>
-      if (DbgDeclareInst *DDI = AllocaDbgDeclares[ai->second])<br>
-        ConvertDebugDeclareToDebugValu<wbr>e(DDI, SI, DIB);<br>
+      for (DbgInfoIntrinsic *DII : AllocaDbgDeclares[ai->second])<br>
+        ConvertDebugDeclareToDebugValu<wbr>e(DII, SI, DIB);<br>
       BB->getInstList().erase(SI);<br>
     }<br>
   }<br>
<br>
Added: llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr-dse.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dbg-addr-dse.ll?rev=313905&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>DebugInfo/X86/dbg-addr-dse.ll?<wbr>rev=313905&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr-dse.ll (added)<br>
+++ llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr-dse.ll Thu Sep 21 12:52:03 2017<br>
@@ -0,0 +1,100 @@<br>
+; RUN: llc %s -o %t.s<br>
+; RUN: llvm-mc %t.s -filetype=obj -triple=x86_64-windows-msvc -o %t.o<br>
+; RUN: FileCheck %s < %t.s --check-prefix=ASM<br>
+; RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=DWARF<br>
+<br>
+; In this example, the variable lives mostly in memory, but at the point of the<br>
+; assignment to global, it lives nowhere, and is described as the constant<br>
+; value 1.<br>
+<br>
+; C source:<br>
+;<br>
+; void escape(int *);<br>
+; extern int global;<br>
+; void f(int x) {<br>
+;   escape(&x);<br>
+;   x = 1; // DSE should delete and insert dbg.value(i32 1)<br>
+;   global = x;<br>
+;   x = 2; // DSE should insert dbg.addr<br>
+;   escape(&x);<br>
+; }<br>
+<br>
+; ModuleID = 'dse.c'<br>
+source_filename = "dse.c"<br>
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64-pc-windows-msvc19.0.<wbr>24215"<br>
+<br>
+declare void @llvm.dbg.addr(metadata, metadata, metadata) #2<br>
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2<br>
+declare void @escape(i32*)<br>
+<br>
+@global = external global i32, align 4<br>
+<br>
+; Function Attrs: nounwind uwtable<br>
+define void @f(i32 %x) #0 !dbg !8 {<br>
+entry:<br>
+  %x.addr = alloca i32, align 4<br>
+  store i32 %x, i32* %x.addr, align 4<br>
+  call void @llvm.dbg.addr(metadata i32* %x.addr, metadata !13, metadata !DIExpression()), !dbg !18<br>
+  call void @escape(i32* %x.addr), !dbg !19<br>
+  call void @llvm.dbg.value(metadata i32 1, metadata !13, metadata !DIExpression()), !dbg !20<br>
+  store i32 1, i32* @global, align 4, !dbg !22<br>
+  call void @llvm.dbg.addr(metadata i32* %x.addr, metadata !13, metadata !DIExpression()), !dbg !23<br>
+  store i32 2, i32* %x.addr, align 4, !dbg !23<br>
+  call void @escape(i32* %x.addr), !dbg !24<br>
+  ret void, !dbg !25<br>
+}<br>
+<br>
+; ASM-LABEL: f: # @f<br>
+; ASM: movl    %ecx, [[OFF_X:[0-9]+]](%rsp)<br>
+; ASM: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]]] [%RSP+0]<br>
+; ASM: callq   escape<br>
+; ASM: #DEBUG_VALUE: f:x <- 1<br>
+; ASM: movl    $1, global(%rip)<br>
+; FIXME: Needs a fix to LiveDebugVariables<br>
+; ASMX: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]]] [%RSP+0]<br>
+; ASM: movl    $2, [[OFF_X]](%rsp)<br>
+; ASM: callq   escape<br>
+; ASM: retq<br>
+<br>
+; DWARF:      DW_TAG_formal_parameter<br>
+; DWARF-NEXT:   DW_AT_location        (0x00000000<br>
+; DWARF-NEXT:      {{[^:]*}}: DW_OP_breg7 RSP+{{[0-9]+}}<br>
+; DWARF-NEXT:      {{[^:]*}}: DW_OP_consts +1, DW_OP_stack_value<br>
+; FIXME: Needs a fix to LiveDebugVariables<br>
+; DWARFX-NEXT:      {{[^:]*}}: DW_OP_breg7 RSP+{{[0-9]+}})<br>
+; DWARF-NEXT:   DW_AT_name    ("x")<br>
+<br>
+attributes #0 = { nounwind uwtable }<br>
+attributes #2 = { nounwind readnone speculatable }<br>
+<br>
+!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!3, !4, !5, !6}<br>
+!llvm.ident = !{!7}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+!1 = !DIFile(filename: "dse.c", directory: "C:\5Csrc\5Cllvm-project\<wbr>5Cbuild")<br>
+!2 = !{}<br>
+!3 = !{i32 2, !"Dwarf Version", i32 4}<br>
+!4 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!5 = !{i32 1, !"wchar_size", i32 2}<br>
+!6 = !{i32 7, !"PIC Level", i32 2}<br>
+!7 = !{!"clang version 6.0.0 "}<br>
+!8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)<br>
+!9 = !DISubroutineType(types: !10)<br>
+!10 = !{null, !11}<br>
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!12 = !{!13}<br>
+!13 = !DILocalVariable(name: "x", arg: 1, scope: !8, file: !1, line: 3, type: !11)<br>
+!14 = !{!15, !15, i64 0}<br>
+!15 = !{!"int", !16, i64 0}<br>
+!16 = !{!"omnipotent char", !17, i64 0}<br>
+!17 = !{!"Simple C/C++ TBAA"}<br>
+!18 = !DILocation(line: 3, column: 12, scope: !8)<br>
+!19 = !DILocation(line: 4, column: 3, scope: !8)<br>
+!20 = !DILocation(line: 5, column: 5, scope: !8)<br>
+!21 = !DILocation(line: 6, column: 12, scope: !8)<br>
+!22 = !DILocation(line: 6, column: 10, scope: !8)<br>
+!23 = !DILocation(line: 7, column: 5, scope: !8)<br>
+!24 = !DILocation(line: 8, column: 3, scope: !8)<br>
+!25 = !DILocation(line: 9, column: 1, scope: !8)<br>
<br>
Added: llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dbg-addr.ll?rev=313905&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>DebugInfo/X86/dbg-addr.ll?rev=<wbr>313905&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr.ll (added)<br>
+++ llvm/trunk/test/DebugInfo/X86/<wbr>dbg-addr.ll Thu Sep 21 12:52:03 2017<br>
@@ -0,0 +1,67 @@<br>
+; RUN: llc %s -o %t.s<br>
+; RUN: llvm-mc -triple x86_64--linux %t.s -filetype=obj -o %t.o<br>
+; RUN: FileCheck < %t.s %s<br>
+; RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=DWARF<br>
+<br>
+; Unlike dbg.declare, dbg.addr should be lowered to DBG_VALUE instructions. It<br>
+; is control-dependent.<br>
+<br>
+; CHECK-LABEL: use_dbg_addr:<br>
+; CHECK: #DEBUG_VALUE: use_dbg_addr:o <- [%RSP+0]<br>
+<br>
+; FIXME: Avoid the use of a single-location location list and use<br>
+; DW_AT_start_offset instead.<br>
+<br>
+; DWARF: DW_TAG_variable<br>
+; DWARF-NEXT:              DW_AT_location (0x00000000<br>
+; DWARF-NEXT:                          0x{{.*}} - 0x{{.*}}: DW_OP_breg7 RSP+0)<br>
+; DWARF-NEXT:              DW_AT_name ("o")<br>
+<br>
+<br>
+; ModuleID = 't.c'<br>
+source_filename = "t.c"<br>
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64--linux"<br>
+<br>
+%struct.Foo = type { i32 }<br>
+<br>
+; Function Attrs: noinline nounwind uwtable<br>
+define void @use_dbg_addr() #0 !dbg !7 {<br>
+entry:<br>
+  %o = alloca %struct.Foo, align 4<br>
+  call void @llvm.dbg.addr(metadata %struct.Foo* %o, metadata !10, metadata !15), !dbg !16<br>
+  call void @escape_foo(%struct.Foo* %o), !dbg !17<br>
+  ret void, !dbg !18<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone speculatable<br>
+declare void @llvm.dbg.addr(metadata, metadata, metadata) #1<br>
+<br>
+declare void @escape_foo(%struct.Foo*)<br>
+<br>
+attributes #0 = { noinline nounwind uwtable }<br>
+attributes #1 = { nounwind readnone speculatable }<br>
+<br>
+!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!3, !4, !5}<br>
+!llvm.ident = !{!6}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\<wbr>5Cbuild")<br>
+!2 = !{}<br>
+!3 = !{i32 2, !"Dwarf Version", i32 4}<br>
+!4 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!5 = !{i32 1, !"wchar_size", i32 4}<br>
+!6 = !{!"clang version 6.0.0 "}<br>
+!7 = distinct !DISubprogram(name: "use_dbg_addr", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)<br>
+!8 = !DISubroutineType(types: !9)<br>
+!9 = !{null}<br>
+!10 = !DILocalVariable(name: "o", scope: !7, file: !1, line: 4, type: !11)<br>
+!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !1, line: 1, size: 32, elements: !12)<br>
+!12 = !{!13}<br>
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !11, file: !1, line: 1, baseType: !14, size: 32)<br>
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!15 = !DIExpression()<br>
+!16 = !DILocation(line: 4, column: 14, scope: !7)<br>
+!17 = !DILocation(line: 5, column: 3, scope: !7)<br>
+!18 = !DILocation(line: 6, column: 1, scope: !7)<br>
<br>
Modified: llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-5.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sroasplit-5.ll?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>DebugInfo/X86/sroasplit-5.ll?<wbr>rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-5.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-5.ll Thu Sep 21 12:52:03 2017<br>
@@ -20,10 +20,10 @@ target triple = "x86_64-unknown-linux-gn<br>
 ;<br>
 ; There should be no debug info for the padding.<br>
 ; CHECK-NOT: DW_OP_LLVM_fragment, 56<br>
-; CHECK: DIExpression(DW_OP_LLVM_<wbr>fragment, 32, 24)<br>
-; CHECK-NOT: DW_OP_LLVM_fragment, 56<br>
 ; CHECK: DIExpression(DW_OP_LLVM_<wbr>fragment, 0, 32)<br>
 ; CHECK-NOT: DW_OP_LLVM_fragment, 56<br>
+; CHECK: DIExpression(DW_OP_LLVM_<wbr>fragment, 32, 24)<br>
+; CHECK-NOT: DW_OP_LLVM_fragment, 56<br>
 %struct.prog_src_register = type { i32, i24 }<br>
<br>
 ; Function Attrs: nounwind<br>
<br>
Added: llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-dbg-declare.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sroasplit-dbg-declare.ll?rev=313905&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>DebugInfo/X86/sroasplit-dbg-<wbr>declare.ll?rev=313905&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-dbg-declare.ll (added)<br>
+++ llvm/trunk/test/DebugInfo/X86/<wbr>sroasplit-dbg-declare.ll Thu Sep 21 12:52:03 2017<br>
@@ -0,0 +1,59 @@<br>
+; RUN: opt -S -sroa -o - %s | FileCheck %s<br>
+<br>
+; SROA should split the alloca in two new ones, each with its own dbg.declare.<br>
+; The original alloca and dbg.declare should be removed.<br>
+<br>
+define void @f1() {<br>
+entry:<br>
+  %0 = alloca [9 x i32]<br>
+  call void @llvm.dbg.declare(metadata [9 x i32]* %0, metadata !11, metadata !DIExpression()), !dbg !17<br>
+  %1 = bitcast [9 x i32]* %0 to i8*<br>
+  call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 36, i32 16, i1 true)<br>
+  %2 = getelementptr [9 x i32], [9 x i32]* %0, i32 0, i32 0<br>
+  store volatile i32 1, i32* %2<br>
+  ret void<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone speculatable<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1<br>
+<br>
+; Function Attrs: argmemonly nounwind<br>
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1) #0<br>
+<br>
+attributes #0 = { argmemonly nounwind }<br>
+attributes #1 = { nounwind readnone speculatable }<br>
+<br>
+!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!3, !4, !5}<br>
+!llvm.ident = !{!6}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+!1 = !DIFile(filename: "foo.c", directory: "/bar")<br>
+!2 = !{}<br>
+!3 = !{i32 2, !"Dwarf Version", i32 4}<br>
+!4 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!5 = !{i32 1, !"wchar_size", i32 4}<br>
+!6 = !{!"clang version 6.0.0"}<br>
+!7 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !10)<br>
+!8 = !DISubroutineType(types: !9)<br>
+!9 = !{null}<br>
+!10 = !{!11}<br>
+!11 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !12)<br>
+!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 288, elements: !15)<br>
+!13 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !14)<br>
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!15 = !{!16}<br>
+!16 = !DISubrange(count: 9)<br>
+!17 = !DILocation(line: 3, column: 18, scope: !7)<br>
+<br>
+; CHECK-NOT:  = alloca [9 x i32]<br>
+; CHECK-NOT:  call void @llvm.dbg.declare(metadata [9 x i32]*<br>
+<br>
+; CHECK:      %[[VAR1:.*]] = alloca i32<br>
+; CHECK-NEXT: %[[VAR2:.*]] = alloca [8 x i32]<br>
+; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* %[[VAR1]]<br>
+; CHECK-NEXT: call void @llvm.dbg.declare(metadata [8 x i32]* %[[VAR2]]<br>
+<br>
+; CHECK-NOT:  = alloca [9 x i32]<br>
+; CHECK-NOT:  call void @llvm.dbg.declare(metadata [9 x i32]*<br>
+<br>
<br>
Added: llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr-inline-dse.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Mem2Reg/dbg-addr-inline-dse.ll?rev=313905&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>Transforms/Mem2Reg/dbg-addr-<wbr>inline-dse.ll?rev=313905&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr-inline-dse.ll (added)<br>
+++ llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr-inline-dse.ll Thu Sep 21 12:52:03 2017<br>
@@ -0,0 +1,94 @@<br>
+; RUN: opt -mem2reg -S < %s | FileCheck %s -implicit-check-not="call void @llvm.dbg.addr"<br>
+<br>
+; This example is intended to simulate this pass pipeline, which may not exist<br>
+; in practice:<br>
+; 1. DSE f from the original C source<br>
+; 2. Inline escape<br>
+; 3. mem2reg<br>
+; This exercises the corner case of multiple llvm.dbg.addr intrinsics.<br>
+<br>
+; C source:<br>
+;<br>
+; void escape(int *px) { ++*px; }<br>
+; extern int global;<br>
+; void f(int x) {<br>
+;   escape(&x);<br>
+;   x = 1; // DSE should delete and insert dbg.value(i32 1)<br>
+;   global = x;<br>
+;   x = 2; // DSE should insert dbg.addr<br>
+;   escape(&x);<br>
+; }<br>
+<br>
+; ModuleID = 'dse.c'<br>
+source_filename = "dse.c"<br>
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64-pc-windows-msvc19.0.<wbr>24215"<br>
+<br>
+declare void @llvm.dbg.addr(metadata, metadata, metadata) #2<br>
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2<br>
+<br>
+@global = external global i32, align 4<br>
+<br>
+; Function Attrs: nounwind uwtable<br>
+define void @f(i32 %x) #0 !dbg !8 {<br>
+entry:<br>
+  %x.addr = alloca i32, align 4<br>
+  store i32 %x, i32* %x.addr, align 4<br>
+  call void @llvm.dbg.addr(metadata i32* %x.addr, metadata !13, metadata !DIExpression()), !dbg !18<br>
+  %ld.1 = load i32, i32* %x.addr, align 4, !dbg !19<br>
+  %inc.1 = add nsw i32 %ld.1, 1, !dbg !19<br>
+  store i32 %inc.1, i32* %x.addr, align 4, !dbg !19<br>
+  call void @llvm.dbg.value(metadata i32 1, metadata !13, metadata !DIExpression()), !dbg !20<br>
+  store i32 1, i32* @global, align 4, !dbg !22<br>
+  call void @llvm.dbg.addr(metadata i32* %x.addr, metadata !13, metadata !DIExpression()), !dbg !23<br>
+  store i32 2, i32* %x.addr, align 4, !dbg !23<br>
+  %ld.2 = load i32, i32* %x.addr, align 4, !dbg !19<br>
+  %inc.2 = add nsw i32 %ld.2, 1, !dbg !19<br>
+  store i32 %inc.2, i32* %x.addr, align 4, !dbg !19<br>
+  ret void, !dbg !25<br>
+}<br>
+<br>
+; CHECK-LABEL: define void @f(i32 %x)<br>
+; CHECK: call void @llvm.dbg.value(metadata i32 %x, metadata !13, metadata !DIExpression())<br>
+; CHECK: %inc.1 = add nsw i32 %x, 1<br>
+; CHECK: call void @llvm.dbg.value(metadata i32 %inc.1, metadata !13, metadata !DIExpression())<br>
+; CHECK: call void @llvm.dbg.value(metadata i32 1, metadata !13, metadata !DIExpression())<br>
+; CHECK: store i32 1, i32* @global, align 4<br>
+; CHECK: call void @llvm.dbg.value(metadata i32 2, metadata !13, metadata !DIExpression())<br>
+; CHECK: %inc.2 = add nsw i32 2, 1<br>
+; CHECK: call void @llvm.dbg.value(metadata i32 %inc.2, metadata !13, metadata !DIExpression())<br>
+; CHECK: ret void<br>
+<br>
+attributes #0 = { nounwind uwtable }<br>
+attributes #2 = { nounwind readnone speculatable }<br>
+<br>
+!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!3, !4, !5, !6}<br>
+!llvm.ident = !{!7}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+!1 = !DIFile(filename: "dse.c", directory: "C:\5Csrc\5Cllvm-project\<wbr>5Cbuild")<br>
+!2 = !{}<br>
+!3 = !{i32 2, !"Dwarf Version", i32 4}<br>
+!4 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!5 = !{i32 1, !"wchar_size", i32 2}<br>
+!6 = !{i32 7, !"PIC Level", i32 2}<br>
+!7 = !{!"clang version 6.0.0 "}<br>
+!8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)<br>
+!9 = !DISubroutineType(types: !10)<br>
+!10 = !{null, !11}<br>
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!12 = !{!13}<br>
+!13 = !DILocalVariable(name: "x", arg: 1, scope: !8, file: !1, line: 3, type: !11)<br>
+!14 = !{!15, !15, i64 0}<br>
+!15 = !{!"int", !16, i64 0}<br>
+!16 = !{!"omnipotent char", !17, i64 0}<br>
+!17 = !{!"Simple C/C++ TBAA"}<br>
+!18 = !DILocation(line: 3, column: 12, scope: !8)<br>
+!19 = !DILocation(line: 4, column: 3, scope: !8)<br>
+!20 = !DILocation(line: 5, column: 5, scope: !8)<br>
+!21 = !DILocation(line: 6, column: 12, scope: !8)<br>
+!22 = !DILocation(line: 6, column: 10, scope: !8)<br>
+!23 = !DILocation(line: 7, column: 5, scope: !8)<br>
+!24 = !DILocation(line: 8, column: 3, scope: !8)<br>
+!25 = !DILocation(line: 9, column: 1, scope: !8)<br>
<br>
Added: llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Mem2Reg/dbg-addr.ll?rev=313905&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>Transforms/Mem2Reg/dbg-addr.<wbr>ll?rev=313905&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr.ll (added)<br>
+++ llvm/trunk/test/Transforms/<wbr>Mem2Reg/dbg-addr.ll Thu Sep 21 12:52:03 2017<br>
@@ -0,0 +1,91 @@<br>
+; RUN: opt -mem2reg -S < %s | FileCheck %s<br>
+<br>
+; ModuleID = 'newvars.c'<br>
+source_filename = "newvars.c"<br>
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64-pc-windows-msvc19.0.<wbr>24215"<br>
+<br>
+; Function Attrs: nounwind uwtable<br>
+define i32 @if_else(i32 %cond, i32 %a, i32 %b) !dbg !8 {<br>
+entry:<br>
+  %x = alloca i32, align 4<br>
+  call void @llvm.dbg.addr(metadata i32* %x, metadata !16, metadata !DIExpression()), !dbg !26<br>
+  store i32 %a, i32* %x, align 4, !dbg !26, !tbaa !17<br>
+  %tobool = icmp ne i32 %cond, 0, !dbg !28<br>
+  br i1 %tobool, label %if.then, label %if.else, !dbg !30<br>
+<br>
+if.then:                                          ; preds = %entry<br>
+  store i32 0, i32* %x, align 4, !dbg !31, !tbaa !17<br>
+  br label %if.end, !dbg !33<br>
+<br>
+if.else:                                          ; preds = %entry<br>
+  store i32 %b, i32* %x, align 4, !dbg !36, !tbaa !17<br>
+  br label %if.end<br>
+<br>
+if.end:                                           ; preds = %if.else, %if.then<br>
+  %rv = load i32, i32* %x, align 4, !dbg !37, !tbaa !17<br>
+  ret i32 %rv, !dbg !39<br>
+}<br>
+<br>
+; CHECK-LABEL: define i32 @if_else({{.*}})<br>
+; CHECK: entry:<br>
+; CHECK-NOT:   alloca i32<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %a, metadata ![[X_LOCAL:[0-9]+]], metadata !DIExpression())<br>
+; CHECK: if.then:                                          ; preds = %entry<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 0, metadata ![[X_LOCAL]], metadata !DIExpression())<br>
+; CHECK: if.else:                                          ; preds = %entry<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %b, metadata ![[X_LOCAL]], metadata !DIExpression())<br>
+; CHECK: if.end:                                           ; preds = %if.else, %if.then<br>
+; CHECK:   %[[PHI:[^ ]*]] = phi i32 [ 0, %if.then ], [ %b, %if.else ]<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %[[PHI]], metadata ![[X_LOCAL]], metadata !DIExpression())<br>
+; CHECK:   ret i32<br>
+<br>
+; CHECK: ![[X_LOCAL]] = !DILocalVariable(name: "x", {{.*}})<br>
+<br>
+; Function Attrs: nounwind readnone speculatable<br>
+declare void @llvm.dbg.declare(metadata, metadata, metadata)<br>
+declare void @llvm.dbg.addr(metadata, metadata, metadata)<br>
+<br>
+!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!3, !4, !5, !6}<br>
+!llvm.ident = !{!7}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+!1 = !DIFile(filename: "newvars.c", directory: "C:\5Csrc\5Cllvm-project\<wbr>5Cbuild")<br>
+!2 = !{}<br>
+!3 = !{i32 2, !"Dwarf Version", i32 4}<br>
+!4 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!5 = !{i32 1, !"wchar_size", i32 2}<br>
+!6 = !{i32 7, !"PIC Level", i32 2}<br>
+!7 = !{!"clang version 6.0.0 "}<br>
+!8 = distinct !DISubprogram(name: "if_else", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)<br>
+!9 = !DISubroutineType(types: !10)<br>
+!10 = !{!11, !11, !11, !11}<br>
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!12 = !{!13, !14, !15, !16}<br>
+!13 = !DILocalVariable(name: "b", arg: 3, scope: !8, file: !1, line: 1, type: !11)<br>
+!14 = !DILocalVariable(name: "a", arg: 2, scope: !8, file: !1, line: 1, type: !11)<br>
+!15 = !DILocalVariable(name: "cond", arg: 1, scope: !8, file: !1, line: 1, type: !11)<br>
+!16 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !11)<br>
+!17 = !{!18, !18, i64 0}<br>
+!18 = !{!"int", !19, i64 0}<br>
+!19 = !{!"omnipotent char", !20, i64 0}<br>
+!20 = !{!"Simple C/C++ TBAA"}<br>
+!22 = !DILocation(line: 1, column: 34, scope: !8)<br>
+!23 = !DILocation(line: 1, column: 27, scope: !8)<br>
+!24 = !DILocation(line: 1, column: 17, scope: !8)<br>
+!25 = !DILocation(line: 2, column: 3, scope: !8)<br>
+!26 = !DILocation(line: 2, column: 7, scope: !8)<br>
+!27 = !DILocation(line: 2, column: 11, scope: !8)<br>
+!28 = !DILocation(line: 3, column: 7, scope: !29)<br>
+!29 = distinct !DILexicalBlock(scope: !8, file: !1, line: 3, column: 7)<br>
+!30 = !DILocation(line: 3, column: 7, scope: !8)<br>
+!31 = !DILocation(line: 4, column: 7, scope: !32)<br>
+!32 = distinct !DILexicalBlock(scope: !29, file: !1, line: 3, column: 13)<br>
+!33 = !DILocation(line: 5, column: 3, scope: !32)<br>
+!34 = !DILocation(line: 6, column: 9, scope: !35)<br>
+!35 = distinct !DILexicalBlock(scope: !29, file: !1, line: 5, column: 10)<br>
+!36 = !DILocation(line: 6, column: 7, scope: !35)<br>
+!37 = !DILocation(line: 8, column: 10, scope: !8)<br>
+!38 = !DILocation(line: 9, column: 1, scope: !8)<br>
+!39 = !DILocation(line: 8, column: 3, scope: !8)<br>
<br>
Added: llvm/trunk/test/Transforms/<wbr>SROA/dbg-addr-diamond.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SROA/dbg-addr-diamond.ll?rev=313905&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>Transforms/SROA/dbg-addr-<wbr>diamond.ll?rev=313905&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/Transforms/<wbr>SROA/dbg-addr-diamond.ll (added)<br>
+++ llvm/trunk/test/Transforms/<wbr>SROA/dbg-addr-diamond.ll Thu Sep 21 12:52:03 2017<br>
@@ -0,0 +1,127 @@<br>
+; RUN: opt -use-dbg-addr -sroa -S < %s | FileCheck %s<br>
+<br>
+; ModuleID = '<stdin>'<br>
+source_filename = "newvars.c"<br>
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64-pc-windows-msvc19.0.<wbr>24215"<br>
+<br>
+%struct.Pair = type { i32, i32 }<br>
+<br>
+@pair = internal global %struct.Pair zeroinitializer<br>
+<br>
+; Function Attrs: nounwind uwtable<br>
+define void @if_else(i32 %cond, i32 %a, i32 %b) !dbg !8 {<br>
+entry:<br>
+  %p = alloca %struct.Pair, align 4<br>
+  %0 = bitcast %struct.Pair* %p to i8*, !dbg !25<br>
+  call void @llvm.dbg.addr(metadata %struct.Pair* %p, metadata !20, metadata !DIExpression()), !dbg !26<br>
+  %x = getelementptr inbounds %struct.Pair, %struct.Pair* %p, i32 0, i32 0, !dbg !27<br>
+  store i32 %a, i32* %x, align 4, !dbg !28<br>
+  %y = getelementptr inbounds %struct.Pair, %struct.Pair* %p, i32 0, i32 1, !dbg !34<br>
+  store i32 %b, i32* %y, align 4, !dbg !35<br>
+  %tobool = icmp ne i32 %cond, 0, !dbg !37<br>
+  br i1 %tobool, label %if.then, label %if.else, !dbg !39<br>
+<br>
+if.then:                                          ; preds = %entry<br>
+  %x1 = getelementptr inbounds %struct.Pair, %struct.Pair* %p, i32 0, i32 0, !dbg !40<br>
+  store i32 0, i32* %x1, align 4, !dbg !42<br>
+  %y2 = getelementptr inbounds %struct.Pair, %struct.Pair* %p, i32 0, i32 1, !dbg !43<br>
+  store i32 %a, i32* %y2, align 4, !dbg !44<br>
+  br label %if.end, !dbg !45<br>
+<br>
+if.else:                                          ; preds = %entry<br>
+  %x3 = getelementptr inbounds %struct.Pair, %struct.Pair* %p, i32 0, i32 0, !dbg !46<br>
+  store i32 %b, i32* %x3, align 4, !dbg !48<br>
+  %y4 = getelementptr inbounds %struct.Pair, %struct.Pair* %p, i32 0, i32 1, !dbg !49<br>
+  store i32 0, i32* %y4, align 4, !dbg !50<br>
+  br label %if.end<br>
+<br>
+if.end:                                           ; preds = %if.else, %if.then<br>
+  %1 = bitcast %struct.Pair* %p to i8*, !dbg !51<br>
+  %2 = bitcast %struct.Pair* @pair to i8*, !dbg !51<br>
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %1, i64 8, i32 4, i1 false), !dbg !51<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: define void @if_else(i32 %cond, i32 %a, i32 %b)<br>
+; CHECK: entry:<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %a, metadata ![[PVAR:[0-9]+]], metadata ![[XFRAG:DIExpression\(DW_OP_<wbr>LLVM_fragment, 0, 32\)]])<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %b, metadata ![[PVAR]], metadata ![[YFRAG:DIExpression\(DW_OP_<wbr>LLVM_fragment, 32, 32\)]])<br>
+; CHECK: if.then:<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 0, metadata ![[PVAR]], metadata ![[XFRAG]])<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %a, metadata ![[PVAR]], metadata ![[YFRAG]])<br>
+; CHECK: if.else:<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %b, metadata ![[PVAR]], metadata ![[XFRAG]])<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 0, metadata ![[PVAR]], metadata ![[YFRAG]])<br>
+; CHECK: if.end:<br>
+; CHECK:   %p.sroa.4.0 = phi i32 [ %a, %if.then ], [ 0, %if.else ]<br>
+; CHECK:   %p.sroa.0.0 = phi i32 [ 0, %if.then ], [ %b, %if.else ]<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %p.sroa.0.0, metadata ![[PVAR]], metadata ![[XFRAG]])<br>
+; CHECK:   call void @llvm.dbg.value(metadata i32 %p.sroa.4.0, metadata ![[PVAR]], metadata ![[YFRAG]])<br>
+<br>
+; CHECK: ![[PVAR]] = !DILocalVariable(name: "p", {{.*}})<br>
+<br>
+; Function Attrs: argmemonly nounwind<br>
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #2<br>
+<br>
+; Function Attrs: nounwind readnone speculatable<br>
+declare void @llvm.dbg.addr(metadata, metadata, metadata)<br>
+<br>
+!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+!llvm.module.flags = !{!3, !4, !5, !6}<br>
+!llvm.ident = !{!7}<br>
+<br>
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+!1 = !DIFile(filename: "newvars.c", directory: "C:\5Csrc\5Cllvm-project\<wbr>5Cbuild")<br>
+!2 = !{}<br>
+!3 = !{i32 2, !"Dwarf Version", i32 4}<br>
+!4 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!5 = !{i32 1, !"wchar_size", i32 2}<br>
+!6 = !{i32 7, !"PIC Level", i32 2}<br>
+!7 = !{!"clang version 6.0.0 "}<br>
+!8 = distinct !DISubprogram(name: "if_else", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !16)<br>
+!9 = !DISubroutineType(types: !10)<br>
+!10 = !{!11, !14, !14, !14}<br>
+!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Pair", file: !1, line: 1, size: 64, elements: !12)<br>
+!12 = !{!13, !15}<br>
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !11, file: !1, line: 1, baseType: !14, size: 32)<br>
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!15 = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: !11, file: !1, line: 1, baseType: !14, size: 32, offset: 32)<br>
+!16 = !{!17, !18, !19, !20}<br>
+!17 = !DILocalVariable(name: "b", arg: 3, scope: !8, file: !1, line: 2, type: !14)<br>
+!18 = !DILocalVariable(name: "a", arg: 2, scope: !8, file: !1, line: 2, type: !14)<br>
+!19 = !DILocalVariable(name: "cond", arg: 1, scope: !8, file: !1, line: 2, type: !14)<br>
+!20 = !DILocalVariable(name: "p", scope: !8, file: !1, line: 3, type: !11)<br>
+!22 = !DILocation(line: 2, column: 42, scope: !8)<br>
+!23 = !DILocation(line: 2, column: 35, scope: !8)<br>
+!24 = !DILocation(line: 2, column: 25, scope: !8)<br>
+!25 = !DILocation(line: 3, column: 3, scope: !8)<br>
+!26 = !DILocation(line: 3, column: 15, scope: !8)<br>
+!27 = !DILocation(line: 4, column: 5, scope: !8)<br>
+!28 = !DILocation(line: 4, column: 7, scope: !8)<br>
+!29 = !{!30, !31, i64 0}<br>
+!30 = !{!"Pair", !31, i64 0, !31, i64 4}<br>
+!31 = !{!"int", !32, i64 0}<br>
+!32 = !{!"omnipotent char", !33, i64 0}<br>
+!33 = !{!"Simple C/C++ TBAA"}<br>
+!34 = !DILocation(line: 5, column: 5, scope: !8)<br>
+!35 = !DILocation(line: 5, column: 7, scope: !8)<br>
+!36 = !{!30, !31, i64 4}<br>
+!37 = !DILocation(line: 6, column: 7, scope: !38)<br>
+!38 = distinct !DILexicalBlock(scope: !8, file: !1, line: 6, column: 7)<br>
+!39 = !DILocation(line: 6, column: 7, scope: !8)<br>
+!40 = !DILocation(line: 7, column: 7, scope: !41)<br>
+!41 = distinct !DILexicalBlock(scope: !38, file: !1, line: 6, column: 13)<br>
+!42 = !DILocation(line: 7, column: 9, scope: !41)<br>
+!43 = !DILocation(line: 8, column: 7, scope: !41)<br>
+!44 = !DILocation(line: 8, column: 9, scope: !41)<br>
+!45 = !DILocation(line: 9, column: 3, scope: !41)<br>
+!46 = !DILocation(line: 10, column: 7, scope: !47)<br>
+!47 = distinct !DILexicalBlock(scope: !38, file: !1, line: 9, column: 10)<br>
+!48 = !DILocation(line: 10, column: 9, scope: !47)<br>
+!49 = !DILocation(line: 11, column: 7, scope: !47)<br>
+!50 = !DILocation(line: 11, column: 9, scope: !47)<br>
+!51 = !DILocation(line: 13, column: 10, scope: !8)<br>
+!52 = !{i64 0, i64 4, !53, i64 4, i64 4, !53}<br>
+!53 = !{!31, !31, i64 0}<br>
+!54 = !DILocation(line: 14, column: 1, scope: !8)<br>
<br>
Modified: llvm/trunk/unittests/<wbr>Transforms/Utils/CMakeLists.<wbr>txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/CMakeLists.txt?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/unittests/<wbr>Transforms/Utils/CMakeLists.<wbr>txt?rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/unittests/<wbr>Transforms/Utils/CMakeLists.<wbr>txt (original)<br>
+++ llvm/trunk/unittests/<wbr>Transforms/Utils/CMakeLists.<wbr>txt Thu Sep 21 12:52:03 2017<br>
@@ -1,5 +1,6 @@<br>
 set(LLVM_LINK_COMPONENTS<br>
   Analysis<br>
+  AsmParser<br>
   Core<br>
   Support<br>
   TransformUtils<br>
<br>
Modified: llvm/trunk/unittests/<wbr>Transforms/Utils/Local.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Local.cpp?rev=313905&r1=313904&r2=313905&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/unittests/<wbr>Transforms/Utils/Local.cpp?<wbr>rev=313905&r1=313904&r2=<wbr>313905&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/unittests/<wbr>Transforms/Utils/Local.cpp (original)<br>
+++ llvm/trunk/unittests/<wbr>Transforms/Utils/Local.cpp Thu Sep 21 12:52:03 2017<br>
@@ -8,10 +8,14 @@<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
 #include "llvm/Transforms/Utils/Local.<wbr>h"<br>
+#include "llvm/AsmParser/Parser.h"<br>
 #include "llvm/IR/BasicBlock.h"<br>
+#include "llvm/IR/DIBuilder.h"<br>
 #include "llvm/IR/IRBuilder.h"<br>
 #include "llvm/IR/Instructions.h"<br>
+#include "llvm/IR/IntrinsicInst.h"<br>
 #include "llvm/IR/LLVMContext.h"<br>
+#include "llvm/Support/SourceMgr.h"<br>
 #include "gtest/gtest.h"<br>
<br>
 using namespace llvm;<br>
@@ -95,3 +99,70 @@ TEST(Local, RemoveDuplicatePHINodes) {<br>
   EXPECT_TRUE(<wbr>EliminateDuplicatePHINodes(BB)<wbr>);<br>
   EXPECT_EQ(3U, BB->size());<br>
 }<br>
+<br>
+std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {<br>
+  SMDiagnostic Err;<br>
+  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);<br>
+  if (!Mod)<br>
+    Err.print("UtilsTests", errs());<br>
+  return Mod;<br>
+}<br>
+<br>
+TEST(Local, ReplaceDbgDeclare) {<br>
+  LLVMContext C;<br>
+<br>
+  // Original C source to get debug info for a local variable:<br>
+  // void f() { int x; }<br>
+  std::unique_ptr<Module> M = parseIR(<br>
+      C,<br>
+      "define void @f() !dbg !8 {\n"<br>
+      "entry:\n"<br>
+      "  %x = alloca i32, align 4\n"<br>
+      "  call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata "<br>
+      "!DIExpression()), !dbg !13\n"<br>
+      "  call void @llvm.dbg.declare(metadata i32* %x, metadata !11, metadata "<br>
+      "!DIExpression()), !dbg !13\n"<br>
+      "  ret void, !dbg !14\n"<br>
+      "}\n"<br>
+      "declare void @llvm.dbg.declare(metadata, metadata, metadata)\n"<br>
+      "!<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}\n"<br>
+      "!llvm.module.flags = !{!3, !4}\n"<br>
+      "!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "<br>
+      "\"clang version 6.0.0 \", isOptimized: false, runtimeVersion: 0, "<br>
+      "emissionKind: FullDebug, enums: !2)\n"<br>
+      "!1 = !DIFile(filename: \"t2.c\", directory: \"foo\")\n"<br>
+      "!2 = !{}\n"<br>
+      "!3 = !{i32 2, !\"Dwarf Version\", i32 4}\n"<br>
+      "!4 = !{i32 2, !\"Debug Info Version\", i32 3}\n"<br>
+      "!8 = distinct !DISubprogram(name: \"f\", scope: !1, file: !1, line: 1, "<br>
+      "type: !9, isLocal: false, isDefinition: true, scopeLine: 1, "<br>
+      "isOptimized: false, unit: !0, variables: !2)\n"<br>
+      "!9 = !DISubroutineType(types: !10)\n"<br>
+      "!10 = !{null}\n"<br>
+      "!11 = !DILocalVariable(name: \"x\", scope: !8, file: !1, line: 2, type: "<br>
+      "!12)\n"<br>
+      "!12 = !DIBasicType(name: \"int\", size: 32, encoding: DW_ATE_signed)\n"<br>
+      "!13 = !DILocation(line: 2, column: 7, scope: !8)\n"<br>
+      "!14 = !DILocation(line: 3, column: 1, scope: !8)\n");<br>
+  auto *GV = M->getNamedValue("f");<br>
+  ASSERT_TRUE(GV);<br>
+  auto *F = dyn_cast<Function>(GV);<br>
+  ASSERT_TRUE(F);<br>
+  Instruction *Inst = &F->front().front();<br>
+  auto *AI = dyn_cast<AllocaInst>(Inst);<br>
+  ASSERT_TRUE(AI);<br>
+  Inst = Inst->getNextNode()-><wbr>getNextNode();<br>
+  ASSERT_TRUE(Inst);<br>
+  auto *DII = dyn_cast<DbgDeclareInst>(Inst)<wbr>;<br>
+  ASSERT_TRUE(DII);<br>
+  Value *NewBase = Constant::getNullValue(Type::<wbr>getInt32PtrTy(C));<br>
+  DIBuilder DIB(*M);<br>
+  replaceDbgDeclare(AI, NewBase, DII, DIB, /*Deref=*/false, /*Offset=*/0);<br>
+<br>
+  // There should be exactly two dbg.declares.<br>
+  int Declares = 0;<br>
+  for (const Instruction &I : F->front())<br>
+    if (isa<DbgDeclareInst>(I))<br>
+      Declares++;<br>
+  EXPECT_EQ(2, Declares);<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>