diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 216462ec16a36..73864497bb699 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1385,7 +1385,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, if (!V) { // Currently the optimizer can produce this; insert an undef to // help debugging. Probably the optimizer should not do this. - MIRBuilder.buildDirectDbgValue(0, DI.getVariable(), DI.getExpression()); + MIRBuilder.buildIndirectDbgValue(0, DI.getVariable(), DI.getExpression()); } else if (const auto *CI = dyn_cast(V)) { MIRBuilder.buildConstDbgValue(*CI, DI.getVariable(), DI.getExpression()); } else { diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 67d9dacda61b8..3f6622723bdca 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -107,13 +107,9 @@ MachineIRBuilder::buildIndirectDbgValue(Register Reg, const MDNode *Variable, assert( cast(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - // DBG_VALUE insts now carry IR-level indirection in their DIExpression - // rather than encoding it in the instruction itself. - const DIExpression *DIExpr = cast(Expr); - DIExpr = DIExpression::append(DIExpr, {dwarf::DW_OP_deref}); return insertInstr(BuildMI(getMF(), getDL(), getTII().get(TargetOpcode::DBG_VALUE), - /*IsIndirect*/ false, Reg, Variable, DIExpr)); + /*IsIndirect*/ true, Reg, Variable, Expr)); } MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI, @@ -124,15 +120,11 @@ MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI, assert( cast(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - // DBG_VALUE insts now carry IR-level indirection in their DIExpression - // rather than encoding it in the instruction itself. - const DIExpression *DIExpr = cast(Expr); - DIExpr = DIExpression::append(DIExpr, {dwarf::DW_OP_deref}); return buildInstr(TargetOpcode::DBG_VALUE) .addFrameIndex(FI) - .addReg(0) + .addImm(0) .addMetadata(Variable) - .addMetadata(DIExpr); + .addMetadata(Expr); } MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, @@ -156,7 +148,7 @@ MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, MIB.addReg(0U); } - return MIB.addReg(0).addMetadata(Variable).addMetadata(Expr); + return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr); } MachineInstrBuilder MachineIRBuilder::buildDbgLabel(const MDNode *Label) { diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp index 0bd0c27cb0e82..5b20a2482b7b9 100644 --- a/llvm/lib/CodeGen/LiveDebugVariables.cpp +++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -100,27 +100,28 @@ enum : unsigned { UndefLocNo = ~0U }; /// usage of the location. class DbgValueLocation { public: - DbgValueLocation(unsigned LocNo) - : LocNo(LocNo) { + DbgValueLocation(unsigned LocNo, bool WasIndirect) + : LocNo(LocNo), WasIndirect(WasIndirect) { static_assert(sizeof(*this) == sizeof(unsigned), "bad bitfield packing"); assert(locNo() == LocNo && "location truncation"); } - DbgValueLocation() : LocNo(0) {} + DbgValueLocation() : LocNo(0), WasIndirect(0) {} unsigned locNo() const { // Fix up the undef location number, which gets truncated. return LocNo == INT_MAX ? UndefLocNo : LocNo; } + bool wasIndirect() const { return WasIndirect; } bool isUndef() const { return locNo() == UndefLocNo; } DbgValueLocation changeLocNo(unsigned NewLocNo) const { - return DbgValueLocation(NewLocNo); + return DbgValueLocation(NewLocNo, WasIndirect); } friend inline bool operator==(const DbgValueLocation &LHS, const DbgValueLocation &RHS) { - return LHS.LocNo == RHS.LocNo; + return LHS.LocNo == RHS.LocNo && LHS.WasIndirect == RHS.WasIndirect; } friend inline bool operator!=(const DbgValueLocation &LHS, @@ -129,7 +130,8 @@ class DbgValueLocation { } private: - unsigned LocNo; + unsigned LocNo : 31; + unsigned WasIndirect : 1; }; /// Map of where a user value is live, and its location. @@ -283,8 +285,8 @@ class UserValue { void mapVirtRegs(LDVImpl *LDV); /// Add a definition point to this value. - void addDef(SlotIndex Idx, const MachineOperand &LocMO) { - DbgValueLocation Loc(getLocationNo(LocMO)); + void addDef(SlotIndex Idx, const MachineOperand &LocMO, bool IsIndirect) { + DbgValueLocation Loc(getLocationNo(LocMO), IsIndirect); // Add a singular (Idx,Idx) -> Loc mapping. LocMap::iterator I = locInts.find(Idx); if (!I.valid() || I.start() != Idx) @@ -319,10 +321,11 @@ class UserValue { /// /// \param LI Scan for copies of the value in LI->reg. /// \param LocNo Location number of LI->reg. + /// \param WasIndirect Indicates if the original use of LI->reg was indirect /// \param Kills Points where the range of LocNo could be extended. /// \param [in,out] NewDefs Append (Idx, LocNo) of inserted defs here. void addDefsFromCopies( - LiveInterval *LI, unsigned LocNo, + LiveInterval *LI, unsigned LocNo, bool WasIndirect, const SmallVectorImpl &Kills, SmallVectorImpl> &NewDefs, MachineRegisterInfo &MRI, LiveIntervals &LIS); @@ -542,6 +545,8 @@ void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) { OS << "undef"; else { OS << I.value().locNo(); + if (I.value().wasIndirect()) + OS << " ind"; } } for (unsigned i = 0, e = locations.size(); i != e; ++i) { @@ -650,18 +655,19 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { } // Get or create the UserValue for (variable,offset) here. - assert(!MI.getOperand(1).isImm() && "DBG_VALUE with indirect flag before " - "LiveDebugVariables"); + bool IsIndirect = MI.getOperand(1).isImm(); + if (IsIndirect) + assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); const DILocalVariable *Var = MI.getDebugVariable(); const DIExpression *Expr = MI.getDebugExpression(); UserValue *UV = getUserValue(Var, Expr, MI.getDebugLoc()); if (!Discard) - UV->addDef(Idx, MI.getOperand(0)); + UV->addDef(Idx, MI.getOperand(0), IsIndirect); else { MachineOperand MO = MachineOperand::CreateReg(0U, false); MO.setIsDebug(); - UV->addDef(Idx, MO); + UV->addDef(Idx, MO, false); } return true; } @@ -769,7 +775,7 @@ void UserValue::extendDef(SlotIndex Idx, DbgValueLocation Loc, LiveRange *LR, } void UserValue::addDefsFromCopies( - LiveInterval *LI, unsigned LocNo, + LiveInterval *LI, unsigned LocNo, bool WasIndirect, const SmallVectorImpl &Kills, SmallVectorImpl> &NewDefs, MachineRegisterInfo &MRI, LiveIntervals &LIS) { @@ -833,7 +839,7 @@ void UserValue::addDefsFromCopies( MachineInstr *CopyMI = LIS.getInstructionFromIndex(DstVNI->def); assert(CopyMI && CopyMI->isCopy() && "Bad copy value"); unsigned LocNo = getLocationNo(CopyMI->getOperand(0)); - DbgValueLocation NewLoc(LocNo); + DbgValueLocation NewLoc(LocNo, WasIndirect); I.insert(Idx, Idx.getNextSlot(), NewLoc); NewDefs.push_back(std::make_pair(Idx, NewLoc)); break; @@ -881,7 +887,8 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI, // sub-register in that regclass). For now, simply skip handling copies if // a sub-register is involved. if (LI && !LocMO.getSubReg()) - addDefsFromCopies(LI, Loc.locNo(), Kills, Defs, MRI, LIS); + addDefsFromCopies(LI, Loc.locNo(), Loc.wasIndirect(), Kills, Defs, MRI, + LIS); continue; } @@ -1323,14 +1330,21 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx, // that the original virtual register was a pointer. Also, add the stack slot // offset for the spilled register to the expression. const DIExpression *Expr = Expression; - if (Spilled) - Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, SpillOffset); + uint8_t DIExprFlags = DIExpression::ApplyOffset; + bool IsIndirect = Loc.wasIndirect(); + if (Spilled) { + if (IsIndirect) + DIExprFlags |= DIExpression::DerefAfter; + Expr = + DIExpression::prepend(Expr, DIExprFlags, SpillOffset); + IsIndirect = true; + } assert((!Spilled || MO.isFI()) && "a spilled location must be a frame index"); do { BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE), - Spilled, MO, Variable, Expr); + IsIndirect, MO, Variable, Expr); // Continue and insert DBG_VALUES after every redefinition of register // associated with the debug value within the range diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 9cd0e93f8615b..9f78a1b4ca9fd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1393,11 +1393,9 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) { "Expected inlined-at fields to agree"); // A dbg.declare describes the address of a source variable, so lower it // into an indirect DBG_VALUE. - auto *Expr = DI->getExpression(); - Expr = DIExpression::append(Expr, {dwarf::DW_OP_deref}); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ false, - *Op, DI->getVariable(), Expr); + TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ true, + *Op, DI->getVariable(), DI->getExpression()); } else { // We can't yet handle anything else here because it would require // generating code, thus altering codegen because of debug info. @@ -1421,19 +1419,19 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) { if (CI->getBitWidth() > 64) BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addCImm(CI) - .addReg(0U) + .addImm(0U) .addMetadata(DI->getVariable()) .addMetadata(DI->getExpression()); else BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addImm(CI->getZExtValue()) - .addReg(0U) + .addImm(0U) .addMetadata(DI->getVariable()) .addMetadata(DI->getExpression()); } else if (const auto *CF = dyn_cast(V)) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addFPImm(CF) - .addReg(0U) + .addImm(0U) .addMetadata(DI->getVariable()) .addMetadata(DI->getExpression()); } else if (unsigned Reg = lookUpRegForValue(V)) { diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index a0c8e83cd8a75..47da2c3b9febb 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -677,7 +677,7 @@ MachineInstr * InstrEmitter::EmitDbgValue(SDDbgValue *SD, DenseMap &VRBaseMap) { MDNode *Var = SD->getVariable(); - const DIExpression *Expr = SD->getExpression(); + MDNode *Expr = SD->getExpression(); DebugLoc DL = SD->getDebugLoc(); assert(cast(Var)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); @@ -701,11 +701,12 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD, // EmitTargetCodeForFrameDebugValue is responsible for allocation. auto FrameMI = BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE)) .addFrameIndex(SD->getFrameIx()); - if (SD->isIndirect()) - Expr = DIExpression::append(Expr, {dwarf::DW_OP_deref}); - - FrameMI.addReg(0); + // Push [fi + 0] onto the DIExpression stack. + FrameMI.addImm(0); + else + // Push fi onto the DIExpression stack. + FrameMI.addReg(0); return FrameMI.addMetadata(Var).addMetadata(Expr); } // Otherwise, we're going to create an instruction here. @@ -751,9 +752,9 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD, // Indirect addressing is indicated by an Imm as the second parameter. if (SD->isIndirect()) - Expr = DIExpression::append(Expr, {dwarf::DW_OP_deref}); - - MIB.addReg(0U, RegState::Debug); + MIB.addImm(0U); + else + MIB.addReg(0U, RegState::Debug); MIB.addMetadata(Var); MIB.addMetadata(Expr); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 4e00c3bd51a1b..7c9d043bfe9e1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5565,6 +5565,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue( MachineFunction &MF = DAG.getMachineFunction(); const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo(); + bool IsIndirect = false; Optional Op; // Some arguments' frame index is recorded during argument lowering. int FI = FuncInfo.getArgumentFrameIndex(Arg); @@ -5586,6 +5587,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue( } if (Reg) { Op = MachineOperand::CreateReg(Reg, false); + IsIndirect = IsDbgDeclare; } } @@ -5634,7 +5636,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue( } assert(!IsDbgDeclare && "DbgDeclare operand is not in memory?"); FuncInfo.ArgDbgValues.push_back( - BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), false, + BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), IsDbgDeclare, RegAndSize.first, Variable, *FragmentExpr)); } }; @@ -5652,6 +5654,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue( } Op = MachineOperand::CreateReg(VMI->second, false); + IsIndirect = IsDbgDeclare; } else if (ArgRegsAndSizes.size() > 1) { // This was split due to the calling convention, and no virtual register // mapping exists for the value. @@ -5665,28 +5668,9 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue( assert(Variable->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); - - // If the argument arrives in a stack slot, then what the IR thought was a - // normal Value is actually in memory, and we must add a deref to load it. - if (Op->isFI()) { - int FI = Op->getIndex(); - unsigned Size = DAG.getMachineFunction().getFrameInfo().getObjectSize(FI); - if (Expr->isImplicit()) { - SmallVector Ops = {dwarf::DW_OP_deref_size, Size}; - Expr = DIExpression::prependOpcodes(Expr, Ops); - } else { - Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); - } - } - - // If this location was specified with a dbg.declare, then it and its - // expression calculate the address of the variable. Append a deref to - // force it to be a memory location. - if (IsDbgDeclare) - Expr = DIExpression::append(Expr, {dwarf::DW_OP_deref}); - + IsIndirect = (Op->isReg()) ? IsIndirect : true; FuncInfo.ArgDbgValues.push_back( - BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), false, + BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), IsIndirect, *Op, Variable, Expr)); return true; diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp index 5c168f0a3b6f2..16c04dc6980b1 100644 --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -1168,8 +1168,14 @@ TargetInstrInfo::describeLoadedValue(const MachineInstr &MI, if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, TRI)) return None; - assert(MI.getNumExplicitDefs() == 1 && - "Can currently only handle mem instructions with a single define"); + // TODO: Can currently only handle mem instructions with a single define. + // An example from the x86 target: + // ... + // DIV64m $rsp, 1, $noreg, 24, $noreg, implicit-def dead $rax, implicit-def $rdx + // ... + // + if (MI.getNumExplicitDefs() != 1) + return None; // TODO: In what way do we need to take Reg into consideration here? diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/debug-cpp.ll b/llvm/test/CodeGen/AArch64/GlobalISel/debug-cpp.ll index 22044fbaad363..caf0a2eebca57 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/debug-cpp.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/debug-cpp.ll @@ -18,7 +18,7 @@ target triple = "aarch64-unknown-linux-gnu" %struct.NTCopy = type { i32 } ; CHECK-LABEL: name: _Z3foo6NTCopy -; CHECK: DBG_VALUE %{{[0-9]+}}(p0), $noreg, !23, !DIExpression(DW_OP_deref), debug-location !24 +; CHECK: DBG_VALUE %{{[0-9]+}}(p0), 0, !23, !DIExpression(), debug-location !24 ; Function Attrs: noinline nounwind optnone define dso_local i32 @_Z3foo6NTCopy(%struct.NTCopy* %o) #0 !dbg !7 { entry: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll b/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll index 4347f23c8be5f..2945d65d3e27b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll @@ -15,7 +15,7 @@ entry: } ; CHECK-LABEL: name: debug_declare_vla -; CHECK: DBG_VALUE %{{[0-9]+}}(p0), $noreg, !14, !DIExpression(DW_OP_deref), debug-location !15 +; CHECK: DBG_VALUE %{{[0-9]+}}(p0), 0, !14, !DIExpression(), debug-location !15 define void @debug_declare_vla(i32 %in) #0 !dbg !13 { entry: %vla.addr = alloca i32, i32 %in @@ -32,11 +32,11 @@ define void @debug_value(i32 %in) #0 !dbg !16 { store i32 %in, i32* %addr ; CHECK: DBG_VALUE %1(p0), $noreg, !17, !DIExpression(DW_OP_deref), debug-location !18 call void @llvm.dbg.value(metadata i32* %addr, i64 0, metadata !17, metadata !DIExpression(DW_OP_deref)), !dbg !18 -; CHECK: DBG_VALUE 123, $noreg, !17, !DIExpression(), debug-location !18 +; CHECK: DBG_VALUE 123, 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata i32 123, i64 0, metadata !17, metadata !DIExpression()), !dbg !18 -; CHECK: DBG_VALUE float 1.000000e+00, $noreg, !17, !DIExpression(), debug-location !18 +; CHECK: DBG_VALUE float 1.000000e+00, 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0, metadata !17, metadata !DIExpression()), !dbg !18 -; CHECK: DBG_VALUE $noreg, $noreg, !17, !DIExpression(), debug-location !18 +; CHECK: DBG_VALUE $noreg, 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata i32* null, i64 0, metadata !17, metadata !DIExpression()), !dbg !18 ret void } diff --git a/llvm/test/CodeGen/ARM/debug-info-arg.ll b/llvm/test/CodeGen/ARM/debug-info-arg.ll index cfff5230e1d05..579d04131782c 100644 --- a/llvm/test/CodeGen/ARM/debug-info-arg.ll +++ b/llvm/test/CodeGen/ARM/debug-info-arg.ll @@ -11,7 +11,7 @@ define void @foo(%struct.tag_s* nocapture %this, %struct.tag_s* %c, i64 %x, i64 tail call void @llvm.dbg.value(metadata %struct.tag_s* %c, metadata !13, metadata !DIExpression()), !dbg !21 tail call void @llvm.dbg.value(metadata i64 %x, metadata !14, metadata !DIExpression()), !dbg !22 tail call void @llvm.dbg.value(metadata i64 %y, metadata !17, metadata !DIExpression()), !dbg !23 -;CHECK: @DEBUG_VALUE: foo:y <- [DW_OP_plus_uconst 8, DW_OP_deref] $r7 +;CHECK: @DEBUG_VALUE: foo:y <- [DW_OP_plus_uconst 8] [$r7+0] tail call void @llvm.dbg.value(metadata %struct.tag_s* %ptr1, metadata !18, metadata !DIExpression()), !dbg !24 tail call void @llvm.dbg.value(metadata %struct.tag_s* %ptr2, metadata !19, metadata !DIExpression()), !dbg !25 %1 = icmp eq %struct.tag_s* %c, null, !dbg !26 diff --git a/llvm/test/CodeGen/PowerPC/debuginfo-stackarg.ll b/llvm/test/CodeGen/PowerPC/debuginfo-stackarg.ll index 227015c423091..b49f363ed8030 100644 --- a/llvm/test/CodeGen/PowerPC/debuginfo-stackarg.ll +++ b/llvm/test/CodeGen/PowerPC/debuginfo-stackarg.ll @@ -34,7 +34,7 @@ define i64 @foo(i64 %bar1, i64 %bar2, i64 %bar3, i64 %bar4, i64 %bar5) local_unn ; We expect to find a DBG_VALUE refering to the metadata id for bar5, using the lowest ; of the two fixed stack offsets found earlier. ; CHECK-LABEL: body: -; CHECK: DBG_VALUE $r1, $noreg, !17, !DIExpression(DW_OP_plus_uconst, 8, DW_OP_deref) +; CHECK: DBG_VALUE $r1, 0, !17, !DIExpression(DW_OP_plus_uconst, 8) entry: tail call void @llvm.dbg.value(metadata i64 %bar1, metadata !13, metadata !DIExpression()), !dbg !18 tail call void @llvm.dbg.value(metadata i64 %bar2, metadata !14, metadata !DIExpression()), !dbg !19 diff --git a/llvm/test/CodeGen/X86/dbg-value-func-arg.ll b/llvm/test/CodeGen/X86/dbg-value-func-arg.ll index beaf84871d16b..cdaf637a9ba11 100644 --- a/llvm/test/CodeGen/X86/dbg-value-func-arg.ll +++ b/llvm/test/CodeGen/X86/dbg-value-func-arg.ll @@ -30,12 +30,12 @@ target triple = "i386-unknown-unknown" ; Function Attrs: norecurse nounwind readnone define dso_local %struct.bar* @func1(%struct.bar* readnone returned %0, i32 %1, i32 %2, i32* nocapture readnone %3) local_unnamed_addr #0 !dbg !8 { -; CHECK-DAG: DBG_VALUE %fixed-stack.1, $noreg, {{.*}}, !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 32), -; CHECK-DAG: DBG_VALUE %fixed-stack.0, $noreg, {{.*}}, !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 32, 32), -; CHECK-DAG: DBG_VALUE %fixed-stack.3, $noreg, {{.*}}, !DIExpression(DW_OP_deref), -; CHECK-DAG: DBG_VALUE %fixed-stack.2, $noreg, {{.*}}, !DIExpression(DW_OP_deref), -; CHECK-DAG: DBG_VALUE %fixed-stack.3, $noreg, {{.*}}, !DIExpression(DW_OP_deref_size, 4, DW_OP_plus_uconst, 144, DW_OP_stack_value), -; CHECK-DAG: DBG_VALUE %fixed-stack.3, $noreg, {{.*}}, !DIExpression(DW_OP_deref_size, 4, DW_OP_plus_uconst, 144, DW_OP_stack_value, DW_OP_LLVM_fragment, 32, 32), +; CHECK-DAG: DBG_VALUE %fixed-stack.1, 0, {{.*}}, !DIExpression(DW_OP_LLVM_fragment, 0, 32), +; CHECK-DAG: DBG_VALUE %fixed-stack.0, 0, {{.*}}, !DIExpression(DW_OP_LLVM_fragment, 32, 32), +; CHECK-DAG: DBG_VALUE %fixed-stack.3, 0, {{.*}}, !DIExpression(), +; CHECK-DAG: DBG_VALUE %fixed-stack.2, 0, {{.*}}, !DIExpression(), +; CHECK-DAG: DBG_VALUE %fixed-stack.3, 0, {{.*}}, !DIExpression(DW_OP_plus_uconst, 144, DW_OP_stack_value), +; CHECK-DAG: DBG_VALUE %fixed-stack.3, 0, {{.*}}, !DIExpression(DW_OP_plus_uconst, 144, DW_OP_stack_value, DW_OP_LLVM_fragment, 32, 32), call void @llvm.dbg.value(metadata i32 %2, metadata !24, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !26 call void @llvm.dbg.value(metadata i32* %3, metadata !24, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32)), !dbg !26 diff --git a/llvm/test/DebugInfo/ARM/PR16736.ll b/llvm/test/DebugInfo/ARM/PR16736.ll index b190be077218e..0d9e219a3b3c2 100644 --- a/llvm/test/DebugInfo/ARM/PR16736.ll +++ b/llvm/test/DebugInfo/ARM/PR16736.ll @@ -2,7 +2,7 @@ ; RUN: llc -filetype=obj < %s \ ; RUN: | llvm-dwarfdump -debug-info - | FileCheck %s --check-prefix=DWARF ; -; CHECK: @DEBUG_VALUE: h:x <- [DW_OP_plus_uconst {{.*}}, DW_OP_deref] $r{{.*}} +; CHECK: @DEBUG_VALUE: h:x <- [DW_OP_plus_uconst {{.*}}] [$r{{.*}}+0] ; DWARF: DW_TAG_formal_parameter ; DWARF: DW_AT_location ; DWARF-NEXT: DW_OP_reg0 R0 diff --git a/llvm/test/DebugInfo/ARM/float-stack-arg.ll b/llvm/test/DebugInfo/ARM/float-stack-arg.ll index 956022703b116..baa2f8b51e8a1 100644 --- a/llvm/test/DebugInfo/ARM/float-stack-arg.ll +++ b/llvm/test/DebugInfo/ARM/float-stack-arg.ll @@ -19,7 +19,7 @@ define arm_aapcscc float @fn1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, float returned %p5) #0 !dbg !7 { ; CHECK-LABEL: bb.0.entry: -; CHECK-NEXT: DBG_VALUE %fixed-stack.0, $noreg, ![[P5]], !DIExpression(DW_OP_deref) +; CHECK-NEXT: DBG_VALUE %fixed-stack.0, 0, ![[P5]] entry: call void @llvm.dbg.value(metadata float %p5, metadata !17, metadata !DIExpression()), !dbg !18 ret float %p5, !dbg !19 diff --git a/llvm/test/DebugInfo/COFF/pieces.ll b/llvm/test/DebugInfo/COFF/pieces.ll index d6ab63bd7e08c..4e11dcabb4d8e 100644 --- a/llvm/test/DebugInfo/COFF/pieces.ll +++ b/llvm/test/DebugInfo/COFF/pieces.ll @@ -89,7 +89,7 @@ ; ASM-LABEL: nested: # @nested -; ASM: #DEBUG_VALUE: nested:o <- [DW_OP_deref] $rcx +; ASM: #DEBUG_VALUE: nested:o <- [DW_OP_deref] [$rcx+0] ; ASM: movl 12(%rcx), %eax ; ASM: [[p_start:\.Ltmp[0-9]+]]: ; ASM: #DEBUG_VALUE: nested:p <- [DW_OP_LLVM_fragment 32 32] $eax @@ -204,7 +204,7 @@ ; OBJ: DisplayName: nested ; OBJ: } ; OBJ: LocalSym { -; OBJ: Type: Nested +; OBJ: Type: Nested& ; OBJ: VarName: o ; OBJ: } ; OBJ: DefRangeRegisterRelSym { @@ -437,7 +437,7 @@ attributes #5 = { nounwind } !70 = !{!71, !72} !71 = !DILocalVariable(name: "o", arg: 1, scope: !61, file: !1, line: 27, type: !64) !72 = !DILocalVariable(name: "p", scope: !61, file: !1, line: 28, type: !53) -!73 = !DIExpression() +!73 = !DIExpression(DW_OP_deref) !74 = !DILocation(line: 27, column: 26, scope: !61) !75 = !DILocation(line: 28, column: 18, scope: !61) !76 = !DILocation(line: 28, column: 22, scope: !61) diff --git a/llvm/test/DebugInfo/MIR/X86/dbg-call-site-spilled-arg-multiple-defs.mir b/llvm/test/DebugInfo/MIR/X86/dbg-call-site-spilled-arg-multiple-defs.mir new file mode 100644 index 0000000000000..cfb5a74056d92 --- /dev/null +++ b/llvm/test/DebugInfo/MIR/X86/dbg-call-site-spilled-arg-multiple-defs.mir @@ -0,0 +1,137 @@ +# We do not support call site parameters when the machine instructions loading a value +# into the forwarding register has a memory operand and multiple defs. +# The generated code was modified a bit in order to have the scenario. +# +# RUN: llc -debug-entry-values -start-after=machineverifier -filetype=obj %s -o - \ +# RUN: | llvm-dwarfdump - | FileCheck %s --implicit-check-not=DW_TAG_GNU_call_site_parameter +# +# Command: clang -g -O2 -Xclang -femit-debug-entry-values test.c +# -mllvm -stop-before=machineverifier -o test.mir -c +# extern void callee(int); +# extern int y; +# +# #define FORCE_SPILL() \ +# asm volatile("" \ +# : \ +# : \ +# : "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "r8", "r9", \ +# "r10", "r11", "r12", "r13", "r14", "r15") +# +# __attribute__((disable_tail_calls)) void caller(int x) { +# FORCE_SPILL(); +# x = x % y; +# callee(x); +# } +# +--- | + ; ModuleID = 'test.c' + source_filename = "test.c" + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + target triple = "x86_64-unknown-linux-gnu" + + @y = external dso_local local_unnamed_addr global i32, align 4 + + ; Function Attrs: nounwind uwtable + define dso_local void @caller(i32 %x) local_unnamed_addr !dbg !12 { + entry: + call void @llvm.dbg.value(metadata i32 %x, metadata !14, metadata !DIExpression()), !dbg !15 + call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !16, !srcloc !17 + %0 = load i32, i32* @y, align 4, !dbg !18 + %rem = srem i32 %x, %0, !dbg !18 + call void @llvm.dbg.value(metadata i32 %rem, metadata !14, metadata !DIExpression()), !dbg !15 + call void @callee(i32 %rem), !dbg !18 + ret void, !dbg !18 + } + + declare !dbg !4 dso_local void @callee(i32) local_unnamed_addr + + ; Function Attrs: nounwind readnone speculatable willreturn + declare void @llvm.dbg.value(metadata, metadata, metadata) + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!8, !9, !10} + !llvm.ident = !{!11} + + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "test.c", directory: "/") + !2 = !{} + !3 = !{!4} + !4 = !DISubprogram(name: "callee", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) + !5 = !DISubroutineType(types: !6) + !6 = !{null, !7} + !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) + !8 = !{i32 7, !"Dwarf Version", i32 4} + !9 = !{i32 2, !"Debug Info Version", i32 3} + !10 = !{i32 1, !"wchar_size", i32 4} + !11 = !{!"clang version 11.0.0"} + !12 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: 11, type: !5, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13) + !13 = !{!14} + !14 = !DILocalVariable(name: "x", arg: 1, scope: !12, file: !1, line: 11, type: !7) + !15 = !DILocation(line: 0, scope: !12) + !16 = !DILocation(line: 12, column: 4, scope: !12) + !17 = !{i32 -2147471651} + !18 = !DILocation(line: 13, column: 12, scope: !12) + +... +--- +name: caller +alignment: 16 +stack: + - { id: 0, name: '', type: spill-slot, offset: -60, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: + - { bb: 0, offset: 30, fwdArgRegs: + - { arg: 0, reg: '$edi' } } +body: | + bb.0.entry: + liveins: $edi, $rbp, $r15, $r14, $r13, $r12, $rbx + + DBG_VALUE $edi, $noreg, !14, !DIExpression(), debug-location !15 + 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 + frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp + CFI_INSTRUCTION def_cfa_offset 64 + 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 + MOV32mr $rsp, 1, $noreg, 4, $noreg, $edi :: (store 4 into %stack.0) + DBG_VALUE $rsp, 0, !14, !DIExpression(DW_OP_plus_uconst, 4), debug-location !15 + 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 $df, 12, implicit-def early-clobber $fpsw, 12, implicit-def dead early-clobber $eflags, !17, debug-location !16 + $eax = MOV32rm $rsp, 1, $noreg, 4, $noreg :: (load 4 from %stack.0) + DBG_VALUE $eax, $noreg, !14, !DIExpression(), debug-location !15 + CDQ implicit-def $eax, implicit-def $edx, implicit $eax, debug-location !18 + DIV64m $rsp, 1, $noreg, 24, $noreg, implicit-def dead $rax, implicit-def $rdx, implicit-def dead $eflags, implicit $rax, implicit $rdx, debug-location !18 :: (load 8 from %stack.0) + $edi = MOV32rr $edx, debug-location !18 + DBG_VALUE $edi, $noreg, !14, !DIExpression(), debug-location !15 + CALL64pcrel32 @callee, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, debug-location !18 + $rsp = frame-destroy ADD64ri8 $rsp, 8, implicit-def dead $eflags, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 56, debug-location !18 + $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 48, debug-location !18 + $r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 40, debug-location !18 + $r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 32, debug-location !18 + $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 24, debug-location !18 + $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 16, debug-location !18 + $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !18 + CFI_INSTRUCTION def_cfa_offset 8, debug-location !18 + RETQ debug-location !18 + +... diff --git a/llvm/test/DebugInfo/X86/dbg-addr-dse.ll b/llvm/test/DebugInfo/X86/dbg-addr-dse.ll index f6f653a1d982b..a817474c16c08 100644 --- a/llvm/test/DebugInfo/X86/dbg-addr-dse.ll +++ b/llvm/test/DebugInfo/X86/dbg-addr-dse.ll @@ -3,10 +3,6 @@ ; RUN: FileCheck %s < %t.s --check-prefix=ASM ; RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=DWARF -; XFAIL: * -; See PR41992, the third and final dbg.value disappears after -; LiveDebugVariables. - ; 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. @@ -51,11 +47,11 @@ entry: ; ASM-LABEL: f: # @f ; ASM: movl %ecx, [[OFF_X:[0-9]+]](%rsp) -; ASM: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]], DW_OP_deref] $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) -; ASM: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]], DW_OP_deref] $rsp +; ASM: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]]] [$rsp+0] ; ASM: movl $2, [[OFF_X]](%rsp) ; ASM: callq escape ; ASM: retq diff --git a/llvm/test/DebugInfo/X86/dbg-addr.ll b/llvm/test/DebugInfo/X86/dbg-addr.ll index 48cb739be45d3..4e27cf5754c7d 100644 --- a/llvm/test/DebugInfo/X86/dbg-addr.ll +++ b/llvm/test/DebugInfo/X86/dbg-addr.ll @@ -7,7 +7,7 @@ ; is control-dependent. ; CHECK-LABEL: use_dbg_addr: -; CHECK: #DEBUG_VALUE: use_dbg_addr:o <- [DW_OP_deref] $rsp +; CHECK: #DEBUG_VALUE: use_dbg_addr:o <- [$rsp+0] ; DWARF: DW_TAG_variable ; DWARF-NEXT: DW_AT_location (DW_OP_fbreg +0) diff --git a/llvm/test/DebugInfo/X86/live-debug-vars-dse.mir b/llvm/test/DebugInfo/X86/live-debug-vars-dse.mir index bc20ebf5d4e2e..9d6ec9f4ecad4 100644 --- a/llvm/test/DebugInfo/X86/live-debug-vars-dse.mir +++ b/llvm/test/DebugInfo/X86/live-debug-vars-dse.mir @@ -1,9 +1,5 @@ # RUN: llc -start-after=machine-scheduler %s -o - | FileCheck %s -# XFAIL: * -# See PR41992, the third and final dbg.value disappears after -# LiveDebugVariables. - # C source: # void escape(int *); # extern int global; @@ -17,12 +13,12 @@ # CHECK-LABEL: f: # @f # CHECK: movl %ecx, [[OFF_X:[0-9]+]](%rsp) -# CHECK: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]], DW_OP_deref] $rsp +# CHECK: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]]] [$rsp+0] # CHECK: leaq [[OFF_X]](%rsp), %rsi # CHECK: callq escape # CHECK: #DEBUG_VALUE: f:x <- 1 # CHECK: movl $1, global(%rip) -# CHECK: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]], DW_OP_deref] $rsp +# CHECK: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[OFF_X]]] [$rsp+0] # CHECK: movl $2, [[OFF_X]](%rsp) # CHECK: callq escape # CHECK: retq @@ -46,11 +42,11 @@ entry: %x.addr = alloca i32, align 4 store i32 %x, i32* %x.addr, align 4 - call void @llvm.dbg.value(metadata i32* %x.addr, metadata !13, metadata !DIExpression(DW_OP_deref)), !dbg !14 + call void @llvm.dbg.value(metadata i32* %x.addr, metadata !13, metadata !DIExpression()), !dbg !14 call void @escape(i32* %x.addr), !dbg !15 call void @llvm.dbg.value(metadata i32 1, metadata !13, metadata !DIExpression()), !dbg !16 store i32 1, i32* @global, align 4, !dbg !17 - call void @llvm.dbg.value(metadata i32* %x.addr, metadata !13, metadata !DIExpression(DW_OP_deref)), !dbg !18 + call void @llvm.dbg.value(metadata i32* %x.addr, metadata !13, metadata !DIExpression()), !dbg !18 store i32 2, i32* %x.addr, align 4, !dbg !18 call void @escape(i32* %x.addr), !dbg !19 ret void, !dbg !20 @@ -132,7 +128,7 @@ body: | %0 = COPY $ecx MOV32mr %stack.0.x.addr, 1, _, 0, _, %0 :: (store 4 into %ir.x.addr) - DBG_VALUE %stack.0.x.addr, $noreg, !13, !DIExpression(DW_OP_deref), debug-location !14 + DBG_VALUE %stack.0.x.addr, 0, !13, !DIExpression(), debug-location !14 ADJCALLSTACKDOWN64 32, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !15 %1 = LEA64r %stack.0.x.addr, 1, _, 0, _ $rcx = COPY %1, debug-location !15 @@ -140,7 +136,7 @@ body: | ADJCALLSTACKUP64 32, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !15 DBG_VALUE 1, _, !13, !DIExpression(), debug-location !16 MOV32mi $rip, 1, _, @global, _, 1, debug-location !17 :: (store 4 into @global) - DBG_VALUE %stack.0.x.addr, $noreg, !13, !DIExpression(DW_OP_deref), debug-location !18 + DBG_VALUE %stack.0.x.addr, 0, !13, !DIExpression(), debug-location !18 MOV32mi %stack.0.x.addr, 1, _, 0, _, 2, debug-location !18 :: (store 4 into %ir.x.addr) ADJCALLSTACKDOWN64 32, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !19 $rcx = COPY %1, debug-location !19 diff --git a/llvm/test/DebugInfo/X86/op_deref.ll b/llvm/test/DebugInfo/X86/op_deref.ll index a1af8fac78019..5de9976d6de2a 100644 --- a/llvm/test/DebugInfo/X86/op_deref.ll +++ b/llvm/test/DebugInfo/X86/op_deref.ll @@ -6,12 +6,10 @@ ; RUN: | FileCheck %s -check-prefix=CHECK -check-prefix=DWARF3 ; DWARF4: DW_AT_location [DW_FORM_sec_offset] (0x00000000 -; DWARF4-NEXT: {{.*}}: DW_OP_breg1 RDX+0{{$}} -; DWARF4-NEXT: {{.*}}: DW_OP_breg6 RBP-{{[0-9]+}}, DW_OP_deref) +; DWARF4-NEXT: {{.*}}: DW_OP_breg1 RDX+0, DW_OP_deref ; DWARF3: DW_AT_location [DW_FORM_data4] (0x00000000 -; DWARF3-NEXT: {{.*}}: DW_OP_breg1 RDX+0{{$}} -; DWARF3-NEXT: {{.*}}: DW_OP_breg6 RBP-{{[0-9]+}}, DW_OP_deref) +; DWARF3-NEXT: {{.*}}: DW_OP_breg1 RDX+0, DW_OP_deref ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000067] = "vla") @@ -19,13 +17,11 @@ ; Check the DEBUG_VALUE comments for good measure. ; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK ; vla should have a register-indirect address at one point. -; ASM-CHECK: DEBUG_VALUE: vla <- [DW_OP_deref] $rdx -; vla ptr is spilt too, it should have a stack location, -; ASM-CHECK: DEBUG_VALUE: vla <- [DW_OP_constu {{[0-9]+}}, DW_OP_minus, DW_OP_deref] [$rbp+0] +; ASM-CHECK: DEBUG_VALUE: vla <- [DW_OP_deref] [$rdx+0] ; ASM-CHECK: DW_OP_breg1 ; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s --check-prefix=PRETTY-PRINT -; PRETTY-PRINT: DIExpression() +; PRETTY-PRINT: DIExpression(DW_OP_deref) define void @testVLAwithSize(i32 %s) nounwind uwtable ssp !dbg !5 { entry: @@ -108,4 +104,4 @@ declare void @llvm.stackrestore(i8*) nounwind !27 = !DILocation(line: 8, column: 1, scope: !13) !28 = !DIFile(filename: "bar.c", directory: "/Users/echristo/tmp") !29 = !{i32 1, !"Debug Info Version", i32 3} -!30 = !DIExpression() +!30 = !DIExpression(DW_OP_deref) diff --git a/llvm/test/DebugInfo/X86/parameters.ll b/llvm/test/DebugInfo/X86/parameters.ll index 3330e968aa1f2..ed0048cc15e03 100644 --- a/llvm/test/DebugInfo/X86/parameters.ll +++ b/llvm/test/DebugInfo/X86/parameters.ll @@ -28,7 +28,7 @@ ; CHECK: DW_AT_name{{.*}} = "func" ; CHECK: DW_TAG_formal_parameter ; CHECK: DW_AT_location {{.*}} -; CHECK-NEXT: DW_OP_breg4 RSI+0) +; CHECK-NEXT: DW_OP_breg4 RSI+0, DW_OP_deref ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name{{.*}} = "f" @@ -38,8 +38,8 @@ ; CHECK: DW_AT_location{{.*}}(DW_OP_fbreg +23) ; CHECK: DW_TAG_formal_parameter ; CHECK: DW_AT_location{{.*}}( -; CHECK-NEXT: {{.*}}: DW_OP_breg4 RSI+0{{$}} -; CHECK-NEXT: {{.*}}: DW_OP_breg7 RSP+8, DW_OP_deref) +; CHECK-NEXT: {{.*}}: DW_OP_breg4 RSI+0, DW_OP_deref +; CHECK-NEXT: {{.*}}: DW_OP_breg7 RSP+8, DW_OP_deref, DW_OP_deref) ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name{{.*}} = "g" @@ -48,7 +48,7 @@ ; Function Attrs: uwtable define void @_ZN7pr147634funcENS_3fooE(%"struct.pr14763::foo"* noalias sret %agg.result, %"struct.pr14763::foo"* %f) #0 !dbg !4 { entry: - call void @llvm.dbg.declare(metadata %"struct.pr14763::foo"* %f, metadata !22, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.declare(metadata %"struct.pr14763::foo"* %f, metadata !22, metadata !DIExpression(DW_OP_deref)), !dbg !24 call void @_ZN7pr147633fooC1ERKS0_(%"struct.pr14763::foo"* %agg.result, %"struct.pr14763::foo"* %f), !dbg !25 ret void, !dbg !25 } @@ -65,7 +65,7 @@ entry: %frombool = zext i1 %b to i8 store i8 %frombool, i8* %b.addr, align 1 call void @llvm.dbg.declare(metadata i8* %b.addr, metadata !26, metadata !DIExpression()), !dbg !27 - call void @llvm.dbg.declare(metadata %"struct.pr14763::foo"* %g, metadata !28, metadata !DIExpression()), !dbg !27 + call void @llvm.dbg.declare(metadata %"struct.pr14763::foo"* %g, metadata !28, metadata !DIExpression(DW_OP_deref)), !dbg !27 %0 = load i8, i8* %b.addr, align 1, !dbg !29 %tobool = trunc i8 %0 to i1, !dbg !29 br i1 %tobool, label %if.then, label %if.end, !dbg !29 diff --git a/llvm/test/DebugInfo/X86/safestack-byval.ll b/llvm/test/DebugInfo/X86/safestack-byval.ll index 1d53908b49789..a653cd78b91d1 100644 --- a/llvm/test/DebugInfo/X86/safestack-byval.ll +++ b/llvm/test/DebugInfo/X86/safestack-byval.ll @@ -14,7 +14,7 @@ ; } ; CHECK: ![[ZZZ:.*]] = !DILocalVariable(name: "zzz", -; CHECK: DBG_VALUE {{.*}} ![[ZZZ]], !DIExpression(DW_OP_constu, 400, DW_OP_minus, DW_OP_deref) +; CHECK: DBG_VALUE {{.*}} ![[ZZZ]], !DIExpression(DW_OP_deref, DW_OP_constu, 400, DW_OP_minus) %struct.S = type { [100 x i32] } @@ -78,7 +78,7 @@ attributes #2 = { argmemonly nounwind } !20 = !{i32 2, !"Debug Info Version", i32 3} !21 = !{!"clang version 3.8.0 (trunk 254107) (llvm/trunk 254109)"} !22 = !DILocation(line: 8, column: 9, scope: !12) -!23 = !DIExpression(DW_OP_constu, 400, DW_OP_minus) +!23 = !DIExpression(DW_OP_deref, DW_OP_constu, 400, DW_OP_minus) !24 = !DILocation(line: 8, column: 28, scope: !12) !25 = !DIExpression() !26 = !DILocation(line: 9, column: 10, scope: !12) diff --git a/llvm/test/DebugInfo/X86/spill-indirect-nrvo.ll b/llvm/test/DebugInfo/X86/spill-indirect-nrvo.ll index 1ac90ead11034..82c852034aebc 100644 --- a/llvm/test/DebugInfo/X86/spill-indirect-nrvo.ll +++ b/llvm/test/DebugInfo/X86/spill-indirect-nrvo.ll @@ -21,7 +21,7 @@ ; } ; CHECK-LABEL: _Z10get_stringv: -; CHECK: #DEBUG_VALUE: get_string:result <- [DW_OP_deref] $rdi +; CHECK: #DEBUG_VALUE: get_string:result <- [$rdi+0] ; CHECK: movq %rdi, [[OFFS:[0-9]+]](%rsp) # 8-byte Spill ; CHECK: #DEBUG_VALUE: get_string:result <- [DW_OP_plus_uconst [[OFFS]], DW_OP_deref] [$rsp+0] ; CHECK: callq _ZN6stringC1Ei diff --git a/llvm/test/DebugInfo/X86/spill-nontrivial-param.ll b/llvm/test/DebugInfo/X86/spill-nontrivial-param.ll index 9712f4f48f056..08793c13f56d0 100644 --- a/llvm/test/DebugInfo/X86/spill-nontrivial-param.ll +++ b/llvm/test/DebugInfo/X86/spill-nontrivial-param.ll @@ -20,7 +20,7 @@ ; } ; CHECK-LABEL: _Z3foo10NonTrivial: -; CHECK: #DEBUG_VALUE: foo:nt <- [DW_OP_deref] $rdi +; CHECK: #DEBUG_VALUE: foo:nt <- [$rdi+0] ; CHECK: movq %rdi, -8(%rsp) # 8-byte Spill ; CHECK: #DEBUG_VALUE: foo:nt <- [DW_OP_constu 8, DW_OP_minus, DW_OP_deref] [$rsp+0] ; CHECK: #APP diff --git a/llvm/test/DebugInfo/X86/stack-arg-deref.ll b/llvm/test/DebugInfo/X86/stack-arg-deref.ll deleted file mode 100644 index 7b7fcac7dc3f6..0000000000000 --- a/llvm/test/DebugInfo/X86/stack-arg-deref.ll +++ /dev/null @@ -1,85 +0,0 @@ -; RUN: llc -stop-before=finalize-isel -o - %s -mtriple=i386-- | FileCheck %s --check-prefix=MIR -; RUN: llc -o - %s -mtriple=i386-- --filetype=obj | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF --implicit-check-not=DW_TAG_subprogram -; REQUIRES: object-emission -; -; Test that, when arguments are passed on the stack (such as i386), -; variable location dereferences occur in the right place. When referring to -; argument stack slots a deref must be used to load the slot first. - -; MIR: ![[FOOVAR:[0-9]+]] = !DILocalVariable(name: "foovar" -; MIR: ![[BARVAR:[0-9]+]] = !DILocalVariable(name: "barvar" -; MIR: ![[BAZVAR:[0-9]+]] = !DILocalVariable(name: "bazvar" - -; Plain i32 on the stack. -; MIR-LABEL: name: foo -; MIR: DBG_VALUE %fixed-stack.0, $noreg, ![[FOOVAR]], -; MIR-SAME: !DIExpression(DW_OP_deref) -; DWARF: DW_TAG_subprogram -; DWARF-LABEL: DW_AT_name ("cheese") -; DWARF: DW_TAG_variable -; DWARF-NEXT: DW_AT_location (DW_OP_fbreg +4) -; DWARF-NEXT: DW_AT_name ("foovar") -define i8 @foo(i32 %blah) !dbg !20 { -entry: - call void @llvm.dbg.value(metadata i32 %blah, metadata !23, metadata !DIExpression()), !dbg !21 - ret i8 0, !dbg !21 -} - -; Pointer on the stack that we fiddle with. -; MIR-LABEL: name: bar -; MIR: DBG_VALUE %fixed-stack.0, $noreg, ![[BARVAR]], -; MIR-SAME: !DIExpression(DW_OP_deref_size, 4, DW_OP_plus_uconst, 4, DW_OP_stack_value) -; DWARF: DW_TAG_subprogram -; DWARF-LABEL: DW_AT_name ("nope") -; DWARF: DW_TAG_variable -; DWARF-NEXT: DW_AT_location (DW_OP_fbreg +4, DW_OP_deref_size 0x4, DW_OP_plus_uconst 0x4, DW_OP_stack_value) -; DWARF-NEXT: DW_AT_name ("barvar") -define i8 @bar(i32 *%blah) !dbg !30 { -entry: - call void @llvm.dbg.value(metadata i32* %blah, metadata !33, metadata !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value)), !dbg !31 - ret i8 0, !dbg !31 -} - -; Pointer that we use as a dbg.declare variable location, after fiddling with -; the pointer value. -; MIR-LABEL: name: baz -; MIR: DBG_VALUE %fixed-stack.0, $noreg, ![[BAZVAR]], -; MIR-SAME: !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 4, DW_OP_deref) -; DWARF: DW_TAG_subprogram -; DWARF-LABEL: DW_AT_name ("brains") -; DWARF: DW_TAG_variable -; DWARF-NEXT: DW_AT_location (DW_OP_fbreg +4, DW_OP_deref, DW_OP_plus_uconst 0x4) -; DWARF-NEXT: DW_AT_name ("bazvar") -define i8 @baz(i32 *%blah) !dbg !40 { -entry: - call void @llvm.dbg.declare(metadata i32* %blah, metadata !43, metadata !DIExpression(DW_OP_plus_uconst, 4)), !dbg !41 - ret i8 0, !dbg !41 -} - -declare void @llvm.dbg.value(metadata, metadata, metadata) -declare void @llvm.dbg.declare(metadata, metadata, metadata) - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!5} - -!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "asdf", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) -!1 = !DIFile(filename: "nil", directory: "/") -!2 = !{} -!5 = !{i32 2, !"Debug Info Version", i32 3} -!7 = !DISubroutineType(types: !2) -!8 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed) - -!20 = distinct !DISubprogram(name: "cheese", linkageName: "cheese", scope: null, file: !1, line: 12, type: !7, isLocal: false, isDefinition: true, scopeLine: 12, isOptimized: true, unit: !0, retainedNodes: !22) -!21 = !DILocation(line: 1, column: 1, scope: !20) -!22 = !{!23} -!23 = !DILocalVariable(name: "foovar", scope: !20, file: !1, line: 14, type: !8) - -!30 = distinct !DISubprogram(name: "nope", linkageName: "nope", scope: null, file: !1, line: 12, type: !7, isLocal: false, isDefinition: true, scopeLine: 12, isOptimized: true, unit: !0, retainedNodes: !32) -!31 = !DILocation(line: 1, column: 1, scope: !30) -!32 = !{!33} -!33 = !DILocalVariable(name: "barvar", scope: !30, file: !1, line: 14, type: !8) - -!40 = distinct !DISubprogram(name: "brains", linkageName: "brains", scope: null, file: !1, line: 12, type: !7, isLocal: false, isDefinition: true, scopeLine: 12, isOptimized: true, unit: !0, retainedNodes: !42) -!41 = !DILocation(line: 1, column: 1, scope: !40) -!42 = !{!43} -!43 = !DILocalVariable(name: "bazvar", scope: !40, file: !1, line: 14, type: !8) diff --git a/llvm/test/DebugInfo/X86/vla.ll b/llvm/test/DebugInfo/X86/vla.ll index 4e4f7fbb36bcc..7d4aff8470dfa 100644 --- a/llvm/test/DebugInfo/X86/vla.ll +++ b/llvm/test/DebugInfo/X86/vla.ll @@ -1,21 +1,7 @@ ; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=asm %s -o - | FileCheck %s -; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=obj %s -o - | llvm-dwarfdump - --name=a | FileCheck --check-prefix=OBJFILE %s -; REQUIRES: object-emission -; ; Ensure that we generate an indirect location for the variable length array a. -; -; CHECK: ##DEBUG_VALUE: vla:a <- [DW_OP_deref] {{\$r[a-z]+}} +; CHECK: ##DEBUG_VALUE: vla:a <- [DW_OP_deref] [{{\$r[a-z]+}}+0] ; CHECK: DW_OP_breg{{[0-9]}} -; -; Ensure there's only one level of indirection in the vla location -- it should -; be a memory location. Base register can be any allocatable one; variables are -; filtered by --name arg to llvm-dwarfdump. -; -; OBJFILE: DW_TAG_variable -; OBJFILE: DW_AT_location -; OBJFILE-NEXT: ): DW_OP_breg{{[0-9]+}} R{{[0-9A-Z]+}}+0) -; OBJFILE: DW_AT_name ("a") -; ; rdar://problem/13658587 ; ; generated from: @@ -47,7 +33,7 @@ entry: %2 = call i8* @llvm.stacksave(), !dbg !17 store i8* %2, i8** %saved_stack, !dbg !17 %vla = alloca i32, i64 %1, align 16, !dbg !17 - call void @llvm.dbg.declare(metadata i32* %vla, metadata !18, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.declare(metadata i32* %vla, metadata !18, metadata !DIExpression(DW_OP_deref)), !dbg !17 %arrayidx = getelementptr inbounds i32, i32* %vla, i64 0, !dbg !22 store i32 42, i32* %arrayidx, align 4, !dbg !22 %3 = load i32, i32* %n.addr, align 4, !dbg !23