llvm / llvm-project

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

Wrong line information at Og #46583

Open 31fbadee-9e60-4c99-b908-8380e6a40c85 opened 4 years ago

31fbadee-9e60-4c99-b908-8380e6a40c85 commented 4 years ago
Bugzilla Link 47239
Version trunk
OS Linux
CC @adrian-prantl,@dwblaikie,@JDevlieghere,@jmorse,@walkerkd,@pogo59,@vedantk

Extended Description

After setting a breakpoint at func_10 and running line 5 is hit. However, from disassembly, it seems that line 7 is being executed.

$ cat -n a.c 1 int a; 2 int b; 3 int func_10() { 4 int c = &a; 5 int i, j; 6 d: 7 if (c) 8 goto d; 9 i = 0; 10 for (; i;) 11 j = &c; 12 return c; 13 } 14 int main() { b = func_10(); }

$ cat a.c int a; int b; int func_10() { int c = &a; int i, j; d: if (c) goto d; i = 0; for (; i;) j = &c; return c; } int main() { b = func_10(); }

$ clang -v clang version 12.0.0 (https://github.com/llvm/llvm-project.git bc8be3054067ac822fc6d9f4f8e64c841f530f16) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/local/bin Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0 Candidate multilib: .;@m64 Selected multilib: .;@m64

$ clang -Og -g -o opt a.c

$ lldb opt lldb opt (lldb) target create "opt" Current executable set to opt' (x86_64). (lldb) b func_10 Breakpoint 1: where = opt`func_10 + 7 at a.c:5:3, address = 0x0000000000400487 (lldb) r Process 24746 launched: 'opt' (x86_64) Process 24746 stopped

llvmbot commented 4 years ago

Looks like the frontend slaps this line on the br:

define i32 @​func_10() #​0 !dbg !​16 { %1 = alloca i32, align 8 %2 = alloca i32, align 4 %3 = alloca i32, align 4 %4 = bitcast i32 %1 to i8, !dbg !​24 call void @​llvm.lifetime.start.p0i8(i64 8, i8 %4) #​3, !dbg !​24 call void @​llvm.dbg.declare(metadata i32 %1, metadata !​20, metadata !DIExpression()), !dbg !​25 store i32* @​a, i32* %1, align 8, !dbg !​25, !tbaa !​26 %5 = bitcast i32 %2 to i8, !dbg !​30 call void @​llvm.lifetime.start.p0i8(i64 4, i8 %5) #​3, !dbg !​30 call void @​llvm.dbg.declare(metadata i32 %2, metadata !​21, metadata !DIExpression()), !dbg !​31 %6 = bitcast i32 %3 to i8, !dbg !​30 call void @​llvm.lifetime.start.p0i8(i64 4, i8 %6) #​3, !dbg !​30 call void @​llvm.dbg.declare(metadata i32* %3, metadata !​22, metadata !DIExpression()), !dbg !​32 br label %7, !dbg !​30

[...]

!​30 = !DILocation(line: 5, column: 3, scope: !​16)

llvmbot commented 4 years ago

Looking at the IR, the branch instruction in the first bb of func_10 gets assigned line 5.

define nonnull i32 @​func_10() local_unnamed_addr #​0 !dbg !​16 { call void @​llvm.dbg.value(metadata i32 @​a, metadata !​20, metadata !DIExpression()), !dbg !​24 %1 = load i32, i32* @​a, align 4, !dbg !​25, !tbaa !​27 %2 = icmp eq i32 %1, 0, !dbg !​31 br i1 %2, label %4, label %3, !dbg !​32

[...]

!​32 = !DILocation(line: 5, column: 3, scope: !​16)

llvmbot commented 4 years ago

The stepping here is really interesting.

Line 7 -> Line 5 -> Line 12

The first transition seems wrong because it's straight line code and we jump backwards (unless instructions are reordered). Still, the fact that the je points to an assignment is fishy.