Interleaved debug info on arm

When compiling code with lld -O0 --lto-O0 --eh-frame-hdr I get strange interleaved line info all
over the place:
...
0x00000000000595ac 22 11 1 0 0 is_stmt
0x00000000000595bc 25 7 1 0 0 is_stmt <<<
0x00000000000595c0 22 11 1 0 0 is_stmt
0x00000000000595c4 25 7 1 0 0 is_stmt <<<
0x00000000000595c8 26 7 1 0 0 is_stmt

but the code only has 1 reference to line 25 and the references to line 22 all precede that:

; Function Attrs: uwtable
define hidden void @ms_t1d_ConsoleApplication479.Program4_Testni32(i32) #0 !dbg !34 {
  %2 = alloca i32
  store i32 %0, i32* %2
  call void @llvm.dbg.declare(metadata i32* %2, metadata !61, metadata !19), !dbg !63
  %3 = alloca double, !dbg !63
  store double 0.000000e+00, double* %3, !dbg !63
  %4 = alloca %WriteLineObject*, !dbg !63
  store %WriteLineObject* null, %WriteLineObject** %4, !dbg !63
  br label %5, !dbg !63

; <label>:5: ; preds = %1
  call void @llvm.dbg.declare(metadata double* %3, metadata !64, metadata !19), !dbg !68
  call void @llvm.dbg.declare(metadata %WriteLineObject** %4, metadata !69, metadata !19), !dbg !68
  store double 3.140000e+00, double* %3, !dbg !71
  %6 = call i8* @__newinst(i8* bitcast ({ { i64, [30 x i8]*, i8*, [141 x i8]*, { i8*, void (%._ConsoleApplication479.Program*)*, void (i32)*, i8*, %WriteLineString* (%._ConsoleApplication479.Program*)*, i32 ()*, i8** }* }*, i8*, i8*, i8*, [16 x i8], i8*, i8*, i8*, i8* }* @_rtti_t1d_ConsoleApplication479.Program to i8*), i32 16), !dbg !72
  %7 = bitcast i8* %6 to %._ConsoleApplication479.Program*, !dbg !72
  call void @mi_t1d_ConsoleApplication479.Program5_.ctor(%._ConsoleApplication479.Program* %7) #0, !dbg !72
  %8 = bitcast %._ConsoleApplication479.Program* %7 to %WriteLineObject*, !dbg !72
  store %WriteLineObject* %8, %WriteLineObject** %4, !dbg !72
  call void @WriteLine(%WriteLineString* bitcast ({ i8*, i32, [14 x i8] }* @.str2 to %WriteLineString*)) #1, !dbg !73
  %9 = load double, double* %3, !dbg !74
  %10 = sitofp i32 1 to double, !dbg !74
  %11 = fadd double %9, %10, !dbg !74
  store double %11, double* %3, !dbg !74
  %12 = load double, double* %3, !dbg !75
  %13 = sitofp i32 1 to double, !dbg !75
  %14 = fadd double %12, %13, !dbg !75
  store double %14, double* %3, !dbg !75
  ret void, !dbg !76
}

!72 = !DILocation(line: 22, column: 11, scope: !65)
!73 = !DILocation(line: 25, column: 7, scope: !65)

full bitcode: https://gist.github.com/carlokok/aa3fab175f8afe8e4776ad6c2f5cc80a

disasm: https://gist.github.com/carlokok/ab265461b37f87a10e0853ffc4d93c77

What could possibly cause this? It's wreaking havoc with the debugger experience.

Carlo Kok
RemObjects Software

Have you tried looking at the --dump-after-all output to see which pass (if any) is adding the extra line table entries?
-- adrian

Does this happen only when you are using lld? Please try gold to see if it works as you expected.

Yes this only happens when using lld (I’m on aug1’s head)

If I compile with lld with bitcode as input:
-O0 --lto-O0
–eh-frame-hdr --dynamic-linker “/lib/ld-linux-armhf.so.3”

0x0000000000059578 15 0 1 0 0 is_stmt
0x0000000000059588 22 11 1 0 0 is_stmt prologue_end
0x000000000005958c 21 11 1 0 0 is_stmt
0x00000000000595a0 15 5 1 0 0 is_stmt
0x00000000000595a4 22 11 1 0 0 is_stmt
0x00000000000595b4 25 7 1 0 0 is_stmt
0x00000000000595b8 22 11 1 0 0 is_stmt
0x00000000000595bc 25 7 1 0 0 is_stmt
0x00000000000595c4 26 7 1 0 0 is_stmt
0x00000000000595dc 27 7 1 0 0 is_stmt
0x00000000000595f0 30 5 1 0 0 is_stmt

If I precompile the bitcode with llc -O0 -filetype=obj
-O0 --lto-O0
–eh-frame-hdr --dynamic-linker “/lib/ld-linux-armhf.so.3”

0x00000000000401ac 15 0 1 0 0 is_stmt
0x00000000000401c4 15 5 1 0 0 is_stmt prologue_end
0x00000000000401d0 21 11 1 0 0 is_stmt
0x00000000000401e0 22 11 1 0 0 is_stmt
0x00000000000401fc 25 7 1 0 0 is_stmt
0x0000000000040204 26 7 1 0 0 is_stmt
0x0000000000040234 27 7 1 0 0 is_stmt
0x0000000000040250 30 5 1 0 0 is_stmt

You mean --print-after-all ? I don't see any way to pass that to lld; The debug info is fine when using llc.

Carlo Kok
RemObjects Software

Have you tried looking at the --dump-after-all output to see which pass (if any) is adding the
extra line table entries?
-- adrian

You mean --print-after-all ? I don't see any way to pass that to lld; The debug info is fine when using llc.

I have no experience with lld, but worst-case you should be able to hard-code the default to true and recompile liblto/lld.

-- adrian

I do not have an environment to reproduce your problem, and it is not also clear to me what exactly I need to type in to re-run what you did.

Do you think you can create a smaller test case which I can execute and see the problem?