[llvm-bugs] [Bug 39314] New: [DebugInfo] Location list for variable is missing due to mix of dbg.declare and dbg.value

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Oct 16 00:42:31 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=39314

            Bug ID: 39314
           Summary: [DebugInfo] Location list for variable is missing due
                    to mix of dbg.declare and dbg.value
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: david.stenberg at ericsson.com
                CC: llvm-bugs at lists.llvm.org

Reproduced on trunk (r344484).

When compiling the following file, foo.c:

    int i = 0;
    int main() {
      long arr[2] = {0, 0};
      long volatile *ptr = arr;
      for (; i < 1; i++)
        arr[1] = *ptr + 13;
    }

using:

    $ clang -O3 -g -S foo.c -o foo.s
    $ clang foo.s -o foo.out

we do not emit a location list for arr (but instead only a location description
for the first element):

    $ readelf --debug-dump=info -W foo.out | grep -B2 -A3 ': arr'
     <2><5f>: Abbrev Number: 5 (DW_TAG_variable)
        <60>   DW_AT_location    : 4 byte block: 91 78 93 8     (DW_OP_fbreg:
-8; DW_OP_piece: 8)
        <65>   DW_AT_name        : (indirect string, offset: 0x124): arr        
        <69>   DW_AT_decl_file   : 1    
        <6a>   DW_AT_decl_line   : 3    
        <6b>   DW_AT_type        : <0x7b>       

even though we have DBG_VALUEs for the second element available:

    $ grep "DEBUG_VALUE: main:arr" foo.s
        #DEBUG_VALUE: main:arr <- [DW_OP_LLVM_fragment 64 64] 0
        #DEBUG_VALUE: main:arr <- [DW_OP_plus_uconst 13, DW_OP_stack_value,
DW_OP_LLVM_fragment 64 64] $rcx

Some internal analysis:

    In SelectionDAGISel.cpp, in processDbgDeclares(), the dbg.declare is taken
care of, and dbg info for the arr variable is inserted in MF using
MF->setVariableDbgInfo.

    Later, in DwarfDebug::collectVariableInfo, the dbg info from MF is handled
