[llvm] r313905 - Re-land r313825: "[IR] Add llvm.dbg.addr, a control-dependent version of llvm.dbg.declare"

Galina Kistanova via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 22 15:56:36 PDT 2017


Hello Reid,

It looks like this commit broke one of our builders:
http://lab.llvm.org:8011/builders/ubuntu-gcc7.1-werror/builds/1617

Please have a look?

Thanks

Galina

. . .

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
/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)’:
/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR/Verifier.cpp:4005:22:
error: this statement may fall through [-Werror=implicit-fallthrough=]
     visitDbgIntrinsic("addr",
cast<DbgInfoIntrinsic>(*CS.getInstruction()));
     ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/lib/IR/Verifier.cpp:4006:3:
note: here
   case Intrinsic::dbg_value: // llvm.dbg.value
   ^~~~

On Thu, Sep 21, 2017 at 12:52 PM, Reid Kleckner via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

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


More information about the llvm-commits mailing list