DeadArgElim pass marks unused function arguments
as ‘undef’ without updating existing dbg.values referring to it.
As a consequence the debug info metadata in the final executable is wrong.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Please see the following lldb session:
...
(lldb) b f2
Breakpoint 1: where = test`f2 at test.c:4, address = 0x0000000000400460
(lldb) r
Process 12105 launched: './test' (x86_64)
Process 12105 stopped
* thread #1, name = 'test', stop reason = breakpoint 1.1
frame #0: 0x0000000000400460 test`f2(k=1) at test.c:4
(lldb) p k
(int) $0 = 1
(lldb) register read
General Purpose Registers:
rax = 0x0000000000400480 test`main at test.c:12
rbx = 0x0000000000000000
rcx = 0x0000000000000000
rdx = 0x00007fffffffdcd8
rdi = 0x0000000000000001
rsi = 0x00007fffffffdcc8
rbp = 0x00000000004004a0 test`__libc_csu_init
rsp = 0x00007fffffffdbd8
r8 = 0x0000000000400490 test`__libc_csu_fini
r9 = 0x00007ffff7de7ab0 ld-linux-x86-64.so.2`___lldb_unnamed_symbol57$$ld-linux-x86-64.so.2
r10 = 0x0000000000000846
r11 = 0x00007ffff7a2d740 libc.so.6`__libc_start_main at libc-start.c:134
r12 = 0x0000000000400370 test`_start
r13 = 0x00007fffffffdcc0
r14 = 0x0000000000000000
r15 = 0x0000000000000000
rip = 0x0000000000400460 test`f2 at test.c:4
rflags = 0x0000000000000246
cs = 0x0000000000000033
fs = 0x0000000000000000
gs = 0x0000000000000000
ss = 0x000000000000002b
ds = 0x0000000000000000
es = 0x0000000000000000
...So, parameter 'k' does not have value 1, it is wrong. After applying the patch the value will be optimized out.
C code of the test case can be found as a comment in the attached llvm test.
Thanks, this looks mostly good, minor comments for the testcase inline.
Why doesn't this do the right thing automatically though? What does the dbg.value point to after %k is dropped?
| test/Transforms/DeadArgElim/dbginfo-update-dbgval.ll | ||
|---|---|---|
| 27 ↗ | (On Diff #165030) | can you also add a check that f2 no longer has an argument? |
| 79 ↗ | (On Diff #165030) | You can probably strip out all TBAA metadata, it just distracts in this testcase. |
Because %k isn't deleted (I have an explanation in an inline comment). This part of DAE just edits calls to 'f2' s.t they pass in undef wherever they would have passed in a "real" value for %k.
| lib/Transforms/IPO/DeadArgumentElimination.cpp | ||
|---|---|---|
| 295 ↗ | (On Diff #165030) | I think you need Changed = true here. Otherwise, this will return false if Fn has no uses. |
| test/Transforms/DeadArgElim/dbginfo-update-dbgval.ll | ||
| 27 ↗ | (On Diff #165030) | DAE doesn't remove the argument here, see the comment from SurveyFunction: // We consider arguments of non-internal functions to be intrinsically alive as // well as arguments to functions which have their "address taken". |
LGTM with TBAA cruft removed.
| test/Transforms/DeadArgElim/dbginfo-update-dbgval.ll | ||
|---|---|---|
| 27 ↗ | (On Diff #165030) | I see. That's fine then. |
@vsk Thanks for the review!
It sounds reasonable to set 'Changed = true' even we change debug info metadata, so I have addressed it with the diff updated.
Thanks, LGTM as well.
| lib/Transforms/IPO/DeadArgumentElimination.cpp | ||
|---|---|---|
| 296 ↗ | (On Diff #165249) | Nit, add a space before the '('? |