Message ID | 20231224123608.6650-1-xry111@xry111.site |
---|---|
State | New |
Headers | show |
Series | [v2] LoongArch: Expand left rotate to right rotate with negated amount | expand |
LGTM! Thanks! 在 2023/12/24 下午8:33, Xi Ruoyao 写道: > gcc/ChangeLog: > > * config/loongarch/loongarch.md (rotl<mode>3): > New define_expand. > * config/loongarch/simd.md (vrotl<mode>3): Likewise. > (rotl<mode>3): Likewise. > > gcc/testsuite/ChangeLog: > > * gcc.target/loongarch/rotl-with-rotr.c: New test. > * gcc.target/loongarch/rotl-with-vrotr-b.c: New test. > * gcc.target/loongarch/rotl-with-vrotr-h.c: New test. > * gcc.target/loongarch/rotl-with-vrotr-w.c: New test. > * gcc.target/loongarch/rotl-with-vrotr-d.c: New test. > * gcc.target/loongarch/rotl-with-xvrotr-b.c: New test. > * gcc.target/loongarch/rotl-with-xvrotr-h.c: New test. > * gcc.target/loongarch/rotl-with-xvrotr-w.c: New test. > * gcc.target/loongarch/rotl-with-xvrotr-d.c: New test. > --- > > Change from [v1]: > - Wrap the negated wrapping amount with subreg:<IVEC:UNITMODE> for > rotl<IVEC:mode>, to avoid an ICE left rotating QI and HI vectors. > - Add tests for QI, HI, and DI vectors. > > [v1]:https://gcc.gnu.org/pipermail/gcc-patches/2023-December/640872.html > > Bootstrapped and regtested on loongarch64-linux-gnu. Ok for trunk? > > gcc/config/loongarch/loongarch.md | 12 ++++++++ > gcc/config/loongarch/simd.md | 29 +++++++++++++++++++ > .../gcc.target/loongarch/rotl-with-rotr.c | 9 ++++++ > .../gcc.target/loongarch/rotl-with-vrotr-b.c | 7 +++++ > .../gcc.target/loongarch/rotl-with-vrotr-d.c | 7 +++++ > .../gcc.target/loongarch/rotl-with-vrotr-h.c | 7 +++++ > .../gcc.target/loongarch/rotl-with-vrotr-w.c | 28 ++++++++++++++++++ > .../gcc.target/loongarch/rotl-with-xvrotr-b.c | 7 +++++ > .../gcc.target/loongarch/rotl-with-xvrotr-d.c | 7 +++++ > .../gcc.target/loongarch/rotl-with-xvrotr-h.c | 7 +++++ > .../gcc.target/loongarch/rotl-with-xvrotr-w.c | 7 +++++ > 11 files changed, 127 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c > > diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md > index 30025bf1908..939432b83e0 100644 > --- a/gcc/config/loongarch/loongarch.md > +++ b/gcc/config/loongarch/loongarch.md > @@ -2903,6 +2903,18 @@ (define_insn "rotrsi3_extend" > [(set_attr "type" "shift,shift") > (set_attr "mode" "SI")]) > > +;; Expand left rotate to right rotate. > +(define_expand "rotl<mode>3" > + [(set (match_dup 3) > + (neg:SI (match_operand:SI 2 "register_operand"))) > + (set (match_operand:GPR 0 "register_operand") > + (rotatert:GPR (match_operand:GPR 1 "register_operand") > + (match_dup 3)))] > + "" > + { > + operands[3] = gen_reg_rtx (SImode); > + }); > + > ;; The following templates were added to generate "bstrpick.d + alsl.d" > ;; instruction pairs. > ;; It is required that the values of const_immalsl_operand and > diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md > index 13202f79bee..93fb39abcf5 100644 > --- a/gcc/config/loongarch/simd.md > +++ b/gcc/config/loongarch/simd.md > @@ -268,6 +268,35 @@ (define_insn "vrotr<mode>3" > [(set_attr "type" "simd_int_arith") > (set_attr "mode" "<MODE>")]) > > +;; Expand left rotate to right rotate. > +(define_expand "vrotl<mode>3" > + [(set (match_dup 3) > + (neg:IVEC (match_operand:IVEC 2 "register_operand"))) > + (set (match_operand:IVEC 0 "register_operand") > + (rotatert:IVEC (match_operand:IVEC 1 "register_operand") > + (match_dup 3)))] > + "" > + { > + operands[3] = gen_reg_rtx (<MODE>mode); > + }); > + > +;; Expand left rotate with a scalar amount to right rotate: negate the > +;; scalar before broadcasting it because scalar negation is cheaper than > +;; vector negation. > +(define_expand "rotl<mode>3" > + [(set (match_dup 3) > + (neg:SI (match_operand:SI 2 "register_operand"))) > + (set (match_dup 4) > + (vec_duplicate:IVEC (subreg:<IVEC:UNITMODE> (match_dup 3) 0))) > + (set (match_operand:IVEC 0 "register_operand") > + (rotatert:IVEC (match_operand:IVEC 1 "register_operand") > + (match_dup 4)))] > + "" > + { > + operands[3] = gen_reg_rtx (SImode); > + operands[4] = gen_reg_rtx (<MODE>mode); > + }); > + > ;; <x>vrotri.{b/h/w/d} > > (define_insn "rotr<mode>3" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c > new file mode 100644 > index 00000000000..84cc53cecaf > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c > @@ -0,0 +1,9 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > +/* { dg-final { scan-assembler "rotr\\.w" } } */ > + > +unsigned > +t (unsigned a, unsigned b) > +{ > + return a << b | a >> (32 - b); > +} > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c > new file mode 100644 > index 00000000000..14298bf9ee4 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "vrotr\\.b" 2 } } */ > +/* { dg-final { scan-assembler-times "vneg\\.b" 1 } } */ > + > +#define TYPE char > +#include "rotl-with-vrotr-w.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c > new file mode 100644 > index 00000000000..0e971b3235c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "vrotr\\.d" 2 } } */ > +/* { dg-final { scan-assembler-times "vneg\\.d" 1 } } */ > + > +#define TYPE long long > +#include "rotl-with-vrotr-w.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c > new file mode 100644 > index 00000000000..93216ebc245 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "vrotr\\.h" 2 } } */ > +/* { dg-final { scan-assembler-times "vneg\\.h" 1 } } */ > + > +#define TYPE short > +#include "rotl-with-vrotr-w.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c > new file mode 100644 > index 00000000000..d05b86f4716 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c > @@ -0,0 +1,28 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "vrotr\\.w" 2 } } */ > +/* { dg-final { scan-assembler-times "vneg\\.w" 1 } } */ > + > +#ifndef VLEN > +#define VLEN 16 > +#endif > + > +#ifndef TYPE > +#define TYPE int > +#endif > + > +typedef unsigned TYPE V __attribute__ ((vector_size (VLEN))); > +V a, b, c; > + > +void > +test (int x) > +{ > + b = a << x | a >> ((int)sizeof (TYPE) * __CHAR_BIT__ - x); > +} > + > +void > +test2 (void) > +{ > + for (int i = 0; i < VLEN / sizeof (TYPE); i++) > + c[i] = a[i] << b[i] | a[i] >> ((int)sizeof (TYPE) * __CHAR_BIT__ - b[i]); > +} > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c > new file mode 100644 > index 00000000000..2674b1b618c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "xvrotr\\.b" 2 } } */ > +/* { dg-final { scan-assembler-times "xvneg\\.b" 1 } } */ > + > +#define VLEN 32 > +#include "rotl-with-vrotr-b.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c > new file mode 100644 > index 00000000000..e9440331594 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "xvrotr\\.d" 2 } } */ > +/* { dg-final { scan-assembler-times "xvneg\\.d" 1 } } */ > + > +#define VLEN 32 > +#include "rotl-with-vrotr-d.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c > new file mode 100644 > index 00000000000..3d998941f92 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "xvrotr\\.h" 2 } } */ > +/* { dg-final { scan-assembler-times "xvneg\\.h" 1 } } */ > + > +#define VLEN 32 > +#include "rotl-with-vrotr-h.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c > new file mode 100644 > index 00000000000..ca6aa7bae6c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ > +/* { dg-final { scan-assembler-times "xvrotr\\.w" 2 } } */ > +/* { dg-final { scan-assembler-times "xvneg\\.w" 1 } } */ > + > +#define VLEN 32 > +#include "rotl-with-vrotr-w.c"
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 30025bf1908..939432b83e0 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -2903,6 +2903,18 @@ (define_insn "rotrsi3_extend" [(set_attr "type" "shift,shift") (set_attr "mode" "SI")]) +;; Expand left rotate to right rotate. +(define_expand "rotl<mode>3" + [(set (match_dup 3) + (neg:SI (match_operand:SI 2 "register_operand"))) + (set (match_operand:GPR 0 "register_operand") + (rotatert:GPR (match_operand:GPR 1 "register_operand") + (match_dup 3)))] + "" + { + operands[3] = gen_reg_rtx (SImode); + }); + ;; The following templates were added to generate "bstrpick.d + alsl.d" ;; instruction pairs. ;; It is required that the values of const_immalsl_operand and diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md index 13202f79bee..93fb39abcf5 100644 --- a/gcc/config/loongarch/simd.md +++ b/gcc/config/loongarch/simd.md @@ -268,6 +268,35 @@ (define_insn "vrotr<mode>3" [(set_attr "type" "simd_int_arith") (set_attr "mode" "<MODE>")]) +;; Expand left rotate to right rotate. +(define_expand "vrotl<mode>3" + [(set (match_dup 3) + (neg:IVEC (match_operand:IVEC 2 "register_operand"))) + (set (match_operand:IVEC 0 "register_operand") + (rotatert:IVEC (match_operand:IVEC 1 "register_operand") + (match_dup 3)))] + "" + { + operands[3] = gen_reg_rtx (<MODE>mode); + }); + +;; Expand left rotate with a scalar amount to right rotate: negate the +;; scalar before broadcasting it because scalar negation is cheaper than +;; vector negation. +(define_expand "rotl<mode>3" + [(set (match_dup 3) + (neg:SI (match_operand:SI 2 "register_operand"))) + (set (match_dup 4) + (vec_duplicate:IVEC (subreg:<IVEC:UNITMODE> (match_dup 3) 0))) + (set (match_operand:IVEC 0 "register_operand") + (rotatert:IVEC (match_operand:IVEC 1 "register_operand") + (match_dup 4)))] + "" + { + operands[3] = gen_reg_rtx (SImode); + operands[4] = gen_reg_rtx (<MODE>mode); + }); + ;; <x>vrotri.{b/h/w/d} (define_insn "rotr<mode>3" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c new file mode 100644 index 00000000000..84cc53cecaf --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-rotr.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "rotr\\.w" } } */ + +unsigned +t (unsigned a, unsigned b) +{ + return a << b | a >> (32 - b); +} diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c new file mode 100644 index 00000000000..14298bf9ee4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-b.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.b" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.b" 1 } } */ + +#define TYPE char +#include "rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c new file mode 100644 index 00000000000..0e971b3235c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-d.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.d" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.d" 1 } } */ + +#define TYPE long long +#include "rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c new file mode 100644 index 00000000000..93216ebc245 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-h.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.h" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.h" 1 } } */ + +#define TYPE short +#include "rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c new file mode 100644 index 00000000000..d05b86f4716 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-vrotr-w.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.w" 1 } } */ + +#ifndef VLEN +#define VLEN 16 +#endif + +#ifndef TYPE +#define TYPE int +#endif + +typedef unsigned TYPE V __attribute__ ((vector_size (VLEN))); +V a, b, c; + +void +test (int x) +{ + b = a << x | a >> ((int)sizeof (TYPE) * __CHAR_BIT__ - x); +} + +void +test2 (void) +{ + for (int i = 0; i < VLEN / sizeof (TYPE); i++) + c[i] = a[i] << b[i] | a[i] >> ((int)sizeof (TYPE) * __CHAR_BIT__ - b[i]); +} diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c new file mode 100644 index 00000000000..2674b1b618c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-b.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.b" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.b" 1 } } */ + +#define VLEN 32 +#include "rotl-with-vrotr-b.c" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c new file mode 100644 index 00000000000..e9440331594 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-d.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.d" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.d" 1 } } */ + +#define VLEN 32 +#include "rotl-with-vrotr-d.c" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c new file mode 100644 index 00000000000..3d998941f92 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-h.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.h" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.h" 1 } } */ + +#define VLEN 32 +#include "rotl-with-vrotr-h.c" diff --git a/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c new file mode 100644 index 00000000000..ca6aa7bae6c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/rotl-with-xvrotr-w.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.w" 1 } } */ + +#define VLEN 32 +#include "rotl-with-vrotr-w.c"