public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/105176] New: -fdce causes a non-dead variable to show as optimized out when debugging only at -Os/Oz
@ 2022-04-06 10:32 assaiante at diag dot uniroma1.it
  0 siblings, 0 replies; only message in thread
From: assaiante at diag dot uniroma1.it @ 2022-04-06 10:32 UTC (permalink / raw)
  To: gcc-bugs

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.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-06 10:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-06 10:32 [Bug debug/105176] New: -fdce causes a non-dead variable to show as optimized out when debugging only at -Os/Oz assaiante at diag dot uniroma1.it

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).