summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2017-09-21 12:07:33 +0000
committerDaniel Jasper <djasper@google.com>2017-09-21 12:07:33 +0000
commit4b02ed37e6b925f978b5839aaa7ba6ef3c62f887 (patch)
tree758251f3803c1f1ece500e67f2812e15e0c0ebd7
parent4d4149da555cbb29f6fafb150caaf18ecea3a356 (diff)
Revert r313825: "[IR] Add llvm.dbg.addr, a control-dependent version of llvm.dbg.declare"
.. as well as the two subsequent changes r313826 and r313875. This leads to segfaults in combination with ASAN. Will forward repro instructions to the original author (rnk). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313876 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/SourceLevelDebugging.rst62
-rw-r--r--include/llvm/IR/IntrinsicInst.h34
-rw-r--r--include/llvm/IR/Intrinsics.td8
-rw-r--r--include/llvm/Transforms/Utils/Local.h22
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp48
-rw-r--r--lib/IR/DIBuilder.cpp14
-rw-r--r--lib/IR/Verifier.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp13
-rw-r--r--lib/Transforms/Scalar/SROA.cpp30
-rw-r--r--lib/Transforms/Utils/Local.cpp91
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp44
-rw-r--r--test/DebugInfo/X86/dbg-addr-dse.ll100
-rw-r--r--test/DebugInfo/X86/dbg-addr.ll67
-rw-r--r--test/DebugInfo/X86/sroasplit-5.ll4
-rw-r--r--test/DebugInfo/X86/sroasplit-dbg-declare.ll59
-rw-r--r--test/Transforms/Mem2Reg/dbg-addr-inline-dse.ll94
-rw-r--r--test/Transforms/Mem2Reg/dbg-addr.ll91
-rw-r--r--test/Transforms/SROA/dbg-addr-diamond.ll127
18 files changed, 134 insertions, 776 deletions
diff --git a/docs/SourceLevelDebugging.rst b/docs/SourceLevelDebugging.rst
index c46b51c4d81..ee4c5ce8bce 100644
--- a/docs/SourceLevelDebugging.rst
+++ b/docs/SourceLevelDebugging.rst
@@ -171,64 +171,35 @@ Debugger intrinsic functions
----------------------------
LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to
-track source local variables through optimization and code generation.
+provide debug information at various points in generated code.
-``llvm.dbg.addr``
+``llvm.dbg.declare``
^^^^^^^^^^^^^^^^^^^^
.. code-block:: llvm
- void @llvm.dbg.addr(metadata, metadata, metadata)
+ void @llvm.dbg.declare(metadata, metadata, metadata)
-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.
+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.
.. code-block:: llvm
%i.addr = alloca i32, align 4
- call void @llvm.dbg.addr(metadata i32* %i.addr, metadata !1,
- metadata !DIExpression()), !dbg !2
+ call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1, metadata !2), !dbg !3
!1 = !DILocalVariable(name: "i", ...) ; int i
- !2 = !DILocation(...)
+ !2 = !DIExpression()
+ !3 = !DILocation(...)
...
%buffer = alloca [256 x i8], align 8
; The address of i is buffer+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.
+ 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)
``llvm.dbg.value``
@@ -271,9 +242,6 @@ 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
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index b8d6e23907c..eccb4080932 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -71,12 +71,6 @@ 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());
}
@@ -93,13 +87,11 @@ namespace llvm {
return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
}
- /// \name Casting methods
- /// @{
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
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;
}
@@ -107,7 +99,6 @@ namespace llvm {
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
- /// @}
};
/// This represents the llvm.dbg.declare instruction.
@@ -115,30 +106,13 @@ namespace llvm {
public:
Value *getAddress() const { return getVariableLocation(); }
- /// \name Casting methods
- /// @{
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
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.
@@ -148,15 +122,13 @@ namespace llvm {
return getVariableLocation(/* AllowNullOp = */ false);
}
- /// \name Casting methods
- /// @{
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
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.
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index cb16c3d4849..6ced600ddc0 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -583,16 +583,12 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
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----------------------===//
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 9816e7fecf2..42c2ec80beb 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -16,7 +16,6 @@
#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"
@@ -33,7 +32,6 @@ class BranchInst;
class Instruction;
class CallInst;
class DbgDeclareInst;
-class DbgInfoIntrinsic;
class DbgValueInst;
class StoreInst;
class LoadInst;
@@ -264,28 +262,26 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
///
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
-/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
-void ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
+/// that has an associated llvm.dbg.decl intrinsic.
+void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
StoreInst *SI, DIBuilder &Builder);
/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
-/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
-void ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
+/// that has an associated llvm.dbg.decl intrinsic.
+void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
LoadInst *LI, DIBuilder &Builder);
-/// 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,
+/// 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,
PHINode *LI, DIBuilder &Builder);
/// Lowers llvm.dbg.declare intrinsics into appropriate set of
/// llvm.dbg.value intrinsics.
bool LowerDbgDeclare(Function &F);
-/// 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.declare intrinsic corresponding to an alloca, if any.
+DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
/// Finds the llvm.dbg.value intrinsics describing a value.
void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index a98be560860..fb32487ac42 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5109,48 +5109,37 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
DAG.setRoot(CallResult.second);
return nullptr;
}
- case Intrinsic::dbg_addr:
case Intrinsic::dbg_declare: {
- const DbgInfoIntrinsic &DI = cast<DbgInfoIntrinsic>(I);
+ const DbgDeclareInst &DI = cast<DbgDeclareInst>(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.
- const Value *Address = DI.getVariableLocation();
- if (!Address || isa<UndefValue>(Address) ||
+ if (isa<UndefValue>(Address) ||
(Address->use_empty() && !isa<Argument>(Address))) {
DEBUG(dbgs() << "Dropping debug info for " << DI << "\n");
return nullptr;
}
- 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;
+ // Static allocas are handled more efficiently in the variable frame index
+ // side table.
if (const auto *AI =
- 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);
- }
+ dyn_cast<AllocaInst>(Address->stripInBoundsConstantOffsets()))
+ if (AI->isStaticAlloca() && FuncInfo.StaticAllocaMap.count(AI))
+ 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;
- }
+ // 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;
SDValue &N = NodeMap[Address];
if (!N.getNode() && isa<Argument>(Address))
@@ -5161,6 +5150,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
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.
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp
index 88f5b36dd58..1a40d5ce13d 100644
--- a/lib/IR/DIBuilder.cpp
+++ b/lib/IR/DIBuilder.cpp
@@ -24,11 +24,6 @@
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),
@@ -781,11 +776,6 @@ static Instruction *withDebugLoc(Instruction *I, const DILocation *DL) {
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) {
@@ -795,7 +785,7 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
VarInfo->getScope()->getSubprogram() &&
"Expected matching subprograms");
if (!DeclareFn)
- DeclareFn = getDeclareIntrin(M);
+ DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
trackIfUnresolved(VarInfo);
trackIfUnresolved(Expr);
@@ -814,7 +804,7 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
VarInfo->getScope()->getSubprogram() &&
"Expected matching subprograms");
if (!DeclareFn)
- DeclareFn = getDeclareIntrin(M);
+ DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
trackIfUnresolved(VarInfo);
trackIfUnresolved(Expr);
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 9f671e41a18..c875e302188 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -4001,8 +4001,6 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
"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;
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index 60db2ddb63c..f51b8381445 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2106,10 +2106,10 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {
// If we are removing an alloca with a dbg.declare, insert dbg.value calls
// before each store.
- TinyPtrVector<DbgInfoIntrinsic *> DIIs;
+ DbgDeclareInst *DDI = nullptr;
std::unique_ptr<DIBuilder> DIB;
if (isa<AllocaInst>(MI)) {
- DIIs = FindDbgAddrUses(&MI);
+ DDI = FindAllocaDbgDeclare(&MI);
DIB.reset(new DIBuilder(*MI.getModule(), /*AllowUnresolved=*/false));
}
@@ -2145,9 +2145,8 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {
} else if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I) ||
isa<AddrSpaceCastInst>(I)) {
replaceInstUsesWith(*I, UndefValue::get(I->getType()));
- } else if (auto *SI = dyn_cast<StoreInst>(I)) {
- for (auto *DII : DIIs)
- ConvertDebugDeclareToDebugValue(DII, SI, *DIB);
+ } else if (DDI && isa<StoreInst>(I)) {
+ ConvertDebugDeclareToDebugValue(DDI, cast<StoreInst>(I), *DIB);
}
eraseInstFromFunction(*I);
}
@@ -2160,8 +2159,8 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {
None, "", II->getParent());
}
- for (auto *DII : DIIs)
- eraseInstFromFunction(*DII);
+ if (DDI)
+ eraseInstFromFunction(*DDI);
return eraseInstFromFunction(MI);
}
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index b968cb8c892..c96606af6bb 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -4102,10 +4102,9 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
// Migrate debug information from the old alloca to the new alloca(s)
// and the individual partitions.
- TinyPtrVector<DbgInfoIntrinsic *> DbgDeclares = FindDbgAddrUses(&AI);
- if (!DbgDeclares.empty()) {
- auto *Var = DbgDeclares.front()->getVariable();
- auto *Expr = DbgDeclares.front()->getExpression();
+ if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(&AI)) {
+ auto *Var = DbgDecl->getVariable();
+ auto *Expr = DbgDecl->getExpression();
DIBuilder DIB(*AI.getModule(), /*AllowUnresolved*/ false);
uint64_t AllocaSize = DL.getTypeSizeInBits(AI.getAllocatedType());
for (auto Fragment : Fragments) {
@@ -4137,12 +4136,12 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
DIExpression::createFragmentExpression(Expr, Start, Size);
}
- // Remove any existing intrinsics describing the same alloca.
- for (DbgInfoIntrinsic *OldDII : FindDbgAddrUses(Fragment.Alloca))
- OldDII->eraseFromParent();
+ // Remove any existing dbg.declare intrinsic describing the same alloca.
+ if (DbgDeclareInst *OldDDI = FindAllocaDbgDeclare(Fragment.Alloca))
+ OldDDI->eraseFromParent();
DIB.insertDeclare(Fragment.Alloca, Var, FragmentExpr,
- DbgDeclares.front()->getDebugLoc(), &AI);
+ DbgDecl->getDebugLoc(), &AI);
}
}
return Changed;
@@ -4247,15 +4246,6 @@ 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())
@@ -4266,6 +4256,12 @@ 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();
}
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 43b07557e09..c3251e26340 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -1098,13 +1098,12 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
}
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
-/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
+/// that has an associated llvm.dbg.decl intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
StoreInst *SI, DIBuilder &Builder) {
- assert(DII->isAddressOfVariable());
- auto *DIVar = DII->getVariable();
+ auto *DIVar = DDI->getVariable();
assert(DIVar && "Missing variable");
- auto *DIExpr = DII->getExpression();
+ auto *DIExpr = DDI->getExpression();
Value *DV = SI->getOperand(0);
// If an argument is zero extended then use argument directly. The ZExt
@@ -1115,7 +1114,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))
ExtendedArg = dyn_cast<Argument>(SExt->getOperand(0));
if (ExtendedArg) {
- // If this DII was already describing only a fragment of a variable, ensure
+ // If this DDI 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
@@ -1128,23 +1127,23 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
DIExpr->elements_end() - 3);
Ops.push_back(dwarf::DW_OP_LLVM_fragment);
Ops.push_back(FragmentOffset);
- const DataLayout &DL = DII->getModule()->getDataLayout();
+ const DataLayout &DL = DDI->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, DII->getDebugLoc(),
+ Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, DDI->getDebugLoc(),
SI);
}
/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
-/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
+/// that has an associated llvm.dbg.decl intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
LoadInst *LI, DIBuilder &Builder) {
- auto *DIVar = DII->getVariable();
- auto *DIExpr = DII->getExpression();
+ auto *DIVar = DDI->getVariable();
+ auto *DIExpr = DDI->getExpression();
assert(DIVar && "Missing variable");
if (LdStHasDebugValue(DIVar, DIExpr, LI))
@@ -1155,16 +1154,16 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
// 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, DII->getDebugLoc(), (Instruction *)nullptr);
+ LI, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr);
DbgValue->insertAfter(LI);
}
-/// 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,
+/// Inserts a llvm.dbg.value intrinsic after a phi
+/// that has an associated llvm.dbg.decl intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
PHINode *APN, DIBuilder &Builder) {
- auto *DIVar = DII->getVariable();
- auto *DIExpr = DII->getExpression();
+ auto *DIVar = DDI->getVariable();
+ auto *DIExpr = DDI->getExpression();
assert(DIVar && "Missing variable");
if (PhiHasDebugValue(DIVar, DIExpr, APN))
@@ -1177,7 +1176,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
// insertion point.
// FIXME: Insert dbg.value markers in the successors when appropriate.
if (InsertionPt != BB->end())
- Builder.insertDbgValueIntrinsic(APN, DIVar, DIExpr, DII->getDebugLoc(),
+ Builder.insertDbgValueIntrinsic(APN, DIVar, DIExpr, DDI->getDebugLoc(),
&*InsertionPt);
}
@@ -1232,25 +1231,16 @@ bool llvm::LowerDbgDeclare(Function &F) {
return true;
}
-/// 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);
- }
+/// 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;
- return Declares;
+ return nullptr;
}
void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {
@@ -1261,22 +1251,23 @@ void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {
DbgValues.push_back(DVI);
}
+
bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
Instruction *InsertBefore, DIBuilder &Builder,
bool Deref, int Offset) {
- 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 the original alloca, and remove
- // old llvm.dbg.declare.
- Builder.insertDeclare(NewAddress, DIVar, DIExpr, Loc, InsertBefore);
- DII->eraseFromParent();
- }
- return !DbgAddrs.empty();
+ 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;
}
bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index e2ba5c4cfbb..ac28f590b01 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -103,7 +103,7 @@ struct AllocaInfo {
bool OnlyUsedInOneBlock;
Value *AllocaPointerVal;
- TinyPtrVector<DbgInfoIntrinsic*> DbgDeclares;
+ DbgDeclareInst *DbgDeclare;
void clear() {
DefiningBlocks.clear();
@@ -112,7 +112,7 @@ struct AllocaInfo {
OnlyBlock = nullptr;
OnlyUsedInOneBlock = true;
AllocaPointerVal = nullptr;
- DbgDeclares.clear();
+ DbgDeclare = nullptr;
}
/// Scan the uses of the specified alloca, filling in the AllocaInfo used
@@ -147,7 +147,7 @@ struct AllocaInfo {
}
}
- DbgDeclares = FindDbgAddrUses(AI);
+ DbgDeclare = FindAllocaDbgDeclare(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<TinyPtrVector<DbgInfoIntrinsic *>, 8> AllocaDbgDeclares;
+ SmallVector<DbgDeclareInst *, 8> AllocaDbgDeclares;
/// The set of basic blocks the renamer has already visited.
///
@@ -409,11 +409,11 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
// Record debuginfo for the store and remove the declaration's
// debuginfo.
- for (DbgInfoIntrinsic *DII : Info.DbgDeclares) {
+ if (DbgDeclareInst *DDI = Info.DbgDeclare) {
DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
- ConvertDebugDeclareToDebugValue(DII, Info.OnlyStore, DIB);
- DII->eraseFromParent();
- LBI.deleteValue(DII);
+ ConvertDebugDeclareToDebugValue(DDI, Info.OnlyStore, DIB);
+ DDI->eraseFromParent();
+ LBI.deleteValue(DDI);
}
// Remove the (now dead) store and alloca.
Info.OnlyStore->eraseFromParent();
@@ -505,9 +505,9 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
while (!AI->use_empty()) {
StoreInst *SI = cast<StoreInst>(AI->user_back());
// Record debuginfo for the store before removing it.
- for (DbgInfoIntrinsic *DII : Info.DbgDeclares) {
+ if (DbgDeclareInst *DDI = Info.DbgDeclare) {
DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
- ConvertDebugDeclareToDebugValue(DII, SI, DIB);
+ ConvertDebugDeclareToDebugValue(DDI, SI, DIB);
}
SI->eraseFromParent();
LBI.deleteValue(SI);
@@ -517,9 +517,9 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
LBI.deleteValue(AI);
// The alloca's debuginfo can be removed as well.
- for (DbgInfoIntrinsic *DII : Info.DbgDeclares) {
- DII->eraseFromParent();
- LBI.deleteValue(DII);
+ if (DbgDeclareInst *DDI = Info.DbgDeclare) {
+ DDI->eraseFromParent();
+ LBI.deleteValue(DDI);
}
++NumLocalPromoted;
@@ -587,8 +587,8 @@ void PromoteMem2Reg::run() {
}
// Remember the dbg.declare intrinsic describing this alloca, if any.
- if (!Info.DbgDeclares.empty())
- AllocaDbgDeclares[AllocaNum] = Info.DbgDeclares;
+ if (Info.DbgDeclare)
+ AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;
// 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 (auto &Declares : AllocaDbgDeclares)
- for (auto *DII : Declares)
- DII->eraseFromParent();
+ for (DbgDeclareInst *DDI : AllocaDbgDeclares)
+ if (DDI)
+ DDI->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;
- for (DbgInfoIntrinsic *DII : AllocaDbgDeclares[AllocaNo])
- ConvertDebugDeclareToDebugValue(DII, APN, DIB);
+ if (DbgDeclareInst *DDI = AllocaDbgDeclares[AllocaNo])
+ ConvertDebugDeclareToDebugValue(DDI, 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.
- for (DbgInfoIntrinsic *DII : AllocaDbgDeclares[ai->second])
- ConvertDebugDeclareToDebugValue(DII, SI, DIB);
+ if (DbgDeclareInst *DDI = AllocaDbgDeclares[ai->second])
+ ConvertDebugDeclareToDebugValue(DDI, SI, DIB);
BB->getInstList().erase(SI);
}
}
diff --git a/test/DebugInfo/X86/dbg-addr-dse.ll b/test/DebugInfo/X86/dbg-addr-dse.ll
deleted file mode 100644
index b438982b994..00000000000
--- a/test/DebugInfo/X86/dbg-addr-dse.ll
+++ /dev/null
@@ -1,100 +0,0 @@
-; 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*)
-
-@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)
diff --git a/test/DebugInfo/X86/dbg-addr.ll b/test/DebugInfo/X86/dbg-addr.ll
deleted file mode 100644
index ffd0f77ebb7..00000000000
--- a/test/DebugInfo/X86/dbg-addr.ll
+++ /dev/null
@@ -1,67 +0,0 @@
-; 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)
diff --git a/test/DebugInfo/X86/sroasplit-5.ll b/test/DebugInfo/X86/sroasplit-5.ll
index 78f5ca9a979..dbd3b49a6cb 100644
--- a/test/DebugInfo/X86/sroasplit-5.ll
+++ b/test/DebugInfo/X86/sroasplit-5.ll
@@ -20,10 +20,10 @@ target triple = "x86_64-unknown-linux-gnu"
;
; There should be no debug info for the padding.
; 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
+; CHECK: DIExpression(DW_OP_LLVM_fragment, 0, 32)
+; CHECK-NOT: DW_OP_LLVM_fragment, 56
%struct.prog_src_register = type { i32, i24 }
; Function Attrs: nounwind
diff --git a/test/DebugInfo/X86/sroasplit-dbg-declare.ll b/test/DebugInfo/X86/sroasplit-dbg-declare.ll
deleted file mode 100644
index 0a1a41bd591..00000000000
--- a/test/DebugInfo/X86/sroasplit-dbg-declare.ll
+++ /dev/null
@@ -1,59 +0,0 @@
-; 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]*
-
diff --git a/test/Transforms/Mem2Reg/dbg-addr-inline-dse.ll b/test/Transforms/Mem2Reg/dbg-addr-inline-dse.ll
deleted file mode 100644
index 8fe2e0ab317..00000000000
--- a/test/Transforms/Mem2Reg/dbg-addr-inline-dse.ll
+++ /dev/null
@@ -1,94 +0,0 @@
-; 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
-
-@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)
diff --git a/test/Transforms/Mem2Reg/dbg-addr.ll b/test/Transforms/Mem2Reg/dbg-addr.ll
deleted file mode 100644
index 8c97f791a08..00000000000
--- a/test/Transforms/Mem2Reg/dbg-addr.ll
+++ /dev/null
@@ -1,91 +0,0 @@
-; 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)
diff --git a/test/Transforms/SROA/dbg-addr-diamond.ll b/test/Transforms/SROA/dbg-addr-diamond.ll
deleted file mode 100644
index 132da991464..00000000000
--- a/test/Transforms/SROA/dbg-addr-diamond.ll
+++ /dev/null
@@ -1,127 +0,0 @@
-; 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 }
-
-@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)