llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.79k stars 11.9k forks source link

[DebugInfo] branch-folder drops debug info in tail merging even if tail merging doesn't change IR #94050

Closed aeubanks closed 4 months ago

aeubanks commented 5 months ago
$ cat /tmp/a.ll
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-grtev4-linux-gnu"

define i32 @main(i1 %0) {
entry:
  br i1 %0, label %1, label %2

1:                                                ; preds = %entry
  store i64 1, ptr null, align 1
  br label %3, !dbg !3

2:                                                ; preds = %entry
  store i64 0, ptr null, align 1
  br label %3

3:                                                ; preds = %2, %1
  ret i32 0
}

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, nameTableKind: None)
!1 = !DIFile(filename: "foo.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "2d07c91bb9d9c2fa4eee31a1aeed20e3")
!2 = !{i32 2, !"Debug Info Version", i32 3}
!3 = !DILocation(line: 17, column: 3, scope: !4)
!4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !5, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
!5 = !DISubroutineType(types: !6)
!6 = !{}

$ build/rel/bin/llc -o /tmp/b.s /tmp/a.ll -enable-tail-merge=1 -stop-after=branch-folder 
$ build/rel/bin/llc -o /tmp/a.s /tmp/a.ll -enable-tail-merge=0 -stop-after=branch-folder 
$ diff /tmp/a.s /tmp/b.s
98c98
<     JMP_1 %bb.8, debug-location !21
---
>     JMP_1 %bb.8

reduced from a ubsan backtrace missing line info

llvmbot commented 5 months ago

@llvm/issue-subscribers-debuginfo

Author: Arthur Eubanks (aeubanks)

``` $ cat /tmp/a.ll target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-grtev4-linux-gnu" define i32 @main(i1 %0) { entry: br i1 %0, label %1, label %2 1: ; preds = %entry store i64 1, ptr null, align 1 br label %3, !dbg !3 2: ; preds = %entry store i64 0, ptr null, align 1 br label %3 3: ; preds = %2, %1 ret i32 0 } !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!2} !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, nameTableKind: None) !1 = !DIFile(filename: "foo.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "2d07c91bb9d9c2fa4eee31a1aeed20e3") !2 = !{i32 2, !"Debug Info Version", i32 3} !3 = !DILocation(line: 17, column: 3, scope: !4) !4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !5, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) !5 = !DISubroutineType(types: !6) !6 = !{} $ build/rel/bin/llc -o /tmp/b.s /tmp/a.ll -enable-tail-merge=1 -stop-after=branch-folder $ build/rel/bin/llc -o /tmp/a.s /tmp/a.ll -enable-tail-merge=0 -stop-after=branch-folder $ diff /tmp/a.s /tmp/b.s 98c98 < JMP_1 %bb.8, debug-location !21 --- > JMP_1 %bb.8 ``` reduced from a ubsan backtrace missing line info
alanzhao1 commented 4 months ago

I poked around with a debugger - it seems like the issue is in https://github.com/llvm/llvm-project/blob/81e9a3c3fc9552ef0e1191da70aa0d44d918bcc0/llvm/lib/CodeGen/BranchFolding.cpp#L694-L699

The problem is that we remove and put back an unconditional branch instruction, but we don't preserve the debug info of the previous instruction.