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)

Reply via email to