Thanks! generally LGTM, but I would wait one more week to see any other comments :)
On Fri, Jan 19, 2024 at 3:05 PM Monk Chiang <monk.chi...@sifive.com> wrote: > > Since the match.pd transforms (zero_one == 0) ? y : z <op> y, > into ((typeof(y))zero_one * z) <op> y. Add splitters to recongize > this expression to generate SFB instructions. > > gcc/ChangeLog: > PR target/113095 > * config/riscv/sfb.md: New splitters to rewrite single bit > sign extension as the condition to SFB instructions. > > gcc/testsuite/ChangeLog: > * gcc.target/riscv/sfb.c: New test. > --- > gcc/config/riscv/sfb.md | 32 ++++++++++++++++++++++++++++ > gcc/testsuite/gcc.target/riscv/sfb.c | 24 +++++++++++++++++++++ > 2 files changed, 56 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/riscv/sfb.c > > diff --git a/gcc/config/riscv/sfb.md b/gcc/config/riscv/sfb.md > index 8ab747142c8..520b12c22f9 100644 > --- a/gcc/config/riscv/sfb.md > +++ b/gcc/config/riscv/sfb.md > @@ -35,3 +35,35 @@ > [(set_attr "length" "8") > (set_attr "type" "sfb_alu") > (set_attr "mode" "<GPR:MODE>")]) > + > +;; Combine creates this form ((typeof(y))zero_one * z) <op> y > +;; for SiFive short forward branches. > + > +(define_split > + [(set (match_operand:X 0 "register_operand") > + (and:X (sign_extract:X (match_operand:X 1 "register_operand") > + (const_int 1) > + (match_operand 2 "immediate_operand")) > + (match_operand:X 3 "register_operand"))) > + (clobber (match_operand:X 4 "register_operand"))] > + "TARGET_SFB_ALU" > + [(set (match_dup 4) (zero_extract:X (match_dup 1) (const_int 1) (match_dup > 2))) > + (set (match_dup 0) (if_then_else:X (ne:X (match_dup 4) (const_int 0)) > + (match_dup 3) > + (const_int 0)))]) > + > +(define_split > + [(set (match_operand:X 0 "register_operand") > + (and:X (sign_extract:X (match_operand:X 1 "register_operand") > + (const_int 1) > + (match_operand 2 "immediate_operand")) > + (match_operand:X 3 "register_operand"))) > + (clobber (match_operand:X 4 "register_operand"))] > + "TARGET_SFB_ALU && (UINTVAL (operands[2]) < 11)" > + [(set (match_dup 4) (and:X (match_dup 1) (match_dup 2))) > + (set (match_dup 0) (if_then_else:X (ne:X (match_dup 4) (const_int 0)) > + (match_dup 3) > + (const_int 0)))] > +{ > + operands[2] = GEN_INT (1 << UINTVAL(operands[2])); > +}) > diff --git a/gcc/testsuite/gcc.target/riscv/sfb.c > b/gcc/testsuite/gcc.target/riscv/sfb.c > new file mode 100644 > index 00000000000..22f164051f4 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/sfb.c > @@ -0,0 +1,24 @@ > +//* { dg-do compile } */ > +/* { dg-options "-O2 -march=rv32gc -mabi=ilp32d -mtune=sifive-7-series" } */ > + > +int f1(unsigned int x, unsigned int y, unsigned int z) > +{ > + return ((x & 1) == 0) ? y : z ^ y; > +} > + > +int f2(unsigned int x, unsigned int y, unsigned int z) > +{ > + return ((x & 1) != 0) ? z ^ y : y; > +} > + > +int f3(unsigned int x, unsigned int y, unsigned int z) > +{ > + return ((x & 1) == 0) ? y : z | y; > +} > + > +int f4(unsigned int x, unsigned int y, unsigned int z) > +{ > + return ((x & 1) != 0) ? z | y : y; > +} > +/* { dg-final { scan-assembler-times "bne" 4 } } */ > +/* { dg-final { scan-assembler-times "movcc" 4 } } */ > -- > 2.40.1 >