https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128438
Bug ID: 128438
Summary: Missed reassociation to improve frame_init_lowres_core
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: law at gcc dot gnu.org
Blocks: 26163
Target Milestone: ---
Target: riscv
There's a hot block in frame_init_lowres_core in x264 where we're missing a
simplification that's costing us about 1b instructions on RISC-V.
Consider:
typedef unsigned char u8;
int
f1 (u8 a, u8 b, u8 c, u8 d)
{
return (((a + b + 1) >> 1) + ((c + d + 1) >> 1) + 1) >> 1;
}
We generate:
add a1,a0,a1
add a0,a2,a3
addiw a1,a1,1
addiw a0,a0,1
sraiw a1,a1,1
sraiw a0,a0,1
addw a0,a0,a1
addiw a0,a0,1
srli a0,a0,1
We can reassociate and combine constant terms to get:
add a1,a0,a1
add a0,a2,a3
addi t1,a0,3
addi t0,a1,1
sraiw t2,t0,1
sraiw a2,t1,1
addw a3,a2,t2
srli a0,a3,1
The general rule is something like this:
((X + C1) >> K) + Y + C2 -> ((X + C1 + (C2 << K)) >> K) + Y
Where the (C1 + (C2 << K)) obviously simplifies to a new constant.
You have to prove that (X+C1), (C2<<K), (C1 + (C2 << K)) and (X + C1 + (C2 <<
K)) do not overflow.
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26163
[Bug 26163] [meta-bug] missed optimization in SPEC (2026, 2k17, 2k and 2k6 and
95)