https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119433
Bug ID: 119433
Summary: [RISC-V] Reduce critical path with a 2->2 split
Product: gcc
Version: unknown
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: law at gcc dot gnu.org
Target Milestone: ---
Target: riscv
Keywords: missed-optimization
Target: riscv
This testcase when compiled with -O2 -march=rv64gcb_zicond -mabi=lp64d shows
two cases where we could reduce the critical path length with a 2->2 spitter.
struct rtx_def;
typedef struct rtx_def *rtx;
typedef const struct rtx_def *const_rtx;
struct basic_block_def;
typedef struct basic_block_def *basic_block;
enum rtx_code
{
REG,
SIGN_EXTEND,
LAST_AND_UNUSED_RTX_CODE
};
union rtunion_def
{
unsigned int rt_uint;
rtx rt_rtx;
};
typedef union rtunion_def rtunion;
struct rtx_def
{
unsigned int code:16;
union u
{
rtunion fld[1];
} u;
};
enum reg_note
{ REG_DEAD, };
static inline unsigned int
rhs_regno (const_rtx x)
{
return (((x)->u.fld[0]).rt_uint);
}
extern rtx find_reg_note (enum reg_note, const_rtx);
void
optimize_reg_copy_3 (rtx dest, rtx src)
{
rtx src_reg = (((src)->u.fld[0]).rt_rtx);
int src_no = (rhs_regno (src_reg));
int dst_no = (rhs_regno (dest));
if (src_no < 53 || dst_no < 53 || !find_reg_note (REG_DEAD, src_reg))
return;
}
The relevant assembly code:
ld a1,8(a1) # 7 [c=28 l=4] *movdi_64bit/2
lw a5,8(a1) # 12 [c=28 l=4]
*extendsidi2_internal/1
slti a5,a5,53 # 18 [c=4 l=4] *sle_didi
bne a5,zero,.L1 # 19 [c=12 l=4] *branchdi
lw a5,8(a0) # 24 [c=28 l=4]
*extendsidi2_internal/1
slti a5,a5,53 # 30 [c=4 l=4] *sle_didi
bne a5,zero,.L1 # 31 [c=12 l=4] *branchdi
li a0,0 # 34 [c=4 l=4] *movdi_64bit/1
tail find_reg_note # 35 [c=36 l=8]
sibcall_value_internal/1
.L1:
What we want to do is replace the slti+bne sequences with li+blt. The "li" has
no data dependencies and can thus be issued by the processor whenever is
convenient.
In particular we'd want a 2->2 splitter for this:
Trying 26 -> 27:
26: r160:DI=r157:DI>r150:DI
REG_DEAD r157:DI
REG_DEAD r150:DI
REG_EQUAL r157:DI>0x34
27: r158:DI=r160:DI==0
REG_DEAD r160:DI
Failed to match this instruction:
(set (reg:DI 158)
(le:DI (reg:DI 157 [ MEM[(const struct rtx_def
*)dest_10(D)].u.fld[0].rt_uint ])
(reg:DI 150)))