https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126074

            Bug ID: 126074
           Summary: Missing cases for constant synthesis on RISC-V
           Product: gcc
           Version: 17.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: ---

The constant synthesis code for the RISC-V port does not currently utilize
shNadd.uw instructions.  There is a class of constants where doing so would be
useful, though it's unclear how often these constants are occurring in
practice.

Conceptually these constants are going to be fairly narrow as many of the cases
are handled by existing shNadd support as well as other mechanisms. 

What I've come up with is the constant must have bit 31+N on.  Bits 32+N up to
bit 63 must be off.  The constant must be evenly divisible by 3, 5, or 9 for N
== 1, 2 or 3 respectively.  If we divide the constant by 3, 5 or 9 the result
of that division must have bit 31 set and the low 12 bits clear.

As a concrete example, consider 0x180005000UL.

lui t0, 0x80001    // Produces 0xffffffff80001000
sh2add dest,t0,t0  // Produces 0x180005000



Right now LLVM and gcc generate

        lui     a0, 384        // produces 0x180000
        addi    a0, a0, 5      // produces 0x180005
        slli    a0, a0, 12     // produces 0x180005000

So we'd save one instruction for this class of constants.

The biggest worry I'd have would be if there are constants that fit this
pattern, but which are more efficiently synthesized through other means.

Reply via email to