Message ID | 20240119070540.95115-1-monk.chiang@sifive.com |
---|---|
State | New |
Headers | show |
Series | RISC-V: Add split pattern to generate SFB instructions. [PR113095] | expand |
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.chiang@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 >
On 1/19/24 00:09, Kito Cheng wrote: > Thanks! generally LGTM, but I would wait one more week to see any > other comments :)Just a note. 113095 isn't marked as a regression, but it most definitely is a regression. So this meets the stage4 criteria. > > On Fri, Jan 19, 2024 at 3:05 PM Monk Chiang <monk.chiang@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. I would probably suggest seeing if these still work when the NE nodes do not have a mode (ie, replace "ne:X" with just "ne". Our docs are a bit unclear on that topic IIRC and it looks like the RISC-V backend is inconsistent. More importantly, this message doesn't indicate if/how this patch was tested. Given it's conditional on SFB a bug here would be narrow, but we should still be doing a regression test. Jeff
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 } } */