llvm / llvm-project

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

GVN introduces PHI node that hampers the visibility of constant variables defined in destination block while debugging #54763

Open dcdelia opened 2 years ago

dcdelia commented 2 years ago

In this code variables l_271 and l_253 are not available at -O2/-O3 during debugging at line 9.

In short, GVN introduces a PHI node for the value of b needed in the expression at line 9. As incoming values, for the if part GVN creates a BB to host a load i8 from variable b, while for the else part it forwards the value just read from d. In the debug metadata, this PHI node is assigned with line number 9. Therefore, since for l_271 and l_253 the associated llvm.dbg.value() operations come after the PHI node, the variables become visible only after line 9 has executed (i.e., only on line 10 when the function returns).

How may debug information be preserved here? For instance, could it be possible for the llvm.dbg.value() to be similarly duplicated and moved?

We tested clang and lldb 14.0.0 commit 116dc70 on x64. We identified GVN using opt-bisect-limit, please find attached the full IR before and after it. For a quick read we inline instead an excerpt after GVN.

before-GVN.ll.txt after-GVN.ll.txt

$ cat a.c
int a = 4, c, d;
char b;
int main() {
 if (a)
   ;
 else
   b = d;
 int l_271 = 0, l_253 = 6;
 c = (7 && l_253) & l_271 < b;
}

LLDB trace:

$ clang -O3 -g a.c -o opt
$ lldb opt
(lldb) target create "opt"
Current executable set to '/home/stepping/768/reduce/opt' (x86_64).
(lldb) b 9   
Breakpoint 1: where = opt`main + 9 at a.c:9:30, address = 0x0000000000400489
(lldb) r
Process 580 launched: '/home/stepping/768/reduce/opt' (x86_64)
Process 580 stopped
* thread #1, name = 'opt', stop reason = breakpoint 1.1
    frame #0: 0x0000000000400489 opt`main at a.c:9:30
   6      else
   7        b = d;
   8      int l_271 = 0, l_253 = 6;
-> 9      c = (7 && l_253) & l_271 < b;
   10   }
(lldb) frame var
(int) l_271 = <variable not available>

(int) l_253 = <variable not available>

(lldb) s
Process 580 stopped
* thread #1, name = 'opt', stop reason = step in
    frame #0: 0x00000000004004aa opt`main at a.c:10:1
   7        b = d;
   8      int l_271 = 0, l_253 = 6;
   9      c = (7 && l_253) & l_271 < b;
-> 10   }
(lldb) frame var
(int) l_271 = 0
(int) l_253 = 6

Excerpt of the IR after GVN:

define dso_local i32 @main() local_unnamed_addr #0 !dbg !18 {
 %1 = load i32, i32* @a, align 4, !dbg !24, !tbaa !26
 %2 = icmp eq i32 %1, 0, !dbg !24
 br i1 %2, label %5, label %3, !dbg !30

3:                                                ; preds = %0
 %4 = load i8, i8* @b, align 1, !dbg !31, !tbaa !32
 br label %8, !dbg !30

5:                                                ; preds = %0
 %6 = load i32, i32* @d, align 4, !dbg !33, !tbaa !26
 %7 = trunc i32 %6 to i8, !dbg !33
 store i8 %7, i8* @b, align 1, !dbg !34, !tbaa !32
 br label %8

8:                                                ; preds = %3, %5
 %9 = phi i8 [ %4, %3 ], [ %7, %5 ], !dbg !31
 call void @llvm.dbg.value(metadata i32 0, metadata !22, metadata !DIExpression()), !dbg !35
 call void @llvm.dbg.value(metadata i32 6, metadata !23, metadata !DIExpression()), !dbg !35
 %10 = icmp sgt i8 %9, 0, !dbg !36
 %11 = zext i1 %10 to i32, !dbg !36
 store i32 %11, i32* @c, align 4, !dbg !37, !tbaa !26
 ret i32 0, !dbg !38
}

!22 = !DILocalVariable(name: "l_271", scope: !18, file: !3, line: 8, type: !8)
!23 = !DILocalVariable(name: "l_253", scope: !18, file: !3, line: 8, type: !8)

!30 = !DILocation(line: 4, column: 7, scope: !18)
!31 = !DILocation(line: 9, column: 30, scope: !18)
!32 = !{!28, !28, i64 0}
!33 = !DILocation(line: 7, column: 9, scope: !25)
!34 = !DILocation(line: 7, column: 7, scope: !25)
!35 = !DILocation(line: 0, scope: !18)
!36 = !DILocation(line: 9, column: 28, scope: !18)
!37 = !DILocation(line: 9, column: 5, scope: !18)
!38 = !DILocation(line: 10, column: 1, scope: !18)
llvmbot commented 2 years ago

@llvm/issue-subscribers-debuginfo