https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105176
Bug ID: 105176 Summary: -fdce causes a non-dead variable to show as optimized out when debugging only at -Os/Oz 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, variable l_83 appears as optimized out at line 13, where it is used as a call argument to a function defined in another module. This happens with -Os and -Oz but not with -Og/O1/O2/O3. Apparently, -fdce causes the range in the location definition of variable l_83 to not include the call to the function test. By supplying -fno-dce, the value is visible and the ASM stays unchanged. At other levels the location definition seems richer and the ranges include the call. Below we provide details for -Os on x64 (-Oz looks identical) and a partial assessment of older gcc versions (no issue on 6.4, found in gcc-7+). $ cat a.c enum { a } b; void c() { char d, l_122 = 0; short l_83 = 4; int l_126 = 0; for (; b != 3; ++b) { char l_114 = l_83--; test(l_83, l_122, l_126, l_114); } d = l_83; } int main () { c(); } $ cat lib.c #include <stdio.h> void test(int l_83, int l_122, int l_126, int l_114) { printf("%d %d %d %d", l_83, l_122, l_126, l_114); } GCC and GDB version: - gcc (GCC) 12.0.0 20211227 (experimental) - commit id: 500d3f0a302 - GNU gdb (GDB) 11.2 GDB trace: $ gcc -Os -g a.c lib.c -o opt $ gdb -q opt Reading symbols from opt... (gdb) b 13 Breakpoint 1 at 0x400517: file a.c, line 13. (gdb) r Starting program: /tmp/opt Breakpoint 1, c () at a.c:13 13 test(l_83, l_122, l_126, l_114); (gdb) info loc l_114 = 4 '\004' d = <optimized out> l_122 = 0 '\000' l_83 = <optimized out> l_126 = 0 ASM at -Os: 0000000000400506 <c>: 400506: 53 push %rbx 400507: bb 04 00 00 00 mov $0x4,%ebx 40050c: 83 3d 21 0b 20 00 03 cmpl $0x3,0x200b21(%rip) # 601034 <b> 400513: 74 1e je 400533 <c+0x2d> 400515: ff cb dec %ebx 400517: 31 d2 xor %edx,%edx 400519: 31 f6 xor %esi,%esi 40051b: 31 c0 xor %eax,%eax 40051d: 8d 4b 01 lea 0x1(%rbx),%ecx 400520: 0f bf fb movswl %bx,%edi 400523: 0f be c9 movsbl %cl,%ecx 400526: e8 0a 00 00 00 callq 400535 <test> 40052b: ff 05 03 0b 20 00 incl 0x200b03(%rip) # 601034 <b> 400531: eb d9 jmp 40050c <c+0x6> 400533: 5b pop %rbx 400534: c3 retq DWARF at -Os: 0x000000cf: DW_TAG_variable DW_AT_name ("l_83") DW_AT_decl_line (8) DW_AT_decl_column (0x0b) DW_AT_type (0x00000159 "short int") DW_AT_location (0x00000010: [0x0000000000400506, 0x000000000040050c): DW_OP_lit4, DW_OP_stack_value [0x0000000000400515, 0x0000000000400517): DW_OP_breg3 RBX-1, DW_OP_stack_value) DW_AT_GNU_locviews (0x0000000c) >From DWARF location info at -Os, the range does not include the call to the test function since it is at address 400526. Through some testing we found out that the flag involved in the issue is likely -fdce. If we add -fno-dce to the compilation command line used above, the variable l_83 appears in the current frame with its value correctly shown at line 13. The DWARF location info is correctly defined for the variable throughout its whole lifetime. DWARF at -Os with -fno-dce: 0x000000cf: DW_TAG_variable DW_AT_name ("l_83") DW_AT_decl_line (8) DW_AT_decl_column (0x0b) DW_AT_type (0x00000159 "short int") DW_AT_location (0x00000010: [0x0000000000400506, 0x000000000040050c): DW_OP_lit4, DW_OP_stack_value [0x000000000040050c, 0x0000000000400534): DW_OP_reg3 RBX) DW_AT_GNU_locviews (0x0000000c) >From DWARF location info at -Os with -fno-dce, the range is larger than it is at -Os, thus including the call at address 400526. We also tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and the behavior described above for the git version is also reproduced for all versions except gcc-6.4, where the variable is correctly available.