<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>