const ConstantInt *CImm;
} Loc;
- VarLoc(const MachineInstr &MI, LexicalScopes &LS,
- VarLocKind K = InvalidKind)
+ VarLoc(const MachineInstr &MI, LexicalScopes &LS)
: Var(MI), Expr(MI.getDebugExpression()), MI(MI),
UVS(MI.getDebugLoc(), LS) {
static_assert((sizeof(Loc) == sizeof(uint64_t)),
"entry values must be register locations");
}
- /// The constructor for spill locations.
- VarLoc(const MachineInstr &MI, unsigned SpillBase, int SpillOffset,
- LexicalScopes &LS, const MachineInstr &OrigMI)
- : Var(MI), Expr(MI.getDebugExpression()), MI(OrigMI),
- UVS(MI.getDebugLoc(), LS) {
- assert(MI.isDebugValue() && "not a DBG_VALUE");
- assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
- Kind = SpillLocKind;
- Loc.SpillLocation = {SpillBase, SpillOffset};
+ /// Take the variable and machine-location in DBG_VALUE MI, and build an
+ /// entry location using the given expression.
+ static VarLoc CreateEntryLoc(const MachineInstr &MI, LexicalScopes &LS,
+ const DIExpression *EntryExpr) {
+ VarLoc VL(MI, LS);
+ VL.Kind = EntryValueKind;
+ VL.Expr = EntryExpr;
+ return VL;
+ }
+
+ /// Copy the register location in DBG_VALUE MI, updating the register to
+ /// be NewReg.
+ static VarLoc CreateCopyLoc(const MachineInstr &MI, LexicalScopes &LS,
+ unsigned NewReg) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Loc.RegNo = NewReg;
+ return VL;
+ }
+
+ /// Take the variable described by DBG_VALUE MI, and create a VarLoc
+ /// locating it in the specified spill location.
+ static VarLoc CreateSpillLoc(const MachineInstr &MI, unsigned SpillBase,
+ int SpillOffset, LexicalScopes &LS) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Kind = SpillLocKind;
+ VL.Loc.SpillLocation = {SpillBase, SpillOffset};
+ return VL;
}
- // Is the Loc field a constant or constant object?
+ /// Create a DBG_VALUE representing this VarLoc in the given function.
+ /// Copies variable-specific information such as DILocalVariable and
+ /// inlining information from the original DBG_VALUE instruction, which may
+ /// have been several transfers ago.
+ MachineInstr *BuildDbgValue(MachineFunction &MF) const {
+ const DebugLoc &DbgLoc = MI.getDebugLoc();
+ bool Indirect = MI.isIndirectDebugValue();
+ const auto &IID = MI.getDesc();
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *DIExpr = MI.getDebugExpression();
+
+ switch (Kind) {
+ case EntryValueKind:
+ // An entry value is a register location -- but with an updated
+ // expression.
+ return BuildMI(MF, DbgLoc, IID, Indirect, Loc.RegNo, Var, Expr);
+ case RegisterKind:
+ // Register locations are like the source DBG_VALUE, but with the
+ // register number from this VarLoc.
+ return BuildMI(MF, DbgLoc, IID, Indirect, Loc.RegNo, Var, DIExpr);
+ case SpillLocKind: {
+ // Spills are indirect DBG_VALUEs, with a base register and offset.
+ // Use the original DBG_VALUEs expression to build the spilt location
+ // on top of. FIXME: spill locations created before this pass runs
+ // are not recognized, and not handled here.
+ auto *SpillExpr = DIExpression::prepend(
+ DIExpr, DIExpression::ApplyOffset, Loc.SpillLocation.SpillOffset);
+ unsigned Base = Loc.SpillLocation.SpillBase;
+ return BuildMI(MF, DbgLoc, IID, true, Base, Var, SpillExpr);
+ }
+ case ImmediateKind: {
+ MachineOperand MO = MI.getOperand(0);
+ return BuildMI(MF, DbgLoc, IID, Indirect, MO, Var, DIExpr);
+ }
+ case InvalidKind:
+ llvm_unreachable("Tried to produce DBG_VALUE for invalid VarLoc");
+ }
+ }
+
+ /// Is the Loc field a constant or constant object?
bool isConstant() const { return Kind == ImmediateKind; }
/// If this variable is described by a register, return it,
bool dominates(MachineBasicBlock &MBB) const { return UVS.dominates(&MBB); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const { MI.dump(); }
+ // TRI can be null.
+ void dump(const TargetRegisterInfo *TRI, raw_ostream &Out = dbgs()) const {
+ dbgs() << "VarLoc(";
+ switch (Kind) {
+ case RegisterKind:
+ case EntryValueKind:
+ dbgs() << printReg(Loc.RegNo, TRI);
+ break;
+ case SpillLocKind:
+ dbgs() << printReg(Loc.SpillLocation.SpillBase, TRI);
+ dbgs() << "[" << Loc.SpillLocation.SpillOffset << "]";
+ break;
+ case ImmediateKind:
+ dbgs() << Loc.Immediate;
+ break;
+ case InvalidKind:
+ llvm_unreachable("Invalid VarLoc in dump method");
+ }
+
+ dbgs() << ", \"" << Var.getVar()->getName() << "\", " << *Expr << ", ";
+ if (Var.getInlinedAt())
+ dbgs() << "!" << Var.getInlinedAt()->getMetadataID() << ")\n";
+ else
+ dbgs() << "(null))\n";
+ }
#endif
bool operator==(const VarLoc &Other) const {
using VarLocSet = SparseBitVector<>;
using VarLocInMBB = SmallDenseMap<const MachineBasicBlock *, VarLocSet>;
struct TransferDebugPair {
- MachineInstr *TransferInst;
- MachineInstr *DebugInst;
+ MachineInstr *TransferInst; /// Instruction where this transfer occurs.
+ unsigned LocationID; /// Location number for the transfer dest.
};
using TransferMap = SmallVector<TransferDebugPair, 4>;
const VarLoc &VL = VarLocIDs[VLL];
Out << " Var: " << VL.Var.getVar()->getName();
Out << " MI: ";
- VL.dump();
+ VL.dump(TRI, Out);
}
}
Out << "\n";
TransferMap &Transfers,
DebugParamMap &DebugEntryVals,
SparseBitVector<> &KillSet) {
- MachineFunction *MF = MI.getParent()->getParent();
for (unsigned ID : KillSet) {
if (!VarLocIDs[ID].Var.getVar()->isParameter())
continue;
auto ParamDebugInstr = DebugEntryVals[CurrDebugInstr->getDebugVariable()];
DIExpression *NewExpr = DIExpression::prepend(
ParamDebugInstr->getDebugExpression(), DIExpression::EntryValue);
- MachineInstr *EntryValDbgMI =
- BuildMI(*MF, ParamDebugInstr->getDebugLoc(), ParamDebugInstr->getDesc(),
- ParamDebugInstr->isIndirectDebugValue(),
- ParamDebugInstr->getOperand(0).getReg(),
- ParamDebugInstr->getDebugVariable(), NewExpr);
-
- if (ParamDebugInstr->isIndirectDebugValue())
- EntryValDbgMI->getOperand(1).setImm(
- ParamDebugInstr->getOperand(1).getImm());
-
- Transfers.push_back({&MI, EntryValDbgMI});
- VarLoc VL(*EntryValDbgMI, LS);
- unsigned EntryValLocID = VarLocIDs.insert(VL);
- OpenRanges.insert(EntryValLocID, VL.Var);
+
+ VarLoc EntryLoc = VarLoc::CreateEntryLoc(*ParamDebugInstr, LS, NewExpr);
+
+ unsigned EntryValLocID = VarLocIDs.insert(EntryLoc);
+ Transfers.push_back({&MI, EntryValLocID});
+ OpenRanges.insert(EntryValLocID, EntryLoc.Var);
}
}
VarLocMap &VarLocIDs, unsigned OldVarID, TransferKind Kind,
unsigned NewReg) {
const MachineInstr *DebugInstr = &VarLocIDs[OldVarID].MI;
- MachineFunction *MF = MI.getParent()->getParent();
- MachineInstr *NewDebugInstr;
auto ProcessVarLoc = [&MI, &OpenRanges, &Transfers, &DebugInstr,
- &VarLocIDs](VarLoc &VL, MachineInstr *NewDebugInstr) {
+ &VarLocIDs](VarLoc &VL) {
unsigned LocId = VarLocIDs.insert(VL);
// Close this variable's previous location range.
DebugVariable V(*DebugInstr);
OpenRanges.erase(V);
+ // Record the new location as an open range, and a postponed transfer
+ // inserting a DBG_VALUE for this location.
OpenRanges.insert(LocId, VL.Var);
- // The newly created DBG_VALUE instruction NewDebugInstr must be inserted
- // after MI. Keep track of the pairing.
- TransferDebugPair MIP = {&MI, NewDebugInstr};
+ TransferDebugPair MIP = {&MI, LocId};
Transfers.push_back(MIP);
};
"No register supplied when handling a copy of a debug value");
// Create a DBG_VALUE instruction to describe the Var in its new
// register location.
- NewDebugInstr = BuildMI(
- *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(),
- DebugInstr->isIndirectDebugValue(), NewReg,
- DebugInstr->getDebugVariable(), DebugInstr->getDebugExpression());
- if (DebugInstr->isIndirectDebugValue())
- NewDebugInstr->getOperand(1).setImm(DebugInstr->getOperand(1).getImm());
- VarLoc VL(*NewDebugInstr, LS);
- ProcessVarLoc(VL, NewDebugInstr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register copy: ";
- NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
- /*SkipOpers*/false, /*SkipDebugLoc*/false,
- /*AddNewLine*/true, TII));
+ VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for register copy:";
+ VL.dump(TRI);
+ });
return;
}
case TransferKind::TransferSpill: {
// Create a DBG_VALUE instruction to describe the Var in its spilled
// location.
VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
- auto *SpillExpr = DIExpression::prepend(DebugInstr->getDebugExpression(),
- DIExpression::ApplyOffset,
- SpillLocation.SpillOffset);
- NewDebugInstr = BuildMI(
- *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), true,
- SpillLocation.SpillBase, DebugInstr->getDebugVariable(), SpillExpr);
- VarLoc VL(*NewDebugInstr, SpillLocation.SpillBase,
- SpillLocation.SpillOffset, LS, *DebugInstr);
- ProcessVarLoc(VL, NewDebugInstr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
- NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
- /*SkipOpers*/false, /*SkipDebugLoc*/false,
- /*AddNewLine*/true, TII));
+ VarLoc VL = VarLoc::CreateSpillLoc(*DebugInstr, SpillLocation.SpillBase,
+ SpillLocation.SpillOffset, LS);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for spill:";
+ VL.dump(TRI);
+ });
return;
}
case TransferKind::TransferRestore: {
DIBuilder DIB(*const_cast<Function &>(MF->getFunction()).getParent());
// DebugInstr refers to the pre-spill location, therefore we can reuse
// its expression.
- NewDebugInstr = BuildMI(
- *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), false, NewReg,
- DebugInstr->getDebugVariable(), DebugInstr->getDebugExpression());
- VarLoc VL(*NewDebugInstr, LS);
- ProcessVarLoc(VL, NewDebugInstr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register restore: ";
- NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
- /*SkipOpers*/false, /*SkipDebugLoc*/false,
- /*AddNewLine*/true, TII));
+ VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for restore:";
+ VL.dump(TRI);
+ });
return;
}
}
// At this stage, we already know which DBG_VALUEs are for spills and
// where they are located; it's best to fix handle overwrites now.
KillSet.set(ID);
- MachineInstr *NewDebugInstr =
- BuildMI(*MF, VL.MI.getDebugLoc(), VL.MI.getDesc(),
- VL.MI.isIndirectDebugValue(), 0, // $noreg
- VL.MI.getDebugVariable(), VL.MI.getDebugExpression());
- Transfers.push_back({&MI, NewDebugInstr});
+ VarLoc UndefVL = VarLoc::CreateCopyLoc(VL.MI, LS, 0);
+ unsigned UndefLocID = VarLocIDs.insert(UndefVL);
+ Transfers.push_back({&MI, UndefLocID});
}
}
OpenRanges.erase(KillSet, VarLocIDs);
: OpenRanges.getVarLocs()) {
// Copy OpenRanges to OutLocs, if not already present.
dbgs() << "Add to OutLocs in MBB #" << CurMBB->getNumber() << ": ";
- VarLocIDs[ID].dump();
+ VarLocIDs[ID].dump(TRI);
});
VarLocSet &VLS = OutLocs[CurMBB];
Changed = VLS != OpenRanges.getVarLocs();
// The ID location is live-in to MBB -- work out what kind of machine
// location it is and create a DBG_VALUE.
const VarLoc &DiffIt = VarLocIDs[ID];
- const MachineInstr *DebugInstr = &DiffIt.MI;
- MachineInstr *MI = nullptr;
-
- if (DiffIt.isConstant()) {
- MachineOperand MO(DebugInstr->getOperand(0));
- MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), false, MO,
- DebugInstr->getDebugVariable(),
- DebugInstr->getDebugExpression());
- } else {
- auto *DebugExpr = DebugInstr->getDebugExpression();
- Register Reg = DebugInstr->getOperand(0).getReg();
- bool IsIndirect = DebugInstr->isIndirectDebugValue();
-
- if (DiffIt.Kind == VarLoc::SpillLocKind) {
- // This is is a spilt location; DebugInstr refers to the unspilt
- // location. We need to rebuild the spilt location expression and
- // point the DBG_VALUE at the frame register.
- DebugExpr = DIExpression::prepend(
- DebugInstr->getDebugExpression(), DIExpression::ApplyOffset,
- DiffIt.Loc.SpillLocation.SpillOffset);
- Reg = TRI->getFrameRegister(*DebugInstr->getMF());
- IsIndirect = true;
- }
+ MachineInstr *MI = DiffIt.BuildDbgValue(*MBB.getParent());
+ MBB.insert(MBB.instr_begin(), MI);
- MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), IsIndirect, Reg,
- DebugInstr->getDebugVariable(), DebugExpr);
- }
(void)MI;
LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
}
// Add any DBG_VALUE instructions created by location transfers.
for (auto &TR : Transfers) {
- auto *MBB = TR.TransferInst->getParent();
- MBB->insertAfterBundle(TR.TransferInst->getIterator(), TR.DebugInst);
+ MachineBasicBlock *MBB = TR.TransferInst->getParent();
+ const VarLoc &VL = VarLocIDs[TR.LocationID];
+ MachineInstr *MI = VL.BuildDbgValue(MF);
+ MBB->insertAfterBundle(TR.TransferInst->getIterator(), MI);
}
Transfers.clear();
# 'g': test for a crash from PR42773
# 'h': complex expressions should be restored
# 'i': spills should be restored across block boundaries
+# 'j': indirect DBG_VALUEs should be indirect after restoration
# #define FORCE_SPILL() \
# __asm volatile("" : : : \
# CHECK: ![[QVAR:[0-9]+]] = !DILocalVariable(name: "q",
# CHECK: ![[RVAR:[0-9]+]] = !DILocalVariable(name: "r",
# CHECK: ![[SVAR:[0-9]+]] = !DILocalVariable(name: "s",
+# CHECK: ![[TVAR:[0-9]+]] = !DILocalVariable(name: "t",
# Ascertain that the spill has been recognized and manifested in a DBG_VALUE.
# CHECK: MOV64mr $rsp,{{.*-8.*}}killed{{.*}}$rdi :: (store 8 into %stack.0)
%0 = load i32, i32* %add.ptr, align 4, !dbg !223, !tbaa !24
ret i32 %0, !dbg !228
}
-
+
define dso_local i32 @i(i32* readonly %p) local_unnamed_addr !dbg !307 {
entry:
br label %foo
ret i32 %0, !dbg !328
}
+ define dso_local i32 @j(i32* readonly %p) local_unnamed_addr !dbg !402 {
+ entry:
+ br label %foo
+
+ foo:
+ call void @llvm.dbg.value(metadata i32* %p, metadata !404, metadata !DIExpression()), !dbg !405
+ %tobool = icmp eq i32* %p, null, !dbg !406
+ br i1 %tobool, label %if.end, label %if.then, !dbg !408
+
+ if.then: ; preds = %entry
+ tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !409, !srcloc !411
+ br label %if.end, !dbg !412
+
+ if.end: ; preds = %entry, %if.then
+ %add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !413
+ %0 = load i32, i32* %add.ptr, align 4, !dbg !414, !tbaa !24
+ ret i32 %0, !dbg !415
+ }
+
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!0}
!322 = !DILocation(line: 109, column: 14, scope: !307)
!323 = !DILocation(line: 109, column: 10, scope: !307)
!328 = !DILocation(line: 109, column: 3, scope: !307)
+ !401 = !DIBasicType(name: "looong int", size: 64, encoding: DW_ATE_signed)
+ !402 = distinct !DISubprogram(name: "j", scope: !0, file: !1, line: 105, type: !8, scopeLine: 105, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !403)
+ !403 = !{!404}
+ !404 = !DILocalVariable(name: "t", arg: 1, scope: !402, file: !1, line: 105, type: !401)
+ !405 = !DILocation(line: 105, column: 12, scope: !402)
+ !406 = !DILocation(line: 106, column: 7, scope: !407)
+ !407 = distinct !DILexicalBlock(scope: !402, file: !1, line: 106, column: 7)
+ !408 = !DILocation(line: 106, column: 7, scope: !402)
+ !409 = !DILocation(line: 107, column: 5, scope: !410)
+ !410 = distinct !DILexicalBlock(scope: !407, file: !1, line: 106, column: 10)
+ !411 = !{i32 -2147471544}
+ !412 = !DILocation(line: 108, column: 3, scope: !410)
+ !413 = !DILocation(line: 109, column: 14, scope: !402)
+ !414 = !DILocation(line: 109, column: 10, scope: !402)
+ !415 = !DILocation(line: 109, column: 3, scope: !402)
...
---
name: f
RETQ $eax, debug-location !328
...
+---
+# Test that if an unspilt DBG_VALUE starts as an indirect DBG_VALUE, then it
+# is restored as an indirect DBG_VALUE. FIXME: Note that for the intervening
+# period of being a spilt location there is still a missing layer of
+# indirection.
+
+# CHECK-LABEL: name: j
+# CHECK-LABEL: bb.0.entry:
+# CHECK: DBG_VALUE $rdi, 0, ![[TVAR]], !DIExpression()
+# CHECK-LABEL: bb.1.if.then:
+# CHECK: DBG_VALUE $rsp, 0, ![[TVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus)
+# CHECK: INLINEASM
+# CHECK: DBG_VALUE ${{[a-zA-Z0-9]+}}, 0, ![[TVAR]], !DIExpression()
+# CHECK-LABEL: bb.2.if.end
+
+name: j
+tracksRegLiveness: true
+liveins:
+ - { reg: '$rdi', virtual-reg: '' }
+frameInfo:
+ stackSize: 48
+ offsetAdjustment: -48
+ maxAlignment: 8
+ cvBytesOfCalleeSavedRegisters: 48
+fixedStack:
+ - { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
+ callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
+ callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
+ callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
+ callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
+ callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+ - { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
+ callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+stack:
+ - { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+constants: []
+body: |
+ bb.0.entry:
+ successors: %bb.2, %bb.1
+ liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
+
+ DBG_VALUE $rdi, 0, !404, !DIExpression(), debug-location !405
+ DBG_VALUE $rdi, 0, !404, !DIExpression(), debug-location !405
+ TEST64rr renamable $rdi, renamable $rdi, implicit-def $eflags, debug-location !406
+ JCC_1 %bb.2, 4, implicit $eflags, debug-location !408
+
+ bb.1.if.then:
+ successors: %bb.2
+ liveins: $rdi, $rbp, $r15, $r14, $r13, $r12, $rbx
+
+ frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 16
+ frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 24
+ frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 32
+ frame-setup PUSH64r killed $r13, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 40
+ frame-setup PUSH64r killed $r12, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 48
+ frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 56
+ CFI_INSTRUCTION offset $rbx, -56
+ CFI_INSTRUCTION offset $r12, -48
+ CFI_INSTRUCTION offset $r13, -40
+ CFI_INSTRUCTION offset $r14, -32
+ CFI_INSTRUCTION offset $r15, -24
+ CFI_INSTRUCTION offset $rbp, -16
+ MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
+ INLINEASM &"", 1, 12, implicit-def dead early-clobber $rax, 12, implicit-def dead early-clobber $rbx, 12, implicit-def dead early-clobber $rcx, 12, implicit-def dead early-clobber $rdx, 12, implicit-def dead early-clobber $rsi, 12, implicit-def dead early-clobber $rdi, 12, implicit-def dead early-clobber $rbp, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def dead early-clobber $r13, 12, implicit-def dead early-clobber $r14, 12, implicit-def dead early-clobber $r15, 12, implicit-def dead early-clobber $eflags, !20, debug-location !409
+ renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
+ $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 48
+ $r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 40
+ $r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 32
+ $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 24
+ $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 16
+ $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 8
+
+ bb.2.if.end:
+ liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
+
+ renamable $eax = MOV32rm killed renamable $rdi, 1, $noreg, 4, $noreg, debug-location !414 :: (load 4 from %ir.add.ptr, !tbaa !24)
+ RETQ $eax, debug-location !415
+
+...