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

            Bug ID: 124029
           Summary: Improve sgt with certain constants for riscv
           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: ---

Consider this code from 525.x26r_r on rv64gcbv_zicond:

void frob (void);
void
refine_subpel (int cost, int b_chroma_me)
{

  int bcost = bcost = (1 << 28);
  if (b_chroma_me && cost < bcost)
    frob ();
}

Generates:

        li      a5,268435456            # 10    [c=4 l=4]  *movdi_64bit/1
        addi    a5,a5,-1        # 11    [c=4 l=4]  *adddi3/1
        sgt     a0,a0,a5        # 12    [c=4 l=4]  *sgt_didi
        snez    a1,a1   # 7     [c=4 l=4]  *sne_zero_didi
        seqz    a0,a0   # 13    [c=4 l=4]  *seq_zero_didi
        and     a1,a1,a0        # 18    [c=4 l=4]  *anddi3/0
        bne     a1,zero,.L5     # 19    [c=16 l=4]  *branchdi

Note in particular insns 10, 11, 12, 13

That's just trying to compute:
(set (reg:DI 147)
    (gt:DI (reg:DI 151 [ cost ])
        (const_int 268435455 [0xfffffff])))

Of course RISC-V doesn't have an instruction for that.  But there is an
equivalent two instruction sequence.  Add 1 to the constant and convert it to
slt.  ie

(set (reg:DI 147)
     (lt:DI (reg:DI 151) (const_int 0x10000000)

We need a single instruction to construct that constant, then we emit a LT of
two register operands.  So it's a two instruction sequence in the end.  A 3->2
or 4->2 define_split seems appropriate here.

Reply via email to