https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105194
Bug ID: 105194 Summary: -ftree-dce leads to intermittent visibility of variable due to partial DWARF location ranges Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: dc.delia at protonmail dot com Target Milestone: --- When debugging this code, the value of variable l_33 is available when stepping on line 8 and 10 but appears as optimized out on line 9. We tested and found the issue at -Og/-O1/-O2/-O3. Apparently, with -ftree-dce we get DWARF location info for l_33 that does not include the address of the instruction mapped to line 9. By disabling it, instead of a location attribute we see in DWARF a const value 1 for l_33 set (as in the reassignment at line 9 the program compares a boolean expression against 0), which makes the variable value always available. We found this issue on x64 using gdb 11.2 with gcc commit 500d3f0a302. As for past gcc versions, the issue is found in gcc 9/10/11 (we tested 9.3, 10.3, 11.1) but not in 6/7/8 (6.4, 7.5, 8.4). Attaching an analysis for -Og below: $ cat a.c short a; int b; char c(int d) { return 0; } char e(int d) { return d; } void f(int d) { int l_33 = 1; for (;;) { b = e(l_33); l_33 = a = (d || c(l_33 = 0)) >= 0; if (b) break; } } int main() { f(4); } GDB trace: $ gcc -Og -g a.c -o opt $ gdb -q Reading symbols from opt... (gdb) b f Breakpoint 1 at 0x40048f: file a.c, line 8. (gdb) r Starting program: /tmp/opt Breakpoint 1, f (d=4) at a.c:8 8 b = e(l_33); (gdb) info loc l_33 = 1 (gdb) n 9 l_33 = a = (d || c(l_33 = 0)) >= 0; (gdb) info loc l_33 = <optimized out> (gdb) n 10 if (b) (gdb) info loc l_33 = 1 Code at -Og: 000000000040048f <f>: 40048f: bf 01 00 00 00 mov $0x1,%edi 400494: e8 f3 ff ff ff callq 40048c <e> 400499: 0f be c0 movsbl %al,%eax 40049c: 89 05 8a 0b 20 00 mov %eax,0x200b8a(%rip) # 60102c <b> 4004a2: 66 c7 05 85 0b 20 00 movw $0x1,0x200b85(%rip) # 601030 <a> 4004a9: 01 00 4004ab: 85 c0 test %eax,%eax 4004ad: 74 e0 je 40048f <f> 4004af: c3 retq DWARF info at -Og: 0x000000c6: DW_TAG_variable DW_AT_name ("l_33") DW_AT_decl_file ("/tmp/a.c") DW_AT_decl_line (6) DW_AT_decl_column (0x07) DW_AT_type (0x0000005b "int") DW_AT_location (0x0000001b: [0x000000000040048f, 0x00000000004004a2): DW_OP_lit1, DW_OP_stack_value [0x00000000004004ab, 0x00000000004004b0): DW_OP_lit1, DW_OP_stack_value) DW_AT_GNU_locviews (0x00000017) The transformation behind the issue may be -ftree-dce. If we add -fno-tree-dce to the compilation command line, the value of variable l_33 is correctly shown at line 9. In particular, the DWARF location info is not generated but a const value attribute is emmitted. Code at -Og with -fno-tree-dce: 000000000040048f <f>: 40048f: 55 push %rbp 400490: 53 push %rbx 400491: 89 fd mov %edi,%ebp 400493: bf 01 00 00 00 mov $0x1,%edi 400498: e8 ef ff ff ff callq 40048c <e> 40049d: 0f be d8 movsbl %al,%ebx 4004a0: 89 1d 86 0b 20 00 mov %ebx,0x200b86(%rip) # 60102c <b> 4004a6: 85 ed test %ebp,%ebp 4004a8: 66 c7 05 7f 0b 20 00 movw $0x1,0x200b7f(%rip) # 601030 <a> 4004af: 01 00 4004b1: 85 db test %ebx,%ebx 4004b3: 74 de je 400493 <f+0x4> 4004b5: 5b pop %rbx 4004b6: 5d pop %rbp 4004b7: c3 retq DWARF info at -Og with -fno-tree-dce: 0x000000c6: DW_TAG_variable DW_AT_name ("l_33") DW_AT_decl_file ("/tmp/a.c") DW_AT_decl_line (6) DW_AT_decl_column (0x07) DW_AT_type (0x0000005b "int") DW_AT_const_value (0x01)