Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

dbg.addr location lists are wrong #34291

Open Quuxplusone opened 7 years ago

Quuxplusone commented 7 years ago
Bugzilla Link PR35318
Status NEW
Importance P enhancement
Reported by Adrian Prantl (aprantl@apple.com)
Reported on 2017-11-15 10:11:04 -0800
Last modified on 2019-09-12 05:02:16 -0700
Version trunk
Hardware PC All
CC aprantl@apple.com, david.stenberg@ericsson.com, dblaikie@gmail.com, jeremy.morse.llvm@gmail.com, llvm-bugs@lists.llvm.org, rnk@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
$ cat /tmp/test.c
int main(int argc, char **argv) {
  printf(argv[0]);
  int i = argc;
  ++i;
  ++i;
  return i;
}
$ clang --version
clang version 6.0.0 (trunk 318314) (llvm/trunk 318312)
$ clang -mllvm -use-dbg-addr -o /tmp/test /tmp/test.c -g
$ dwarfdump /tmp/test.dSYM

0x0000002a:     TAG_subprogram [2] *
                 AT_low_pc( 0x0000000100000f40 )
                 AT_high_pc( 0x0000004a )
                 AT_frame_base( rbp )
                 AT_name( "main" )
...

0x0000005f:         TAG_variable [4]
                     AT_location( 0x00000000
                        0x0000000100000f84 - 0x0000000100000f8a: rbp-20 )
                     AT_name( "i" )
                     AT_decl_file( "/private/tmp/test.c" )
                     AT_decl_line( 3 )
                     AT_type( {0x0000006f} ( int ) )
Quuxplusone commented 6 years ago
I have to be more specific. The location is not *wrong* it just begins too late
to be useful.

0x0000000100000f84 is the beginning of the epilogue:

(lldb) b 0x0000000100000f84
Breakpoint 3: where = test`main + 68 at t.c:6, address = 0x0000000100000f84
(lldb) c
Process 30997 resuming
Process 30997 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
    frame #0: 0x0000000100000f84 test`main(argc=1, argv=0x00007ffeefbff848) at t.c:6
   3      int i = argc;
   4      ++i;
   5      ++i;
-> 6      return i;
   7    }
Target 0: (test) stopped.
(lldb) fr var
(int) argc = 1
(char **) argv = 0x00007ffeefbff848
(int) i = 3
(lldb) dis
    0x100000f82 <+66>: movl   %ecx, %eax
->  0x100000f84 <+68>: addq   $0x20, %rsp
    0x100000f88 <+72>: popq   %rbp
    0x100000f89 <+73>: retq
Quuxplusone commented 6 years ago
This is still reproducible on trunk.

The dbg.addr seems to be placed incorrectly after instruction selection.

Before:

  *** IR Dump After Module Verifier ***
  ; Function Attrs: noinline nounwind optnone uwtable
  define dso_local i32 @main(i32 %argc, i8** %argv) #0 !dbg !7 {
  entry:
    %retval = alloca i32, align 4
    %argc.addr = alloca i32, align 4
    %argv.addr = alloca i8**, align 8
    %i = alloca i32, align 4
    store i32 0, i32* %retval, align 4
    store i32 %argc, i32* %argc.addr, align 4
    call void @llvm.dbg.addr(metadata i32* %argc.addr, metadata !14, metadata !DIExpression()), !dbg !15
    store i8** %argv, i8*** %argv.addr, align 8
    call void @llvm.dbg.addr(metadata i8*** %argv.addr, metadata !16, metadata !DIExpression()), !dbg !17
    %0 = load i8**, i8*** %argv.addr, align 8, !dbg !18
    %arrayidx = getelementptr inbounds i8*, i8** %0, i64 0, !dbg !18
    %1 = load i8*, i8** %arrayidx, align 8, !dbg !18
    %call = call i32 (i8*, ...) @printf(i8* %1), !dbg !19
->  call void @llvm.dbg.addr(metadata i32* %i, metadata !20, metadata
!DIExpression()), !dbg !21
    %2 = load i32, i32* %argc.addr, align 4, !dbg !22
    store i32 %2, i32* %i, align 4, !dbg !21
    %3 = load i32, i32* %i, align 4, !dbg !23
    %inc = add nsw i32 %3, 1, !dbg !23
    store i32 %inc, i32* %i, align 4, !dbg !23
    %4 = load i32, i32* %i, align 4, !dbg !24
    %inc1 = add nsw i32 %4, 1, !dbg !24
    store i32 %inc1, i32* %i, align 4, !dbg !24
    %5 = load i32, i32* %i, align 4, !dbg !25
    ret i32 %5, !dbg !26
  }
  # *** IR Dump Before X86 DAG->DAG Instruction Selection ***:
  # Machine code for function main: IsSSA, TracksLiveness

