diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 5419a10f4f9a..61b2c7e65842 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -86,7 +86,7 @@ bool DwarfExpression::AddMachineRegIndirect(const TargetRegisterInfo &TRI, } bool DwarfExpression::AddMachineReg(const TargetRegisterInfo &TRI, - unsigned MachineReg) { + unsigned MachineReg, unsigned MaxSize) { if (!TRI.isPhysicalRegister(MachineReg)) return false; @@ -137,10 +137,12 @@ bool DwarfExpression::AddMachineReg(const TargetRegisterInfo &TRI, // its range, emit a DWARF piece for it. if (Reg >= 0 && Intersection.any()) { AddReg(Reg, "sub-register"); + if (Offset >= MaxSize) + break; // Emit a piece for the any gap in the coverage. if (Offset > CurPos) AddOpPiece(Offset - CurPos); - AddOpPiece(Size); + AddOpPiece(std::min(Size, MaxSize - Offset)); CurPos = Offset + Size; // Mark it as emitted. @@ -196,9 +198,12 @@ bool DwarfExpression::AddMachineRegExpression(const TargetRegisterInfo &TRI, bool ValidReg = false; auto Op = ExprCursor.peek(); switch (Op->getOp()) { - default: - ValidReg = AddMachineReg(TRI, MachineReg); + default: { + auto Fragment = ExprCursor.getFragmentInfo(); + ValidReg = AddMachineReg(TRI, MachineReg, + Fragment ? Fragment->SizeInBits : ~1U); break; + } case dwarf::DW_OP_plus: case dwarf::DW_OP_minus: { // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset]. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 96d9f09faf01..fd90fa05bc32 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -72,6 +72,11 @@ public: } /// Determine whether there are any operations left in this expression. operator bool() const { return Start != End; } + + /// Retrieve the fragment information, if any. + Optional getFragmentInfo() const { + return DIExpression::getFragmentInfo(Start, End); + } }; /// Base class containing the logic for constructing DWARF expressions @@ -145,6 +150,10 @@ public: /// Emit a partial DWARF register operation. /// /// \param MachineReg The register number. + /// \param MaxSize If the register must be composed from + /// sub-registers this is an upper bound + /// for how many bits the emitted DW_OP_piece + /// may cover. /// /// If size and offset is zero an operation for the entire register is /// emitted: Some targets do not provide a DWARF register number for every @@ -153,7 +162,8 @@ public: /// multiple subregisters that alias the register. /// /// \return false if no DWARF register exists for MachineReg. - bool AddMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg); + bool AddMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, + unsigned MaxSize = ~1U); /// Emit a signed constant. void AddSignedConstant(int64_t Value); diff --git a/llvm/test/DebugInfo/ARM/partial-subreg.ll b/llvm/test/DebugInfo/ARM/partial-subreg.ll new file mode 100644 index 000000000000..cb9615152960 --- /dev/null +++ b/llvm/test/DebugInfo/ARM/partial-subreg.ll @@ -0,0 +1,66 @@ +; RUN: llc %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s +; This tests a fragment that partially covers subregister compositions. +; +; Our fragment is 96 bits long and lies in a 128-bit register, which +; in turn has to be composed out of its two 64-bit subregisters. + +; CHECK: .debug_info +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_name {{.*}}"subscript.get" +; CHECK: DW_TAG_formal_parameter +; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000) +; CHECK: .debug_loc +; CHECK: 0x00000000: Beginning address offset +; CHECK-NEXT: Ending address offset +; CHECK-NEXT: Location description: 90 90 02 93 08 90 91 02 93 04 +; d16, piece 0x00000008, d17, piece 0x00000004 +source_filename = "simd.ll" +target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" +target triple = "armv7-apple-ios7.0" + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0 + +define <3 x float> @_TFV4simd8float2x3g9subscriptFSiVS_6float3(i32, <3 x float>, <3 x float>) !dbg !5 { +entry: + tail call void @llvm.dbg.value(metadata <3 x float> %1, i64 0, metadata !8, metadata !9), !dbg !10 + tail call void @llvm.dbg.value(metadata <3 x float> %2, i64 0, metadata !8, metadata !11), !dbg !10 + %3 = icmp eq i32 %0, 0, !dbg !12 + br i1 %3, label %7, label %4, !dbg !12 + +;