first. The code looks like this:

    void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
                                         const DISubprogram *SP,
                                         DenseSet<InlinedVariable> &Processed)
{
      // Grab the variable info that was squirreled away in the MMI side-table.
      collectVariableInfoFromMFTable(TheCU, Processed);

      for (const auto &I : DbgValues) {
        InlinedVariable IV = I.first;
        if (Processed.count(IV))
          continue;
        ...

    So "arr" is added to Processed already inside
collectVariableInfoFromMFTable, and when iterating over the DbgValues (the map
with dbg.value "history") we bail out early.

It is SROA that splits arr, resulting in a dbg.declare, and some dbg.values:

    *** IR Dump Before SROA ***
    ; Function Attrs: nounwind uwtable
    define dso_local i32 @main() #0 !dbg !11 {
    entry:
      %retval = alloca i32, align 4
      %arr = alloca [2 x i64], align 16
      %ptr = alloca i64*, align 8
      store i32 0, i32* %retval, align 4
      %0 = bitcast [2 x i64]* %arr to i8*, !dbg !23
      call void @llvm.lifetime.start.p0i8(i64 16, i8* %0) #3, !dbg !23
      call void @llvm.dbg.declare(metadata [2 x i64]* %arr, metadata !15,
metadata !DIExpression()), !dbg !24
      %1 = bitcast [2 x i64]* %arr to i8*, !dbg !24
      call void @llvm.memset.p0i8.i64(i8* align 16 %1, i8 0, i64 16, i1 false),
!dbg !24
      %2 = bitcast i64** %ptr to i8*, !dbg !25
      call void @llvm.lifetime.start.p0i8(i64 8, i8* %2) #3, !dbg !25
      call void @llvm.dbg.declare(metadata i64** %ptr, metadata !20, metadata
!DIExpression()), !dbg !26
      %arraydecay = getelementptr inbounds [2 x i64], [2 x i64]* %arr, i32 0,
i32 0, !dbg !27
      store i64* %arraydecay, i64** %ptr, align 8, !dbg !26, !tbaa !28
      br label %for.cond, !dbg !32

    for.cond:                                         ; preds = %for.body,
%entry
      %3 = load i32, i32* @i, align 4, !dbg !33, !tbaa !36
      %cmp = icmp slt i32 %3, 1, !dbg !38
      br i1 %cmp, label %for.body, label %for.end, !dbg !39

    for.body:                                         ; preds = %for.cond
      %4 = load i64*, i64** %ptr, align 8, !dbg !40, !tbaa !28
      %5 = load volatile i64, i64* %4, align 8, !dbg !41, !tbaa !42
      %add = add nsw i64 %5, 13, !dbg !44
      %arrayidx = getelementptr inbounds [2 x i64], [2 x i64]* %arr, i64 0, i64
1, !dbg !45
      store i64 %add, i64* %arrayidx, align 8, !dbg !46, !tbaa !42
      %6 = load i32, i32* @i, align 4, !dbg !47, !tbaa !36
      %inc = add nsw i32 %6, 1, !dbg !47
      store i32 %inc, i32* @i, align 4, !dbg !47, !tbaa !36
      br label %for.cond, !dbg !48, !llvm.loop !49

    for.end:                                          ; preds = %for.cond
      %7 = bitcast i64** %ptr to i8*, !dbg !51
      call void @llvm.lifetime.end.p0i8(i64 8, i8* %7) #3, !dbg !51
      %8 = bitcast [2 x i64]* %arr to i8*, !dbg !51
      call void @llvm.lifetime.end.p0i8(i64 16, i8* %8) #3, !dbg !51
      %9 = load i32, i32* %retval, align 4, !dbg !51
      ret i32 %9, !dbg !51
    }
    *** IR Dump After SROA ***
    ; Function Attrs: nounwind uwtable
    define dso_local i32 @main() #0 !dbg !11 {
    entry:
      %arr.sroa.0 = alloca i64, align 16
      call void @llvm.dbg.declare(metadata i64* %arr.sroa.0, metadata !15,
metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg !23
      %arr.sroa.0.0..sroa_cast4 = bitcast i64* %arr.sroa.0 to i8*, !dbg !24
      call void @llvm.lifetime.start.p0i8(i64 8, i8*
%arr.sroa.0.0..sroa_cast4), !dbg !24
      store i64 0, i64* %arr.sroa.0, align 16, !dbg !23
      call void @llvm.dbg.value(metadata i64 0, metadata !15, metadata
!DIExpression(DW_OP_LLVM_fragment, 64, 64)), !dbg !23
      call void @llvm.dbg.value(metadata i64* undef, metadata !20, metadata
!DIExpression()), !dbg !25
      br label %for.cond, !dbg !26

    for.cond:                                         ; preds = %for.body,
%entry
      %0 = load i32, i32* @i, align 4, !dbg !27, !tbaa !30
      %cmp = icmp slt i32 %0, 1, !dbg !34
      br i1 %cmp, label %for.body, label %for.end, !dbg !35

    for.body:                                         ; preds = %for.cond
      %arr.sroa.0.0.arr.sroa.0.0. = load volatile i64, i64* %arr.sroa.0, align
16, !dbg !36, !tbaa !37
      %add = add nsw i64 %arr.sroa.0.0.arr.sroa.0.0., 13, !dbg !39
      call void @llvm.dbg.value(metadata i64 %add, metadata !15, metadata
!DIExpression(DW_OP_LLVM_fragment, 64, 64)), !dbg !23
      %1 = load i32, i32* @i, align 4, !dbg !40, !tbaa !30
      %inc = add nsw i32 %1, 1, !dbg !40
      store i32 %inc, i32* @i, align 4, !dbg !40, !tbaa !30
      br label %for.cond, !dbg !41, !llvm.loop !42

    for.end:                                          ; preds = %for.cond
      %arr.sroa.0.0..sroa_cast5 = bitcast i64* %arr.sroa.0 to i8*, !dbg !44
      call void @llvm.lifetime.end.p0i8(i64 8, i8* %arr.sroa.0.0..sroa_cast5),
!dbg !44
      ret i32 0, !dbg !44
    }

Should the DWARF emission be able to handle these cases, or is the input bad
somehow?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181016/a6dd5ba2/attachment-0001.html>


More information about the llvm-bugs mailing list