https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105145
Bug ID: 105145 Summary: dropped DWARF location information at -O1/-O2/-O3 upon ftree-dse Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: assaiante at diag dot uniroma1.it Target Milestone: --- When debugging this minimized C example, pointer variable l_158 appears as optimized out at every stepped line, including line 14 where it is used to compute the value of a function call argument. This happens at -O1/O2/O3 but not at -Og. Apparently, -ftree-dse makes the DWARF DIE for l_158 drop a location definition while the ASM stays unchanged. When adding -fno-tree-dse to -O1/O2/O3, the variable value appears at lines 13 and 14. However, it stays as optimized out between line 10 (where it is assigned) to 13. We were not able to pinpoint what may be behind this latter fact, though. Below we provide details for -O1 on x64 and a quick assessment of prior gcc versions. $ cat a.c int *a; int **d = &a; int *e = &d; int f; volatile char g; short h(int b, int c) { return 0; } int main() { int ***l_134 = e; int *l_133 = l_134; int l_141 = 0; int *l_158 = &l_141; short l_185 = 3; *d = l_158; g = ***l_134 + h(f != &l_158, l_185); } GCC and GDB version: - gcc (GCC) 12.0.0 20211227 (experimental) - commit id: 500d3f0a302 - GNU gdb (GDB) 11.2 GDB trace: $ gcc -O1 -g a.c -o opt $ gdb -q opt root@1f83e51b6153:/tmp# gdb -q opt Reading symbols from opt... (gdb) b 14 Breakpoint 1 at 0x4004aa: file a.c, line 14. (gdb) r Starting program: /tmp/opt Breakpoint 1, main () at a.c:14 14 g = ***l_134 + h(f != &l_158, l_185); (gdb) info locals l_134 = 0x601030 <d> l_133 = 0x601030 <d> l_141 = 0 l_158 = <optimized out> l_185 = 3 ASM at -O1: 000000000040048c <main>: 40048c: 48 8b 05 95 0b 20 00 mov 0x200b95(%rip),%rax # 601028 <e> 400493: c7 44 24 fc 00 00 00 movl $0x0,-0x4(%rsp) 40049a: 00 40049b: 48 8d 4c 24 fc lea -0x4(%rsp),%rcx 4004a0: 48 8b 15 89 0b 20 00 mov 0x200b89(%rip),%rdx # 601030 <d> 4004a7: 48 89 0a mov %rcx,(%rdx) 4004aa: 48 8b 00 mov (%rax),%rax 4004ad: 48 8b 00 mov (%rax),%rax 4004b0: 8b 00 mov (%rax),%eax 4004b2: 88 05 88 0b 20 00 mov %al,0x200b88(%rip) # 601040 <g> 4004b8: b8 00 00 00 00 mov $0x0,%eax 4004bd: c3 retq DWARF at -O1: 0x00000101: DW_TAG_variable DW_AT_name ("l_158") DW_AT_decl_file ("/tmp/a.c") DW_AT_decl_line (11) DW_AT_decl_column (0x08) DW_AT_type (0x00000041 "int*") Through some testing we found out that the optimization flag involved in the issue is likely -ftree-dse. If we add -fno-tree-dse to the compilation command line used above, the pointer variable l_158 appears in the current frame with its value correctly shown at line 14. The DWARF location info is correctly defined for the variable throughout its whole lifetime. ASM at -O1 with -fno-tree-dse: 000000000040048c <main>: 40048c: 48 8b 05 95 0b 20 00 mov 0x200b95(%rip),%rax # 601028 <e> 400493: c7 44 24 fc 00 00 00 movl $0x0,-0x4(%rsp) 40049a: 00 40049b: 48 8d 4c 24 fc lea -0x4(%rsp),%rcx 4004a0: 48 8b 15 89 0b 20 00 mov 0x200b89(%rip),%rdx # 601030 <d> 4004a7: 48 89 0a mov %rcx,(%rdx) 4004aa: 48 8b 00 mov (%rax),%rax 4004ad: 48 8b 00 mov (%rax),%rax 4004b0: 8b 00 mov (%rax),%eax 4004b2: 88 05 88 0b 20 00 mov %al,0x200b88(%rip) # 601040 <g> 4004b8: b8 00 00 00 00 mov $0x0,%eax 4004bd: c3 retq DWARF at -O1 with -fno-tree-dse: 0x00000101: DW_TAG_variable DW_AT_name ("l_158") DW_AT_decl_line (11) DW_AT_decl_column (0x08) DW_AT_type (0x00000041 "int*") DW_AT_location (0x00000020: [0x000000000040049b, 0x00000000004004a0): DW_OP_fbreg -12, DW_OP_stack_value [0x00000000004004a0, 0x00000000004004b8): DW_OP_reg2 RCX) DW_AT_GNU_locviews (0x0000001c) In short, the ASM of the main function stays identical but we have an accurate location definition that leads to the correct availability of the value of l_158 in its usage at line 14. We have also tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and for the tested optimization levels the behavior is identical to the git version originally analyzed.