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" > + [(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 } } */ -- Thanks, Xionghu