https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124006
Bug ID: 124006
Summary: Improve another conditional sequence for 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: ---
This is using a generalized conditional move sequence when compiled with -O2
-march=rv64gcb_zicond (as noted by the pair of czero instructions with opposite
polarity).
It should be possible to eliminate one of the czero's by realizing this is just
a conditional IOR of a 32bit object. So load a constant when the relevant
bit(s) set into a temporary GPR. Conditionally zero the GPR, then IOR the
temporary with the original value.
typedef long int __ssize_t;
typedef __ssize_t ssize_t;
typedef unsigned long UV;
typedef signed char I8;
typedef unsigned char U8;
typedef int I32;
typedef unsigned int U32;
struct regnode
{
U8 type;
};
typedef struct regnode regnode;
struct scan_data_t;
typedef struct regnode_charclass regnode_charclass;
struct regnode_charclass_class;
typedef struct regnode_charclass_class regnode_charclass_posixl;
typedef struct regnode_ssc regnode_ssc;
typedef struct RExC_state_t RExC_state_t;
regnode *Perl_regnext (regnode * p);
struct regnode_ssc
{
};
extern const U8 PL_regkind[];
struct RExC_state_t
{
};
typedef struct scan_data_t
{
I32 flags;
} scan_data_t;
ssize_t
S_study_chunk (RExC_state_t *pRExC_state, regnode **scanp,
ssize_t *minlenp, ssize_t *deltap,
regnode *last,
scan_data_t *data,
I32 stopparen,
U32 recursed_depth,
regnode_ssc *and_withp, U32 flags, U32 depth)
{
regnode *scan = *scanp, *next;
int is_inf = (flags & 0x0400) && (data->flags & 0x0040);
int is_inf_internal = 0;
fake_study_recurse:
{
UV min_subtract = 0;
_Bool unfolded_multi_char = (0);
ssize_t mincount, maxcount, minnext, deltanext, pos_before = 0;
I32 fl = 0, f = flags;
regnode *const oscan = scan;
regnode_ssc this_class;
regnode_ssc *oclass = ((void *) 0);
I32 next_is_eval = 0;
switch (PL_regkind[((scan)->type)])
{
case 42:
is_inf = is_inf_internal = 1;
scan = Perl_regnext (scan);
goto optimize_curly_tail;
case 44:
do_curly:
data->flags &= ~(0x0080 | 0x0100 | 0x0200);
if (is_inf)
data->flags |= 0x0040;
nogo:
optimize_curly_tail:
}
}
finish:
}
And the relevant part of the resulting assembly:
lw a2,0(a5)
andi a2,a2,-897
ori a4,a2,64
czero.eqz a4,a4,a3
czero.nez a3,a2,a3
addw a4,a4,a3
sw a4,0(a5)
ret