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)))