https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120559
Bug ID: 120559 Summary: local variable stack store eliminated while its stack location is kept as passed argument (only with LTO, rv64gc) Product: gcc Version: 13.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: lucian.silistru at gmail dot com Target Milestone: --- Created attachment 61588 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61588&action=edit source code to repro, build.sh to build, riscv-none-elf-gcc-13.3.0 used __attribute__((noinline)) void send_buffer(uint32_t channel, void *ptr, uint32_t size) { struct tx_buffer_entry *entry; channel_init(); entry = get_buffer(); if (entry == NULL) { printf("Error finding buffer\n"); return; } entry->data = ptr; entry->size = size; entry->state = 1; printf("Sending data on channel %u, from loc %p\n", channel, (void*)entry); write_to_hw(channel, (void *)(&entry)); } In a function like the above, sometimes when linking with LTO, entry is used as a register throughout the function body but the end store that copies it to the stack will vanish. write_to_hw() is always called with the value sp+offset written to a1. But "sd entry_reg, offset(sp)" is sometimes deleted. "sd entry_reg, offset(sp)" always shows up in current object disassembly, always shows up in non-LTO linking (no matter how it was compiled), sometimes shows up in LTO-linked versions, at least never seen in gcc 9.3 for years and now on gcc 13.3.0 showed up after that "printf" like function got updated. In the following dasm, a2 ends up being entry, it is never saved to sp+8 but sp+8 is passed to a1 for write_to_hw(): 00000000000101ec <send_buffer.constprop.0>: ... 1023a: e61c sd a5,8(a2) 1023c: 4785 li a5,1 1023e: 85a2 mv a1,s0 10240: 00062823 sw zero,16(a2) 10244: 00f60023 sb a5,0(a2) 10248: 00009517 auipc a0,0x9 1024c: 79050513 addi a0,a0,1936 # 199d8 <__trunctfdf2+0x2ee> 10250: 00c83423 sd a2,8(a6) 10254: 64e010ef jal 118a2 <printf> 10258: 002c addi a1,sp,8 1025a: 8522 mv a0,s0 1025c: f6bff0ef jal 101c6 <write_to_hw> 10260: 60e2 ld ra,24(sp) 10262: 6442 ld s0,16(sp) 10264: 6105 addi sp,sp,32 10266: 8082 ret Attaching small (not functional but should compile just fine) reproduction code. Used xpack-riscv-none-elf-gcc-13.3.0-1 to compiler but initial repro was on a riscv-rtems6-13.3.0. In the attached hw_work.ltrans0.ltrans.254t.optimized, in send_buffer, the register use of entry is idx_20, &entry is passed and never initialized. Main suspicion right now is that this is some UB but I can't figure out/I don't know what exactly.