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.