-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing line information after SROA pass at Og #49630
Comments
From further analysis, we discovered another problem in this testcase that may be more interesting. By setting a breakpoint on line 11 and checking frame var on it, we can see that variable v_1 is not available but after a next command its value shows up.
From the dwarf DIE of the variable v_1 we can see how the location field changes after SROA pass: ----- BEFORE ----- AFTER From the IR it looks like the problem appears upon lowering from dbg.declare to dbg.value: ----- BEFORE ----- AFTER |
Jeremy/Orlando, any comment? |
I think the second problem is a "variable locations and line numbers" don't line up, however the first one is much more interesting, here's the IR pre-isel, slightly edited: call void @llvm.dbg.value(metadata i32 %mul, metadata !13 ('v_1'), Where you can see that the intermediate assignments to v_0 are optimised out and the assignment values replaced with undef. After passing through isel though: DBG_VALUE %7:gr32, $noreg, !"v_1", !DIExpression(), debug-location !17 The undef assignments are re-ordered to go after the "real" final assignment. The DBG_VALUEs for v_0 get compressed by later passes into a single DBG_VALUE $noreg, because the last assignment to it appears to be undef. This is almost certainly because of the existing limitations in instruction scheduling, and the simplistic approach we take towards it. See also: https://lists.llvm.org/pipermail/llvm-dev/2021-June/150846.html Which is the same limitation applied to a different pass (in a slightly different context). In terms of my / our (the Sony bunch)'s priorities this is probably in the middle: it's too hard to fix with DBG_VALUEs, but instruction referencing / DBG_INSTR_REF will make it much easier to solve, sometime soon. |
mentioned in issue llvm/llvm-bugzilla-archive#50475 |
Extended Description
The last assignment to a variable passed to an external function is not reached in debugging.
If we set a breakpoint on line 11, with a next operation we will end up on line 15, thus skipping line 14 where the last assignment is done.
From opt-bisect, the pass after which the line is not reached anymore is: SROA pass.
Beside this, upon calling the external function, the variable v_0 appears to be not available in lldb but we should see that its value is the same as v_1 from its last assignment.
From both asm and IR, we can see that after SROA pass the first two parameters to test_out are the same variable/register:
ASM ----------
400533: 89 df mov %ebx,%edi
400535: 89 de mov %ebx,%esi
400537: 89 ea mov %ebp,%edx
400539: e8 a2 ff ff ff callq 4004e0 <test_out>
IR -------------
call void @test_out(i32 %6, i32 %6, i32 %3, i32 %10) #3, !dbg !26
Could it be possible to map this parameter passing to the last assignment line?
$ cat a.c
int test_in();
void test_out(int v_0, int v_1, int v_2, int v_3);
int main()
{
int v_0, v_1, v_2, v_3;
v_0 = test_in();
v_1 = test_in();
v_2 = test_in();
v_3 = test_in();
v_1 = (v_2 * ~(~v_0 + v_3));
v_0 = (v_2 >> (v_3 < (v_0 < v_1)));
v_0 = (v_2 * v_3);
v_0 = v_1;
v_3 = ((v_1 & (v_2 & v_3)) < v_0);
test_out(v_0, v_1, v_2, v_3);
}
$ cat lib/test.c
#include <stdio.h>
int ctr = 0;
int test_in() {
return ctr++;
}
void test_out(int v_0, int v_1, int v_2, int v_3) {
printf("%d%d%d%d", v_0, v_1, v_2, v_3);
}
$ clang -v
clang version 13.0.0
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
$ lldb -v
lldb version 13.0.0
clang revision c2c977c
lldb revision c2c977c
$ clang -g -Og -o opt lib/test.c a.c
$ lldb opt
(lldb) target create "opt"
Current executable set to '/home/stepping/test/opt' (x86_64).
(lldb) b 11
Breakpoint 1: where = opt`main + 35 at a.c:11:15, address = 0x0000000000400523
(lldb) r
Process 36 launched: '/home/stepping/test/opt' (x86_64)
Process 36 stopped
frame #0: 0x0000000000400523 opt`main at a.c:11:15
8 v_1 = test_in();
9 v_2 = test_in();
10 v_3 = test_in();
-> 11 v_1 = (v_2 * ~(~v_0 + v_3));
12 v_0 = (v_2 >> (v_3 < (v_0 < v_1)));
13 v_0 = (v_2 * v_3);
14 v_0 = v_1;
(lldb) n
Process 36 stopped
frame #0: 0x0000000000400528 opt`main at a.c:15:21
12 v_0 = (v_2 >> (v_3 < (v_0 < v_1)));
13 v_0 = (v_2 * v_3);
14 v_0 = v_1;
-> 15 v_3 = ((v_1 & (v_2 & v_3)) < v_0);
16 test_out(v_0, v_1, v_2, v_3);
17
18 return 0;
(lldb) frame var v_0
(int) v_0 =
(lldb) frame var v_1
(int) v_1 = -6
The text was updated successfully, but these errors were encountered: