https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128421
Bug ID: 128421
Summary: Poor register allocation on RISC-V?
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: law at gcc dot gnu.org
Target Milestone: ---
short *lowres_costs[][7];
struct sps {
int i_mb_width, i_mb_height
} mc_2(int *, short *, short *, short *, short *, int), *sps;
struct x264 {
struct {
int i_mb_x, i_mb_stride
} mb;
int scratch_buffer
};
#define CLIP_ADD(s, x) s = x < 5 ? s + x : 5
int propagate_frames, propagate_p0;
short propagate_frames_0_1, propagate_frames_0_0, propagate_propagate_cost;
void propagate(struct x264 *h) {
short *ref_costs[] = {};
short *mvs[2];
int *buf = &h->scratch_buffer;
for (; h;) {
int mb_index = h->mb.i_mb_stride;
mc_2(buf, &propagate_propagate_cost, &propagate_frames_0_0,
lowres_costs[propagate_p0][0], &propagate_frames_0_1,
sps->i_mb_width);
for (; h->mb.i_mb_x < sps; h->mb.i_mb_x++, mb_index++) {
int propagate_amount = buf[h->mb.i_mb_x];
for (int list = 0; list < 2; list++)
if ((propagate_frames, lowres_costs)[propagate_p0][0]) {
int listamount = propagate_amount;
if (*mvs)
continue;
int mbx = mvs[mb_index][0] + h->mb.i_mb_x;
int idx0 = h->mb.i_mb_stride;
int idx3 = h->mb.i_mb_stride;
int idx1weight = mvs[mb_index][0];
int idx3weight = mvs[mb_index][0];
if (mvs[mb_index][1])
CLIP_ADD(ref_costs[list][idx0], idx1weight);
else if (mbx < h && sps->i_mb_height)
CLIP_ADD(ref_costs[list][idx3], listamount * idx3weight >> 10);
}
}
}
}
The bad code, built with -Ofast -march=rv64gcbv_zicond_zvbb_zvl128b -mabi=lp64d
You're looking for this fragment:
li t0,4096
addi t4,t0,1023
ld t0,40(sp)
sd t4,24(sp)
sh1add t4,s10,t0
ld t0,24(sp)
sd t4,16(sp)
ble t2,t0,.L7
Note the store/load pair around the sh1add. This should be investigated to
see if we're holding one or more values that could be rematerialized and we
could then drop the store/load pair. This is obviously from x264.