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 = ®info_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).