https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105124
Bug ID: 105124 Summary: -Og loses DWARF value for a reassigned variable that is kept instead by other optimization levels 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: --- In this minimized C code, variable l_62 appears as optimized out at line 6, where it is assigned again with the same value and used in the assignment of global variable a. The variable is then available at line 8 with its correct value 6 coming from the update at line 7. This behavior only occurs when the optimization level is Og, while at -O1 and higher optimization levels the variable is always visible with a correct value available. Interestingly, if we assign l_62 for instance with 2 at line 4, then the issue is no longer present at Og and the value 2 is displayed at line 6 (just like at -O1/O2/O3). We also note that, in this case, at -O1/-Og the DWARF info contains values 0 and 6, while at -O2/-O3 also value 0 which is in use only between line 6 and 7. We provide below a detailed analysis on x64. $ cat a.c short a; int foo1() { return 0; } short foo0(int d) { int e, f = 11, l_62 = 0; e = foo1(); a = f | (l_62 = e) >= d; l_62 = 6; return d; } int main() { foo0(0); } GCC and GDB version (GCC commit id: 500d3f0a302): $ gcc --version gcc (GCC) 12.0.0 20211227 (experimental) $ gdb --version GNU gdb (GDB) 11.2 GDB trace: $ gcc -Og -g a.c -o opt $ gdb -q opt Reading symbols from opt... (gdb) b 6 Breakpoint 1 at 0x40048f: file a.c, line 6. (gdb) r Starting program: /home/stepping/4/reduce/opt Breakpoint 1, foo0 (d=d@entry=0) at a.c:6 6 a = f | (l_62 = e) >= d; (gdb) info loc e = <optimized out> f = 11 l_62 = <optimized out> (gdb) n 8 return d; (gdb) info loc e = <optimized out> f = 11 l_62 = 6 ASM of foo0 function: 000000000040048c <foo0>: 40048c: 53 push %rbx 40048d: 89 fb mov %edi,%ebx 40048f: 66 c7 05 92 0b 20 00 movw $0xb,0x200b92(%rip) # 60102a <a> 400496: 0b 00 400498: 89 d8 mov %ebx,%eax 40049a: 5b pop %rbx 40049b: c3 retq DWARF at -Og: 0x000000c9: DW_TAG_variable DW_AT_name ("l_62") DW_AT_decl_file ("/home/stepping/4/reduce/a.c") DW_AT_decl_line (4) DW_AT_decl_column (0x12) DW_AT_type (0x0000007f "int") DW_AT_location (0x00000010: [0x000000000040048f, 0x000000000040048f): DW_OP_lit0, DW_OP_stack_value [0x0000000000400498, 0x000000000040049c): DW_OP_lit6, DW_OP_stack_value) DW_AT_unknown_2137 (0x0000000c) >From a quick analysis of DWARF symbols, the problem seems to be in the location definition of the variable. The first entry is an empty range when it should probably include the instruction at 40048f which is associated with line 6. We tried to manually patch the executable file from -Og by setting the first entry of the location [0x000000000040048f, 0x000000000040048f) to [0x000000000040048f, 0x0000000000400498). After the change, the variable is displayed. At -O1 and higher optimization levels, the first entry of the DWARF location info contains the correct range that includes the ASM instruction associated with line 6. DWARF at O1 (identical at O2/O3, only addresses change): 0x000000a1: DW_TAG_variable DW_AT_abstract_origin (0x000000e2 "l_62") DW_AT_location (0x00000020: [0x00000000004003a0, 0x00000000004003ac): DW_OP_lit0, DW_OP_stack_value [0x00000000004003ac, 0x00000000004003af): DW_OP_lit6, DW_OP_stack_value) DW_AT_unknown_2137 (0x0000001c) If we interpret the code correctly, foo1 is always inlined/constant-propagated, while foo0 is inlined at other optimization levels but not at -Og. We have also tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and the variable l_62 is always optimized out on line 6 at each optimization level. The only exception is gcc-7 that produces (only at Og) a wrong debug information, since at line 6 l_62 has 6 as current value.