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.

Reply via email to