[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