https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123001
Bug ID: 123001
Summary: Assignments to globally allocated struct fields
removed with -O1.
Product: gcc
Version: 15.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: grubba at grubba dot org
Target Milestone: ---
Regression between gcc version 14.3.1 20250801 (Gentoo 14.3.1_p20250801 p4) and
gcc version 15.2.1 20251122 (Gentoo 15.2.1_p20251122 p3).
Fragment from Pike 9.0 src/peep.c (full repository available at
https://pike.lysator.liu.se/development/git/):
ptrdiff_t insert_opcode2(unsigned int f,
INT32 b,
INT32 c,
INT_TYPE current_line,
struct pike_string *current_file)
{
/* volatile */ p_instr *p;
p=(p_instr *)buffer_alloc(&instrbuf, sizeof(p_instr));
p->opcode=f;
p->line=current_line;
copy_shared_string(p->file, dmalloc_touch_named(struct pike_string *,
current_file,
"insert_opcode"));
p->arg=b;
p->arg2=c;
// fprintf(stderr, "p: %p\n", p);
return p - (p_instr *)buffer_ptr(&instrbuf);
}
Enabling either of the volatile or the fprintf call or compiling with -O0
causes the issue to go away.
Disassembly when the issue is present:
Dump of assembler code for function insert_opcode2:
0x00000000001e9b10 <+0>: endbr64
0x00000000001e9b14 <+4>: push %r12
0x00000000001e9b16 <+6>: lea 0x22b163(%rip),%rdi # 0x414c80
<instrbuf>
0x00000000001e9b1d <+13>: mov %r8,%r12
0x00000000001e9b20 <+16>: push %rbp
0x00000000001e9b21 <+17>: push %rbx
0x00000000001e9b22 <+18>: mov 0x22b157(%rip),%rbx # 0x414c80
<instrbuf>
0x00000000001e9b29 <+25>: lea 0x20(%rbx),%rbp
0x00000000001e9b2d <+29>: cmp %rbp,0x22b154(%rip) # 0x414c88
<instrbuf+8>
0x00000000001e9b34 <+36>: jb 0x1e9b70 <insert_opcode2+96>
0x00000000001e9b36 <+38>: mov $0x20,%esi
0x00000000001e9b3b <+43>: call 0x637b0 <buffer_check_space>
0x00000000001e9b40 <+48>: mov %rbx,%rax
0x00000000001e9b43 <+51>: sub 0x22b13e(%rip),%rax # 0x414c88
<instrbuf+8>
0x00000000001e9b4a <+58>: add 0x22b13f(%rip),%rax # 0x414c90
<instrbuf+16>
0x00000000001e9b51 <+65>: mov %rbp,0x22b128(%rip) # 0x414c80
<instrbuf>
0x00000000001e9b58 <+72>: sar $0x5,%rax
0x00000000001e9b5c <+76>: addl $0x1,(%r12)
0x00000000001e9b61 <+81>: pop %rbx
0x00000000001e9b62 <+82>: pop %rbp
0x00000000001e9b63 <+83>: pop %r12
0x00000000001e9b65 <+85>: ret
0x00000000001e9b66 <+86>: cs nopw 0x0(%rax,%rax,1)
0x00000000001e9b70 <+96>: mov $0x20,%esi
0x00000000001e9b75 <+101>: call 0x63480 <buffer_grow>
0x00000000001e9b7a <+106>: mov 0x22b0ff(%rip),%rbx # 0x414c80
<instrbuf>
0x00000000001e9b81 <+113>: lea 0x22b0f8(%rip),%rdi # 0x414c80
<instrbuf>
0x00000000001e9b88 <+120>: lea 0x20(%rbx),%rbp
0x00000000001e9b8c <+124>: jmp 0x1e9b36 <insert_opcode2+38>
End of assembler dump.
As can be seen by the disassembly, all of the assignments to the fields of p
appear to have been dead-code eliminated.