After:

  # *** IR Dump After X86 DAG->DAG Instruction Selection ***:
  # Machine code for function main: IsSSA, TracksLiveness
  Frame Objects:
    fi#0: size=4, align=4, at location [SP+8]
    fi#1: size=4, align=4, at location [SP+8]
    fi#2: size=8, align=8, at location [SP+8]
    fi#3: size=4, align=4, at location [SP+8]
  Function Live Ins: $edi in %0, $rsi in %2

  bb.0.entry:
    liveins: $edi, $rsi
    %2:gr64 = COPY $rsi
    %0:gr32 = COPY $edi
    %1:gr32 = COPY killed %0:gr32
    %3:gr64 = COPY killed %2:gr64
    MOV32mi %stack.0.retval, 1, $noreg, 0, $noreg, 0 :: (store 4 into %ir.retval)
    MOV32mr %stack.1.argc.addr, 1, $noreg, 0, $noreg, %1:gr32 :: (store 4 into %ir.argc.addr)
    DBG_VALUE %stack.1.argc.addr, 0, !"argc", !DIExpression(), debug-location !15; pr35318.c:1:14 line no:1
    MOV64mr %stack.2.argv.addr, 1, $noreg, 0, $noreg, %3:gr64 :: (store 8 into %ir.argv.addr)
    DBG_VALUE %stack.2.argv.addr, 0, !"argv", !DIExpression(), debug-location !17; pr35318.c:1:27 line no:1
    %20:gr64 = MOV64rm %stack.2.argv.addr, 1, $noreg, 0, $noreg, debug-location !18 :: (load 8 from %ir.argv.addr); pr35318.c:2:10
    %19:gr64 = MOV64rm %20:gr64, 1, $noreg, 0, $noreg, debug-location !18 :: (load 8 from %ir.arrayidx); pr35318.c:2:10
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !19; pr35318.c:2:3
    $rdi = COPY %19:gr64, debug-location !19; pr35318.c:2:3
    $al = MOV8ri 0, debug-location !19; pr35318.c:2:3
    CALL64pcrel32 @printf, <regmask $bh $bl $bp $bph $bpl $bx $ebp $ebx $hbp $hbx $rbp $rbx $r12 $r13 $r14 $r15 $r12b $r13b $r14b $r15b $r12bh $r13bh $r14bh $r15bh $r12d $r13d $r14d $r15d $r12w $r13w $r14w $r15w $r12wh and 3 more...>, implicit $rsp, implicit $ssp, implicit $al, implicit $rdi, implicit-def $eax, debug-location !19; pr35318.c:2:3
    ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !19; pr35318.c:2:3
    %17:gr32 = COPY $eax, debug-location !19; pr35318.c:2:3
    %15:gr32 = MOV32rm %stack.1.argc.addr, 1, $noreg, 0, $noreg, debug-location !22 :: (load 4 from %ir.argc.addr); pr35318.c:3:11
    MOV32mr %stack.3.i, 1, $noreg, 0, $noreg, killed %15:gr32, debug-location !21 :: (store 4 into %ir.i); pr35318.c:3:7
    %13:gr32 = MOV32rm %stack.3.i, 1, $noreg, 0, $noreg, debug-location !23 :: (load 4 from %ir.i); pr35318.c:4:3
    %12:gr32 = ADD32ri8 killed %13:gr32(tied-def 0), 1, implicit-def $eflags, debug-location !23; pr35318.c:4:3
    MOV32mr %stack.3.i, 1, $noreg, 0, $noreg, killed %12:gr32, debug-location !23 :: (store 4 into %ir.i); pr35318.c:4:3
    %9:gr32 = MOV32rm %stack.3.i, 1, $noreg, 0, $noreg, debug-location !24 :: (load 4 from %ir.i); pr35318.c:5:3
    %8:gr32 = ADD32ri8 killed %9:gr32(tied-def 0), 1, implicit-def $eflags, debug-location !24; pr35318.c:5:3
    MOV32mr %stack.3.i, 1, $noreg, 0, $noreg, killed %8:gr32, debug-location !24 :: (store 4 into %ir.i); pr35318.c:5:3
    %5:gr32 = MOV32rm %stack.3.i, 1, $noreg, 0, $noreg, debug-location !25 :: (load 4 from %ir.i); pr35318.c:6:10
    $eax = COPY %5:gr32, debug-location !26; pr35318.c:6:3
->  DBG_VALUE %stack.3.i, 0, !"i", !DIExpression(), debug-location !21;
pr35318.c:3:7 line no:3
    RETQ implicit $eax, debug-location !26; pr35318.c:6:3

I don't know much about this code, but a quick troubleshooting session shows
that the DbgValue for i is treated as trailing, which is why it is emitted
before the terminator:

    // Add trailing DbgValue's before the terminator. FIXME: May want to add
    // some of them before one or more conditional branches?
    SmallVector<MachineInstr*, 8> DbgMIs;
    for (; DI != DE; ++DI) {
      if ((*DI)->isInvalidated())
        continue;
      assert((*DI)->getOrder() >= LastOrder &&
             "emitting DBG_VALUE out of order");
      if (MachineInstr *DbgMI = Emitter.EmitDbgValue(*DI, VRBaseMap))
        DbgMIs.push_back(DbgMI);
    }