On Mon, Jan 10, 2022 at 12:37 AM Xionghu Luo <luo...@linux.ibm.com> wrote: > > Ping, thanks. > > > On 2021/12/13 13:16, Xionghu Luo wrote: > > Add specialized version to combine two instructions from > > > > 9: {r123:CC=cmp(r124:DI&0x600000000,0);clobber scratch;} > > REG_DEAD r124:DI > > 10: pc={(r123:CC==0)?L15:pc} > > REG_DEAD r123:CC > > > > to: > > > > 10: {pc={(r123:DI&0x600000000==0)?L15:pc};clobber scratch;clobber %0:CC;} > > > > then split2 will split it to one rotate dot instruction (to save one > > rotate back instruction) as shifted result doesn't matter when comparing > > to 0 in CCEQmode. > > > > Bootstrapped and regression tested pass on Power 8/9/10, OK for master? > > > > gcc/ChangeLog: > > > > PR target/102239 > > * config/rs6000/rs6000.md (*anddi3_insn_dot): New. > > > > gcc/testsuite/ChangeLog: > > > > PR target/102239 > > * gcc.target/powerpc/pr102239.c: New test. > > --- > > gcc/config/rs6000/rs6000-protos.h | 1 + > > gcc/config/rs6000/rs6000.c | 7 ++++ > > gcc/config/rs6000/rs6000.md | 38 +++++++++++++++++++++ > > gcc/testsuite/gcc.target/powerpc/pr102239.c | 13 +++++++ > > 4 files changed, 59 insertions(+) > > create mode 100644 gcc/testsuite/gcc.target/powerpc/pr102239.c > > > > diff --git a/gcc/config/rs6000/rs6000-protos.h > > b/gcc/config/rs6000/rs6000-protos.h > > index 14f6b313105..3644c524376 100644 > > --- a/gcc/config/rs6000/rs6000-protos.h > > +++ b/gcc/config/rs6000/rs6000-protos.h > > @@ -73,6 +73,7 @@ extern int expand_block_move (rtx[], bool); > > extern bool expand_block_compare (rtx[]); > > extern bool expand_strn_compare (rtx[], int); > > extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode); > > +extern bool rs6000_is_valid_rotate_dot_mask (rtx mask, machine_mode mode); > > extern bool rs6000_is_valid_and_mask (rtx, machine_mode); > > extern bool rs6000_is_valid_shift_mask (rtx, rtx, machine_mode); > > extern bool rs6000_is_valid_insert_mask (rtx, rtx, machine_mode); > > diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c > > index 5e129986516..57a38cf954a 100644 > > --- a/gcc/config/rs6000/rs6000.c > > +++ b/gcc/config/rs6000/rs6000.c > > @@ -11606,6 +11606,13 @@ rs6000_is_valid_mask (rtx mask, int *b, int *e, > > machine_mode mode) > > return true; > > } > > > > +bool > > +rs6000_is_valid_rotate_dot_mask (rtx mask, machine_mode mode) > > +{ > > + int nb, ne; > > + return rs6000_is_valid_mask (mask, &nb, &ne, mode) && nb >= ne && ne > 0; > > +} > > + > > /* Return whether MASK (a CONST_INT) is a valid mask for any rlwinm, > > rldicl, > > or rldicr instruction, to implement an AND with it in mode MODE. */ > > > > diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md > > index 6bec2bddbde..014dc9612ea 100644 > > --- a/gcc/config/rs6000/rs6000.md > > +++ b/gcc/config/rs6000/rs6000.md > > @@ -3762,6 +3762,44 @@ (define_insn_and_split "*and<mode>3_2insn_dot2" > > (set_attr "dot" "yes") > > (set_attr "length" "8,12")]) > > > > +(define_insn_and_split "*anddi3_insn_dot"
This pattern needs a name that better represents its purpose. The pattern name implies that it's operating on a combination of AND and Record Condition bit. Also "insn" is confusing; I think that you are using the template from the 2insn_dot names, so this should explicitly be 1insn. Maybe "branch_anddi3_1insn_dot", or just "branch_anddi3_dot". > > + [(set (pc) > > + (if_then_else (eq (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") > > + (match_operand:DI 2 "const_int_operand" "n,n")) > > + (const_int 0)) > > + (label_ref (match_operand 3 "")) > > + (pc))) > > + (clobber (match_scratch:DI 0 "=r,r")) > > + (clobber (reg:CC CR0_REGNO))] > > + "rs6000_is_valid_rotate_dot_mask (operands[2], DImode) > > + && TARGET_POWERPC64" > > + "#" > > + "&& reload_completed" > > + [(pc)] > > +{ > > + int nb, ne; > > + if (rs6000_is_valid_mask (operands[2], &nb, &ne, DImode) > > + && nb >= ne > > + && ne > 0) > > + { > > + unsigned HOST_WIDE_INT val = INTVAL (operands[2]); > > + int shift = 63 - nb; > > + rtx tmp = gen_rtx_ASHIFT (DImode, operands[1], GEN_INT (shift)); > > + tmp = gen_rtx_AND (DImode, tmp, GEN_INT (val << shift)); > > + rtx cr0 = gen_rtx_REG (CCmode, CR0_REGNO); > > + rs6000_emit_dot_insn (operands[0], tmp, 1, cr0); > > + rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]); > > + rtx cond = gen_rtx_EQ (CCEQmode, cr0, const0_rtx); > > + rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx); > > + emit_jump_insn (gen_rtx_SET (pc_rtx, ite)); > > + DONE; > > + } > > + else > > + FAIL; > > +} > > + [(set_attr "type" "shift") > > + (set_attr "dot" "yes") > > + (set_attr "length" "8,12")]) > > > > (define_expand "<code><mode>3" > > [(set (match_operand:SDI 0 "gpc_reg_operand") > > diff --git a/gcc/testsuite/gcc.target/powerpc/pr102239.c > > b/gcc/testsuite/gcc.target/powerpc/pr102239.c > > new file mode 100644 > > index 00000000000..1bafc9fe18e > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/powerpc/pr102239.c > > @@ -0,0 +1,13 @@ > > +/* { dg-do compile } */ > > +/* { dg-require-effective-target lp64 } */ > > +/* { dg-options "-O2" } */ > > + > > +void foo(long arg) > > +{ > > + if (arg & ((1UL << 33) | (1UL << 34))) > > + asm volatile("# if"); > > + else > > + asm volatile("# else"); > > +} > > + > > +/* { dg-final { scan-assembler-times "rldicr." 1 } } */ You should use {\mrldicr\.\M} . I believe that the period in "rldicr." will match any character as a regex, not the explicit "." that you intend. This patch is okay with those issues fixed. Thanks, David > > -- > Thanks, > Xionghu