[Bug debug/105161] New: variable constant-folded in its uses appears as optimized out depending on where it is assigned

assaiante at diag dot uniroma1.it gcc-bugzilla@gcc.gnu.org
Tue Apr 5 14:25:07 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105161

            Bug ID: 105161
           Summary: variable constant-folded in its uses appears as
                    optimized out depending on where it is assigned
           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 j is shown as optimized out when debugging
line 8, where it is used to index an access to global array b for assigning
volatile global variable a. The other two variables i and k used for the access
are instead available. This happens at possibly any optimization level: we
tested -Og, -O1, -O2, and -O3.

We suppose the operation (j)*k is constant-folded to 0 when computing the
offset for accessing b. The variable remains optimized out also under other
value choices for j that we tested. But it becomes visible if we make j
non-constant (for instance with “(j++)*k” at line 8).

We also note that if the assignment is done at declaration time (e.g., “int i =
0, j = 0, k;” with line 6 becoming simply “k=0;”), then variable j becomes
visible with 0 value.

Furthemore, for the modified code, older versions of gdb (e.g. 8.1) will not
list j among local variables: we believe this may be a then-fixed gdb bug, but
perhaps still worth mentioning.

We provide details for -Og on x64 and a quick assessment of older gcc versions
below.

$ cat a.c
volatile int a;
int b[10][2];
int main() {
  int i = 0, j, k;
  for (; i < 10; i++) {
    j = k = 0;
    for (; k < 1; k++)
      a = b[i][(j)*k];
  }
}

GCC and GDB version:
- gcc (GCC) 12.0.0 20211227 (experimental) - commit id: 500d3f0a302
- GNU gdb (GDB) 11.2

GDB trace:
$ gcc -Og -g a.c -o opt
$ gdb -q opt
Reading symbols from opt...
(gdb) b 8
Breakpoint 1 at 0x40048d: file a.c, line 8.
(gdb) r
Starting program: /home/stepping/37/reduce/opt 

Breakpoint 1, main () at a.c:8
8             a = b[i][(j)*k];
(gdb) info loc
i = 0
j = <optimized out>
k = 0


ASM of main function at Og:
0000000000400486 <main>:
 400486:       ba 00 00 00 00          mov    $0x0,%edx
 40048b:       eb 1a                   jmp    4004a7 <main+0x21>
 40048d:       48 63 ca                movslq %edx,%rcx
 400490:       8b 0c cd 60 10 60 00    mov    0x601060(,%rcx,8),%ecx
 400497:       89 0d 13 0c 20 00       mov    %ecx,0x200c13(%rip)        #
6010b0 <a>
 40049d:       83 c0 01                add    $0x1,%eax
 4004a0:       85 c0                   test   %eax,%eax
 4004a2:       7e e9                   jle    40048d <main+0x7>
 4004a4:       83 c2 01                add    $0x1,%edx
 4004a7:       83 fa 09                cmp    $0x9,%edx
 4004aa:       7f 07                   jg     4004b3 <main+0x2d>
 4004ac:       b8 00 00 00 00          mov    $0x0,%eax
 4004b1:       eb ed                   jmp    4004a0 <main+0x1a>
 4004b3:       b8 00 00 00 00          mov    $0x0,%eax
 4004b8:       c3                      retq    
 4004b9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)



DWARF at -Og:
0x0000009b:     DW_TAG_variable
                  DW_AT_name    ("i")
                  DW_AT_decl_column     (0x07)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_location        (0x00000010: 
                     [0x0000000000400486, 0x000000000040048d): DW_OP_lit0,
DW_OP_stack_value
                     [0x000000000040048d, 0x00000000004004b9): DW_OP_reg1 RDX)
                  DW_AT_GNU_locviews
    (0x0000000c)

0x000000ab:     DW_TAG_variable
                  DW_AT_name    ("j")
                  DW_AT_decl_file       ("/home/stepping/37/reduce/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x0e)
                  DW_AT_type    (0x00000041 "int")

0x000000b5:     DW_TAG_variable
                  DW_AT_name    ("k")
                  DW_AT_decl_column     (0x11)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_location        (0x0000001e: 
                     [0x000000000040048d, 0x00000000004004a7): DW_OP_reg0 RAX)
                  DW_AT_GNU_locviews
    (0x0000001c)


>From DWARF information, attributes location and const value are completely
missing for variable j, while other variables have a correct location
definition that makes them available at line 8.

Interestingly, if we modify the source code by initializing variable j earlier
at line 4, the const value attribute is correctly added to variable’s DIE and
therefore the variable is correctly available at line 8 at every optimization
level.

DWARF at -Og (with j initialization at line 4):
0x0000009b:     DW_TAG_variable
                  DW_AT_name    ("i")
                  DW_AT_decl_column     (0x07)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_location        (0x00000010: 
                     [0x0000000000400486, 0x000000000040048d): DW_OP_lit0,
DW_OP_stack_value
                     [0x000000000040048d, 0x00000000004004b9): DW_OP_reg1 RDX)
                  DW_AT_GNU_locviews   (0x0000000c)

0x000000ab:     DW_TAG_variable
                  DW_AT_name    ("j")
                  DW_AT_decl_file       ("/tmp/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x0e)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_const_value     (0x00)

0x000000b6:     DW_TAG_variable
                  DW_AT_name    ("k")
                  DW_AT_decl_column     (0x15)
                  DW_AT_type    (0x00000041 "int")
                  DW_AT_location        (0x0000001e: 
                     [0x000000000040048d, 0x00000000004004a7): DW_OP_reg0 RAX)
                  DW_AT_GNU_locviews    (0x0000001c)


We have also tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and the
variable j is always optimized out on line 6 at any optimization level.


More information about the Gcc-bugs mailing list