https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119847
Bug ID: 119847
Summary: RISC-V:GCC fail to optimize repeated patterns in
volatile operations
Product: gcc
Version: 14.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: bigmagicreadsun at gmail dot com
Target Milestone: ---
When optimizing volatile memory operations, GCC 13.1 and 14.1 generate
redundant instruction sequences instead of optimizing them. Below is my test
case:
-march=rv64gc -mabi=lp64d -Os
<C>
#include <stdint.h>
uint16_t test_rd(uint32_t addr)
{
return (uint16_t)(*(volatile uint32_t *)((uintptr_t)(0xF8000000 + (addr <<
2))));
}
void test(uint16_t *buf)
{
buf[10] = test_rd(0x300ae);
buf[11] = test_rd(0x300ad);
buf[12] = test_rd(0x300ac);
}
Generated assembly (GCC 13.1/14.1):
<ASM>
test:
li a5,65024000
slli a5,a5,6
addi a5,a5,696
lw a5,0(a5)
sh a5,20(a0)
li a5,65024000
slli a5,a5,6
addi a5,a5,692
lw a5,0(a5)
sh a5,22(a0)
li a5,65024000
slli a5,a5,6
addi a5,a5,688
lw a5,0(a5)
sh a5,24(a0)
ret
The sequence li a5,65024000 + slli a5,a5,6 is needlessly repeated for each
test_rd() call. Full example: https://godbolt.org/z/1ooj71f6f
Expected behavior (GCC 12.1):
<ASM>
test:
li a5,65024000
slli a5,a5,6
addi a4,a5,696
lw a4,0(a4)
sh a4,20(a0)
addi a4,a5,692
addi a5,a5,688
lw a4,0(a4)
lw a5,0(a5)
sh a4,22(a0)
sh a5,24(a0)
ret
The older compiler correctly avoids redundant base address calculations. Why
does this optimization regress in GCC 13/14?