https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127778
Bug ID: 127778
Summary: RISC-V: Missed optimization for non-stack base +
[2048, 4094] after PR120811
Product: gcc
Version: 16.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: luismgsilva at outlook dot com
Target Milestone: ---
Created attachment 65783
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65783&action=edit
RISC-V: Restore sum-of-two-s12 add split without undoing PR120811
PR target/120811 removed `*add<mode>3_const_sum_of_two_s12` so that post-reload
combine would not squash the `addi` pairs LRA emits for out-of-range frame
offsets. That pattern was also the split for an ordinary (non-SP/FP) base plus
a constant in `(2048, 4094]` or `[-4096, -2049]`: `addi` of 2047 or -2048, with
the remainder folded into the memory operand.
After the removal those addresses are materialized with `li`/`lui` and `add`.
This shows up in Dhrystone `Proc_8` on the store to `Arr_2[Int_Loc +
20][Int_Loc]`. The row displacement is `20 * 50 * sizeof (int) == 4000`.
Reduced testcase, compiled with `-O2 -march=rv32gc -mabi=ilp32`:
void
store_4000 (int *p, int v)
{
p[1000] = v;
}
GCC 15:
addi a0,a0,2047
sw a1,1953(a0) # 2047 + 1953 = 4000
GCC 16:
li a5,4096
add a0,a0,a5
sw a1,-96(a0) # 4096 - 96 = 4000
The same sequence appears for a load from `p[1000]`.
The attached patch restores `*add<mode>3_const_sum_of_two_s12` for bases other
than the stack pointer, the frame pointer, and other frame-related registers.
`store_4000` returns to the GCC 15 sequence, and the LRA reloads covered by
`gcc.target/riscv/pr120811.c` stay an `addi` from `sp` plus a load or store
with a signed 12-bit offset.