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.