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

Reply via email to