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

            Bug ID: 123967
           Summary: Improve if-converted sequence on risc-v
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

For this testcase (500.perlbench, semi-hot):

typedef long int __ssize_t;
typedef __ssize_t ssize_t;
typedef long unsigned int size_t;
typedef size_t STRLEN;
typedef struct cop COP;
typedef struct sv SV;
typedef struct p5rx REGEXP;
typedef struct magic MAGIC;
typedef unsigned char U8;
typedef int I32;
typedef unsigned int U32;
struct sv
{
  void *sv_any;
  U32 sv_flags;
  union
  {
    SV *svu_rv;
  } sv_u;
};
struct p5rx
{
  union
  {
    struct regexp *svu_rx;
  } sv_u;
};
typedef struct regexp
{
  U32 extflags;
} regexp;
typedef struct
{
  char *ganch;
} regmatch_info;
struct cop
{
  U32 cop_hints;
};
struct magic
{
  U8 mg_flags;
  ssize_t mg_len;
};
MAGIC *Perl_mg_find_mglob (SV * sv);
extern COP *PL_curcop;
static STRLEN S_MgBYTEPOS (MAGIC *mg, SV *sv, const char *s, STRLEN len) ;

static struct regexp *
S_ReANY (const REGEXP *const re)
{
  return re->sv_u.svu_rx;
}


I32
Perl_regexec_flags (REGEXP *const rx, char *stringarg, char *strend,
                    char *strbeg, ssize_t minend, SV *sv, void *data,
                    U32 flags)
{
  char *startpos;
  ssize_t minlen;
  const
    _Bool
    utf8_target =
    (((((sv)->sv_flags & 0x20000000)
       && !(((PL_curcop)->cop_hints + 0) & 0x00000008))) ? (_Bool) 1 : (_Bool)
     0);
  regmatch_info reginfo_buf;
  regmatch_info *const reginfo = &reginfo_buf;

  startpos = stringarg;

  MAGIC *mg;



  reginfo->ganch =
    (flags & 0x08)
    ? stringarg
    : ((mg = Perl_mg_find_mglob (sv)) && mg->mg_len >= 0)
    ? strbeg + S_MgBYTEPOS (mg, sv, strbeg, strend - strbeg) : strbeg;



  if ((startpos + minlen) > strend || startpos < strbeg)
      return 0;




  ((utf8_target)
   ? (((S_ReANY ((const REGEXP *) (rx)))->extflags) |=
      (1U << (((0 + 12) + 2) + 6)))
   : (((S_ReANY ((const REGEXP *) (rx)))->extflags) &=
      ~(1U << (((0 + 12) + 2) + 6))));

}

We're getting code like this for rv64gcb_zicond at -O2:

       lw      a3,0(a2)
        bclri   a5,a3,20
        bseti   a3,a3,20
        czero.nez       a5,a5,a4
        czero.eqz       a4,a3,a4
        add     a5,a5,a4

Something like this would be better:
        lw      a4,56(a0)     # a4 = x
        snez    t0,s2         # t0 = (s2 != 0) ? 1 : 0
        slli    t0,t0,20      # t0 = mask (0 or 1<<20)
        bclri   a2,a4,20      # a2 = x & ~(1<<20)
        or      a2,a2,t0      # a2 = (x & ~(1<<20)) | mask  -> desired result
        sw      a2,56(a0)


That sequence would save about 4b instructions on 500.perlbench (I forget which
input).

Reply via email to