https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123904
Bug ID: 123904
Summary: Failure to optimize left shit + and sequence on RISC-V
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: law at gcc dot gnu.org
Target Milestone: ---
I was reviewing some old email and stumbled over this. It's a minor missed
optimization for rv64.
unsigned foo19(unsigned a, unsigned b) {
b = (b << 2) >> 2;
return a + (b << 1);
}
Compiled with -O2 -march=rv64gcbv results in:
bseti a5,zero,31
addi a5,a5,-2
slliw a1,a1,1
and a1,a1,a5
addw a0,a1,a0
There's numerous interesting things in there that look like they might be ripe
for some optimization work. Looking at the .combine dump we have:
Trying 3 -> 7:
3: r138:DI=r148:DI
REG_DEAD r148:DI
7: r141:DI=sign_extend(r138:DI#0<<0x1)
REG_DEAD r138:DI
Failed to match this instruction:
(set (reg:DI 141)
(ashift:DI (sign_extract:DI (reg:DI 148 [ b ])
(const_int 31 [0x1f])
(const_int 0 [0]))
(const_int 1 [0x1])))
That's slli.uw. Though I think we have to be careful with that form. It came
up in some other work and matching it did trip some code quality regressions.
Trying 10, 7 -> 11:
10: r143:DI=0x7ffffffe
7: r141:DI=sign_extend(r138:DI#0<<0x1)
REG_DEAD r138:DI
11: r142:DI=r141:DI&r143:DI
REG_DEAD r143:DI
REG_DEAD r141:DI
REG_EQUAL r141:DI&0x7ffffffe
Failed to match this instruction:
(set (reg:DI 142)
(and:DI (ashift:DI (reg/v:DI 138 [ b ])
(const_int 1 [0x1]))
(const_int 2147483646 [0x7ffffffe])))
That's a define_split which generates a slli.uw + bclr.