$ cat t.c
int test(int x)
{
char buf[128 << 10];
return buf[x];
}
$ ./gcc/cc1 t.c -nostdinc -O2 -fdump-rtl-all -o- 2>/dev/null | grep test: -A20
test:
.LFB0 = .
lu12i.w $r13,-135168>>12 # 0xfffffffffffdf000
ori $r13,$r13,4080
add.d $r3,$r3,$r13
.LCFI0 = .
lu12i.w $r12,-131072>>12 # 0xfffffffffffe0000
lu12i.w $r13,131072>>12 # 0x20000
add.d $r13,$r13,$r12
addi.d $r12,$r3,16
add.d $r12,$r13,$r12
lu12i.w $r13,131072>>12 # 0x20000
st.d $r12,$r3,8
ori $r13,$r13,16
ldx.b $r4,$r12,$r4
add.d $r3,$r3,$r13
.LCFI1 = .
jr $r1
.LFE0:
.size test, .-test
.section .eh_frame,"aw",@progbits
Note the "st.d $r12,$r3,8" instruction is completely meaningless.
The t.c.300r.ira dump contains some "interesting" thing:
Pass 0 for finding pseudo/allocno costs
a0 (r87,l0) best GR_REGS, allocno GR_REGS
a1 (r84,l0) best NO_REGS, allocno NO_REGS
a2 (r83,l0) best GR_REGS, allocno GR_REGS
a0(r87,l0) costs: SIBCALL_REGS:2000,2000 JIRL_REGS:2000,2000
CSR_REGS:2000,2000 GR_REGS:2000,2000 FP_REGS:8000,8000 ALL_REGS:32000,32000
MEM:8000,8000
a1(r84,l0) costs: SIBCALL_REGS:1000000,1000000 JIRL_REGS:1000000,1000000
CSR_REGS:1000000,1000000 GR_REGS:1000000,1000000 FP_REGS:1004000,1004000
ALL_REGS:1016000,1016000 MEM:1004000,1004000
a2(r83,l0) costs: SIBCALL_REGS:1000000,1000000 JIRL_REGS:1000000,1000000
CSR_REGS:1000000,1000000 GR_REGS:1000000,1000000 FP_REGS:1004000,1004000
ALL_REGS:1008000,1008000 MEM:1004000,1004000
Here r84 is the pseudo register for ($frame - 131072). Any idea why the
compiler selects "NO_REGS" here?
FWIW RISC-V port suffers the same issue:
https://godbolt.org/z/aPorqj73b.