Index: llvm/lib/CodeGen/LiveDebugVariables.cpp =================================================================== --- llvm/lib/CodeGen/LiveDebugVariables.cpp +++ llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -38,9 +38,11 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/CodeGen/VirtRegMap.h" @@ -57,6 +59,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" #include #include #include @@ -394,10 +397,6 @@ LiveIntervals *LIS; const TargetRegisterInfo *TRI; - using StashedInstrRef = - std::tuple; - /// Position and VReg of a PHI instruction during register allocation. struct PHIValPos { SlotIndex SI; /// Slot where this PHI occurs. @@ -412,7 +411,17 @@ /// at different positions. DenseMap> RegToPHIIdx; - std::map> StashedInstrReferences; + /// Record for any debug instructions unlinked from their blocks during + /// regalloc. Stores the instr and it's location, so that they can be + /// re-inserted after regalloc is over. + struct InstrPos { + MachineInstr *MI; ///< Debug instruction, unlinked from it's block. + SlotIndex Idx; ///< Slot position where MI should be re-inserted. + MachineBasicBlock *MBB; ///< Block that MI was in. + }; + + /// Collection of stored debug instructions, preserved until after regalloc. + SmallVector StashedDebugInstrs; /// Whether emitDebugValues is called. bool EmitDone = false; @@ -450,15 +459,18 @@ /// \returns True if the DBG_VALUE instruction should be deleted. bool handleDebugValue(MachineInstr &MI, SlotIndex Idx); - /// Track a DBG_INSTR_REF. This needs to be removed from the MachineFunction - /// during regalloc -- but there's no need to maintain live ranges, as we - /// refer to a value rather than a location. + /// Track variable location debug instructions while using the instruction + /// referencing implementation. Such debug instructions do not need to be + /// updated during regalloc because they identify instructions rather than + /// register locations. However, they needs to be removed from the + /// MachineFunction during regalloc, then re-inserted later, to avoid + /// disrupting the allocator. /// - /// \param MI DBG_INSTR_REF instruction + /// \param MI Any DBG_VALUE / DBG_INSTR_REF / DBG_PHI instruction /// \param Idx Last valid SlotIndex before instruction /// - /// \returns True if the DBG_VALUE instruction should be deleted. - bool handleDebugInstrRef(MachineInstr &MI, SlotIndex Idx); + /// \returns Iterator to continue processing from after unlinking. + MachineBasicBlock::iterator handleDebugInstr(MachineInstr &MI, SlotIndex Idx); /// Add DBG_LABEL instruction to UserLabel. /// @@ -472,9 +484,11 @@ /// for each instruction. /// /// \param mf MachineFunction to be scanned. + /// \param InstrRef Whether to operate in instruction referencing mode. If + /// true, most of LiveDebugVariables doesn't run. /// /// \returns True if any debug values were found. - bool collectDebugValues(MachineFunction &mf); + bool collectDebugValues(MachineFunction &mf, bool InstrRef); /// Compute the live intervals of all user values after collecting all /// their def points. @@ -483,14 +497,14 @@ public: LDVImpl(LiveDebugVariables *ps) : pass(*ps) {} - bool runOnMachineFunction(MachineFunction &mf); + bool runOnMachineFunction(MachineFunction &mf, bool InstrRef); /// Release all memory. void clear() { MF = nullptr; PHIValToPos.clear(); RegToPHIIdx.clear(); - StashedInstrReferences.clear(); + StashedDebugInstrs.clear(); userValues.clear(); userLabels.clear(); virtRegToEqClass.clear(); @@ -702,17 +716,21 @@ return true; } -bool LDVImpl::handleDebugInstrRef(MachineInstr &MI, SlotIndex Idx) { - assert(MI.isDebugRef()); - unsigned InstrNum = MI.getOperand(0).getImm(); - unsigned OperandNum = MI.getOperand(1).getImm(); - auto *Var = MI.getDebugVariable(); - auto *Expr = MI.getDebugExpression(); - auto &DL = MI.getDebugLoc(); - StashedInstrRef Stashed = - std::make_tuple(InstrNum, OperandNum, Var, Expr, DL); - StashedInstrReferences[Idx].push_back(Stashed); - return true; +MachineBasicBlock::iterator LDVImpl::handleDebugInstr(MachineInstr &MI, + SlotIndex Idx) { + assert(MI.isDebugValue() || MI.isDebugRef() || MI.isDebugPHI()); + + // In instruction referencing mode, there should be no DBG_VALUE instructions + // that refer to virtual registers. They might still refer to constants. + if (MI.isDebugValue()) + assert(!MI.getOperand(0).isReg() || !MI.getOperand(0).getReg().isVirtual()); + + // Unlink the instruction, store it in the debug instructions collection. + auto NextInst = std::next(MI.getIterator()); + auto *MBB = MI.getParent(); + MI.removeFromParent(); + StashedDebugInstrs.push_back({&MI, Idx, MBB}); + return NextInst; } bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) { @@ -738,7 +756,7 @@ return true; } -bool LDVImpl::collectDebugValues(MachineFunction &mf) { +bool LDVImpl::collectDebugValues(MachineFunction &mf, bool InstrRef) { bool Changed = false; for (MachineFunction::iterator MFI = mf.begin(), MFE = mf.end(); MFI != MFE; ++MFI) { @@ -759,11 +777,16 @@ : LIS->getInstructionIndex(*std::prev(MBBI)).getRegSlot(); // Handle consecutive debug instructions with the same slot index. do { - // Only handle DBG_VALUE in handleDebugValue(). Skip all other - // kinds of debug instructions. - if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) || - (MBBI->isDebugRef() && handleDebugInstrRef(*MBBI, Idx)) || - (MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) { + // In instruction referencing mode, pass each instr to handleDebugInstr + // to be unlinked. + if (InstrRef && (MBBI->isDebugValue() || MBBI->isDebugPHI() || + MBBI->isDebugRef())) { + MBBI = handleDebugInstr(*MBBI, Idx); + Changed = true; + // In normal debug mode, use the dedicated DBG_VALUE / DBG_LABEL handler + // to track things through register allocation, and erase the instr. + } else if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) || + (MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) { MBBI = MBB->erase(MBBI); Changed = true; } else @@ -1027,7 +1050,7 @@ } } -bool LDVImpl::runOnMachineFunction(MachineFunction &mf) { +bool LDVImpl::runOnMachineFunction(MachineFunction &mf, bool InstrRef) { clear(); MF = &mf; LIS = &pass.getAnalysis(); @@ -1035,7 +1058,7 @@ LLVM_DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: " << mf.getName() << " **********\n"); - bool Changed = collectDebugValues(mf); + bool Changed = collectDebugValues(mf, InstrRef); computeIntervals(); LLVM_DEBUG(print(dbgs())); @@ -1076,9 +1099,19 @@ removeDebugValues(mf); return false; } + + // Have we been asked to track variable locations using instruction + // referencing? + bool InstrRef = false; + auto *TPC = getAnalysisIfAvailable(); + if (TPC) { + auto &TM = TPC->getTM(); + InstrRef = TM.Options.ValueTrackingVariableLocations; + } + if (!pImpl) pImpl = new LDVImpl(this); - return static_cast(pImpl)->runOnMachineFunction(mf); + return static_cast(pImpl)->runOnMachineFunction(mf, InstrRef); } void LiveDebugVariables::releaseMemory() { @@ -1592,21 +1625,46 @@ LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n"); - // Re-insert any DBG_INSTR_REFs back in the position they were. Ordering - // is preserved by vector. - const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF); - for (auto &P : StashedInstrReferences) { - const SlotIndex &Idx = P.first; - auto *MBB = Slots->getMBBFromIndex(Idx); - MachineBasicBlock::iterator insertPos = findInsertLocation(MBB, Idx, *LIS); - for (auto &Stashed : P.second) { - auto MIB = BuildMI(*MF, std::get<4>(Stashed), RefII); - MIB.addImm(std::get<0>(Stashed)); - MIB.addImm(std::get<1>(Stashed)); - MIB.addMetadata(std::get<2>(Stashed)); - MIB.addMetadata(std::get<3>(Stashed)); - MachineInstr *New = MIB; - MBB->insert(insertPos, New); + // Re-insert any debug instrs back in the position they were. Ordering + // is preserved by vector. We must re-insert in the same order to ensure that + // debug instructions don't swap, which could re-order assignments. + for (auto &P : StashedDebugInstrs) { + SlotIndex Idx = P.Idx; + + // Start block index: find the first non-debug instr in the block, and + // insert in front of it. + if (Idx == Slots->getMBBStartIdx(P.MBB)) { + auto It = P.MBB->instr_begin(); + auto PostDebug = skipDebugInstructionsForward(It, P.MBB->instr_end()); + P.MBB->insert(PostDebug, P.MI); + continue; + } + + MachineInstr *Pos = Slots->getInstructionFromIndex(Idx); + if (Pos) { + // Insert at the end of any debug instructions. + auto PostDebug = std::next(Pos->getIterator()); + PostDebug = skipDebugInstructionsForward(PostDebug, P.MBB->instr_end()); + P.MBB->insert(PostDebug, P.MI); + } else { + // Insert position disappeared; walk forwards through slots until we + // find a new one. + SlotIndex End = Slots->getMBBEndIdx(P.MBB); + for (; Idx < End; Idx = Slots->getNextNonNullIndex(Idx)) { + Pos = Slots->getInstructionFromIndex(Idx); + if (Pos) { + P.MBB->insert(Pos->getIterator(), P.MI); + break; + } + } + + // We have reached the end of the block and didn't find anywhere to + // insert! It's not safe to discard any debug instructions; place them + // in front of the first terminator, or in front of end(). + if (Idx >= End) { + auto TermIt = P.MBB->getFirstTerminator(); + P.MBB->insert(TermIt, P.MI); + } } } Index: llvm/lib/CodeGen/ScheduleDAGInstrs.cpp =================================================================== --- llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -804,7 +804,7 @@ DbgMI = nullptr; } - if (MI.isDebugValue() || MI.isDebugRef()) { + if (MI.isDebugValue() || MI.isDebugRef() || MI.isDebugPHI()) { DbgMI = &MI; continue; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5378,6 +5378,35 @@ if (!Arg) return false; + MachineFunction &MF = DAG.getMachineFunction(); + const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo(); + + // Helper to create DBG_INSTR_REFs or DBG_VALUEs, depending on what kind + // we've been asked to pursue. + auto MakeVRegDbgValue = [&](Register Reg, DIExpression *FragExpr, + bool Indirect) { + if (Reg.isVirtual() && TM.Options.ValueTrackingVariableLocations) { + // For VRegs, in instruction referencing mode, create a DBG_INSTR_REF + // pointing at the VReg, which will be patched up later. + auto &Inst = TII->get(TargetOpcode::DBG_INSTR_REF); + auto MIB = BuildMI(MF, DL, Inst); + MIB.addReg(Reg); + MIB.addImm(0); + MIB.addMetadata(Variable); + auto *NewDIExpr = FragExpr; + // We don't have an "Indirect" field in DBG_INSTR_REF, fold that into + // the DIExpression. + if (IsDbgDeclare) + NewDIExpr = DIExpression::prepend(FragExpr, DIExpression::DerefBefore); + MIB.addMetadata(NewDIExpr); + return MIB; + } else { + // Create a completely standard DBG_VALUE. + auto &Inst = TII->get(TargetOpcode::DBG_VALUE); + return BuildMI(MF, DL, Inst, Indirect, Reg, Variable, FragExpr); + } + }; + if (!IsDbgDeclare) { // ArgDbgValues are hoisted to the beginning of the entry block. So we // should only emit as ArgDbgValue if the dbg.value intrinsic is found in @@ -5443,9 +5472,6 @@ } } - MachineFunction &MF = DAG.getMachineFunction(); - const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo(); - bool IsIndirect = false; Optional Op; // Some arguments' frame index is recorded during argument lowering. @@ -5516,9 +5542,9 @@ continue; } assert(!IsDbgDeclare && "DbgDeclare operand is not in memory?"); - FuncInfo.ArgDbgValues.push_back( - BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), IsDbgDeclare, - RegAndSize.first, Variable, *FragmentExpr)); + MachineInstr *NewMI = + MakeVRegDbgValue(RegAndSize.first, *FragmentExpr, false); + FuncInfo.ArgDbgValues.push_back(NewMI); } }; @@ -5549,11 +5575,15 @@ assert(Variable->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); - IsIndirect = (Op->isReg()) ? IsIndirect : true; - FuncInfo.ArgDbgValues.push_back( - BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), IsIndirect, - *Op, Variable, Expr)); + MachineInstr *NewMI = nullptr; + + if (Op->isReg()) + NewMI = MakeVRegDbgValue(Op->getReg(), Expr, IsDbgDeclare); + else + NewMI = BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), true, *Op, + Variable, Expr); + FuncInfo.ArgDbgValues.push_back(NewMI); return true; } Index: llvm/lib/Target/X86/X86InstrInfo.cpp =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.cpp +++ llvm/lib/Target/X86/X86InstrInfo.cpp @@ -4076,6 +4076,8 @@ } CmpInstr.setDesc(get(NewOpcode)); CmpInstr.RemoveOperand(0); + // Mutating this instruction invalidates any debug data associated with it. + CmpInstr.setDebugInstrNum(0); // Fall through to optimize Cmp if Cmp is CMPrr or CMPri. if (NewOpcode == X86::CMP64rm || NewOpcode == X86::CMP32rm || NewOpcode == X86::CMP16rm || NewOpcode == X86::CMP8rm) Index: llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir =================================================================== --- llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir +++ llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir @@ -153,8 +153,6 @@ %3:gr32 = COPY $edi %6:gr16 = COPY %4.sub_16bit %5:gr16 = COPY %3.sub_16bit - DBG_VALUE %5, $noreg, !12, !DIExpression(), debug-location !13 - DBG_VALUE %6, $noreg, !14, !DIExpression(), debug-location !13 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !15 %15:gr32 = MOVSX32rr16 %5, debug-location !15 $edi = COPY %15, debug-location !15 @@ -163,7 +161,6 @@ %14:gr32 = MOVSX32rr16 %5, debug-location !16 %13:gr32 = ADD32ri8 killed %14, 12, implicit-def $eflags, debug-location !16 %11:gr16 = COPY killed %13.sub_16bit, debug-location !16 - DBG_VALUE %11, $noreg, !12, !DIExpression(), debug-location !13 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !17 %9:gr32 = MOVSX32rr16 %11, debug-location !17 $edi = COPY %9, debug-location !17 @@ -182,14 +179,12 @@ %20:gr32 = MOVSX32rr16 %11, debug-location !21 %19:gr32 = ADD32ri8 killed %20, 1, implicit-def $eflags, debug-location !21 %17:gr16 = COPY killed %19.sub_16bit, debug-location !21 - DBG_VALUE %17, $noreg, !12, !DIExpression(), debug-location !13 - ; Verify that vreg 17 is coalesced into gr32. + ; Verify that vreg 17 is coalesced into a gr32, and not copied any further. ; DOESCOALESCE: %{{[0-9]+}}:gr32 = ADD32ri8 - ; DOESCOALESCE-NEXT: DBG_VALUE %{{[0-9]+}}.sub_16bit, + ; DOESCOALESCE-NOT: COPY ; Verify those registers land in $bx ; CHECK: renamable $ebx = ADD32ri8 - ; CHECK-NEXT: DBG_VALUE $bx ; DOESCOALESCE-LABEL: bb.2.if.end: ; CHECK-LABEL: bb.2.if.end: @@ -201,7 +196,6 @@ %30:gr32 = MOVSX32rr16 killed %2, debug-location !24 %29:gr32 = ADD32rr killed %30, killed %31, implicit-def $eflags, debug-location !24 %26:gr16 = COPY killed %29.sub_16bit, debug-location !24 - DBG_VALUE %26, $noreg, !12, !DIExpression(), debug-location !13 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !25 %24:gr32 = MOVSX32rr16 %26, debug-location !25 $edi = COPY %24, debug-location !25 Index: llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir =================================================================== --- llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir +++ llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir @@ -14,7 +14,7 @@ # # Original C code, the PHI is of the value of 'bar' after the control flow. # Compiled at -O0, applied -mem2reg, llc -O0, then manually added the PHI -# instruction label. +# instruction label. Additional variable locations removed. # # void ext(long); # long getlong(void); @@ -144,14 +144,11 @@ %3:gr64 = COPY $rdi %4:gr64 = COPY killed %3 %6:gr64 = COPY killed %5 - DBG_VALUE %4, $noreg, !12, !DIExpression(), debug-location !13 - DBG_VALUE %6, $noreg, !14, !DIExpression(), debug-location !13 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !15 $rdi = COPY %4, debug-location !15 CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !15 ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !15 %9:gr64 = ADD64ri32 %4, 12, implicit-def $eflags, debug-location !16 - DBG_VALUE %9, $noreg, !12, !DIExpression(), debug-location !13 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !17 $rdi = COPY %9, debug-location !17 CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !17 @@ -167,7 +164,6 @@ ; CHECK-LABEL: bb.1.if.then: bb.1.if.then: %10:gr64 = ADD64ri32 %9, 1, implicit-def $eflags, debug-location !21 - DBG_VALUE %10, $noreg, !12, !DIExpression(), debug-location !13 ; Verify that the vreg is different immediately after register coalescing. ; DOESCOALESCE-NOT: %10:gr64 ADD64ri32 @@ -182,7 +178,6 @@ ; CHECK: DBG_PHI $rbx, 1 DBG_INSTR_REF 1, 0, !12, !DIExpression(), debug-location !13 %14:gr64 = ADD64rr killed %2, %6, implicit-def $eflags, debug-location !23 - DBG_VALUE %14, $noreg, !12, !DIExpression(), debug-location !13 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !24 $rdi = COPY %14, debug-location !24 CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !24 Index: llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir =================================================================== --- llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir +++ llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir @@ -82,10 +82,7 @@ DBG_VALUE $edi, $noreg, !11, !DIExpression(), debug-location !12 DBG_VALUE $esi, $noreg, !13, !DIExpression(), debug-location !12 %2:gr32 = COPY killed $esi - DBG_VALUE %2, $noreg, !13, !DIExpression(), debug-location !12 %1:gr32 = COPY killed $edi - DBG_VALUE %1, $noreg, !11, !DIExpression(), debug-location !12 - DBG_VALUE 0, $noreg, !14, !DIExpression(), debug-location !12 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !15 %3:gr32 = MOV32r0 implicit-def dead $eflags $edi = COPY killed %3, debug-location !15 @@ -112,7 +109,6 @@ JMP_1 %bb.1, debug-location !17 bb.1: - DBG_VALUE %2, $noreg, !14, !DIExpression(), debug-location !12 %30:gr32 = MOV32ri 0 %31:gr32 = MOV32ri 1 %32:gr32 = MOV32ri 2 Index: llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir =================================================================== --- llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir +++ llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir @@ -108,9 +108,7 @@ DBG_VALUE $edi, $noreg, !11, !DIExpression(), debug-location !12 DBG_VALUE $esi, $noreg, !13, !DIExpression(), debug-location !12 %2:gr32 = COPY killed $esi - DBG_VALUE %2, $noreg, !13, !DIExpression(), debug-location !12 %1:gr32 = COPY killed $edi - DBG_VALUE %1, $noreg, !11, !DIExpression(), debug-location !12 DBG_VALUE 0, $noreg, !14, !DIExpression(), debug-location !12 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !15 %3:gr32 = MOV32r0 implicit-def dead $eflags @@ -123,8 +121,6 @@ JMP_1 %bb.1, debug-location !17 bb.1.if.else: - DBG_VALUE %2, $noreg, !14, !DIExpression(), debug-location !12 - ; CHECK-LABEL: bb.2.if.end: bb.2.if.end: