Committed, thanks!
On Wed, Apr 19, 2023 at 6:42 PM <juzhe.zh...@rivai.ai> wrote: > > From: Ju-Zhe Zhong <juzhe.zh...@rivai.ai> > > Testcase coming from Kito. > > Co-authored-by: kito-cheng <kito.ch...@sifive.com> > Co-authored-by: kito-cheng <kito.ch...@gmail.com> > > PR 109535 > > gcc/ChangeLog: > > * config/riscv/riscv-vsetvl.cc (count_regno_occurrences): New > function. > (pass_vsetvl::cleanup_insns): Fix bug. > > gcc/testsuite/ChangeLog: > > * g++.target/riscv/rvv/base/pr109535.C: New test. > * gcc.target/riscv/rvv/base/pr109535.c: New test. > > Signed-off-by: Ju-Zhe Zhong <juzhe.zh...@rivai.ai> > Co-authored-by: kito-cheng <kito.ch...@sifive.com> > Co-authored-by: kito-cheng <kito.ch...@gmail.com> > > --- > gcc/config/riscv/riscv-vsetvl.cc | 14 +- > .../g++.target/riscv/rvv/base/pr109535.C | 144 ++++++++++++++++++ > .../gcc.target/riscv/rvv/base/pr109535.c | 11 ++ > 3 files changed, 168 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/pr109535.C > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr109535.c > > diff --git a/gcc/config/riscv/riscv-vsetvl.cc > b/gcc/config/riscv/riscv-vsetvl.cc > index 1b66e3b9eeb..9c356ce5157 100644 > --- a/gcc/config/riscv/riscv-vsetvl.cc > +++ b/gcc/config/riscv/riscv-vsetvl.cc > @@ -1592,6 +1592,18 @@ backward_propagate_worthwhile_p (const basic_block > cfg_bb, > return true; > } > > +/* Count the number of REGNO in RINSN. */ > +static int > +count_regno_occurrences (rtx_insn *rinsn, unsigned int regno) > +{ > + int count = 0; > + extract_insn (rinsn); > + for (int i = 0; i < recog_data.n_operands; i++) > + if (refers_to_regno_p (regno, recog_data.operand[i])) > + count++; > + return count; > +} > + > avl_info::avl_info (const avl_info &other) > { > m_value = other.get_value (); > @@ -3924,7 +3936,7 @@ pass_vsetvl::cleanup_insns (void) const > if (!has_vl_op (rinsn) || !REG_P (get_vl (rinsn))) > continue; > rtx avl = get_vl (rinsn); > - if (count_occurrences (PATTERN (rinsn), avl, 0) == 1) > + if (count_regno_occurrences (rinsn, REGNO (avl)) == 1) > { > /* Get the list of uses for the new instruction. */ > auto attempt = crtl->ssa->new_change_attempt (); > diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/pr109535.C > b/gcc/testsuite/g++.target/riscv/rvv/base/pr109535.C > new file mode 100644 > index 00000000000..7013cfcf4ee > --- /dev/null > +++ b/gcc/testsuite/g++.target/riscv/rvv/base/pr109535.C > @@ -0,0 +1,144 @@ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */ > + > +typedef long size_t; > +typedef signed char int8_t; > +typedef char uint8_t > + > +; > +template < typename > struct Relations{ using Unsigned = uint8_t; }; > +template < typename T > using MakeUnsigned = typename Relations< T > >::Unsigned; > +#pragma riscv intrinsic "vector" > +size_t ScaleByPower() { return 0;} > +template < typename Lane, size_t , int > struct Simd { > +using T = Lane; > + > +template < typename NewT > using Rebind = Simd< NewT, 1, 0 >; > +}; > +template < typename T > struct ClampNAndPow2 { > +using type = Simd< T, 65536, 0 > > +; > +}; > +struct CappedTagChecker { > +using type = ClampNAndPow2< signed char >::type; > +}; > +template < typename , size_t , int > > +using CappedTag = CappedTagChecker::type; > +template < class D > using TFromD = typename D::T; > +template < class T, class D > using Rebind = typename D::Rebind< T >; > +template < class D > > +using RebindToUnsigned = Rebind< MakeUnsigned< D >, D >; > +template < size_t N > > +size_t > +Lanes(Simd< uint8_t, N, 0 > ) { > +size_t kFull = 0; > +size_t kCap ; > +size_t actual = > + __riscv_vsetvl_e8m1(kCap); > +return actual; > +} > +template < size_t N > > +size_t > +Lanes(Simd< int8_t, N, 0 > ) { > +size_t kFull ; > +size_t kCap ; > +size_t actual = > + __riscv_vsetvl_e8m1(kCap); > +return actual; > +} > +template < size_t N > > +vuint8m1_t > +Set(Simd< uint8_t, N, 0 > d, uint8_t arg) { > +size_t __trans_tmp_1 = Lanes(d); > +return __riscv_vmv_v_x_u8m1(arg, __trans_tmp_1); > +} > +template < size_t N > > +vint8m1_t Set(Simd< int8_t, N, 0 > , int8_t ); > +template < class D > using VFromD = decltype(Set(D(), TFromD< D >())); > +template < class D > > +VFromD< D > > +Zero(D ) > +; > + > +template < size_t N > > +vint8m1_t > +BitCastFromByte(Simd< int8_t, N, 0 >, vuint8m1_t v) { > +return __riscv_vreinterpret_v_u8m1_i8m1(v); > +} > +template < class D, class FromV > > +VFromD< D > > +BitCast(D d, FromV v) { > +return BitCastFromByte(d, v) > + > +; > +} > +template < size_t N > > +void > +Store(vint8m1_t v, Simd< int8_t, N, 0 > d) { > +int8_t *p ; > +__riscv_vse8_v_i8m1(p, v, Lanes(d)); > +} > +template < class V, class D > > +void > +StoreU(V v, D d) { > +Store(v, d) > +; > +} > +template < class D > using Vec = decltype(Zero(D())); > +size_t Generate_count; > +template < class D, class Func> > +void Generate(D d, Func func) { > +RebindToUnsigned< D > du > +; > +size_t N = Lanes(d); > +Vec< decltype(du) > vidx ; > +for (; ; ) { > + StoreU(func(d, vidx), d); > + vidx = (Set(du, N)); > +} > +} > +template < typename T, int , int kMinArg, class Test, int kPow2 > > +struct ForeachCappedR { > +static void Do(size_t , size_t ) { > + CappedTag< T, kMinArg, kPow2 > d; > + Test()(T(), d); > +} > +}; > +template < class > struct ForeachCountAndMisalign; > +struct TestGenerate; > +template < int kPow2 = 1 > class ForExtendableVectors { > +public: > + > +template < typename T > void operator()(T) { > + size_t max_lanes ; > + ForeachCappedR< T, 0, size_t{} , > + ForeachCountAndMisalign< int >, kPow2 >::Do(1, max_lanes); > +} > +}; > +class ForPartialVectors { > +public: > +template < typename T > void operator()(T t) { > + ForExtendableVectors()(t); > +} > +}; > +void ForSignedTypes(ForPartialVectors func) { func(int8_t()); } > +template < class > struct ForeachCountAndMisalign { > +template < typename T, class D > > +void operator()(T, D d) { > + int rng > + ; > + size_t misalignments[1] ; > + for ( size_t ma : misalignments) > + for (size_t mb : misalignments) > + TestGenerate()(d, 0, ma, mb, rng); > +} > +}; > +struct TestGenerate { > +template < class D > > +void operator()(D d, size_t , size_t , size_t, int ) { > + auto gen2 = [](auto d, auto vidx) { > + return BitCast(d, (vidx)); > + }; > + Generate(d, gen2); > +} > +}; > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr109535.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/pr109535.c > new file mode 100644 > index 00000000000..7582fe9c392 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr109535.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -march=rv32gcv -mabi=ilp32d" } */ > + > +#include "riscv_vector.h" > + > +void foo(void *in1, void *in2, void *in3, void *out, size_t vl) { > + vint8m1_t a = __riscv_vle8_v_i8m1(in1, vl); > + vint8m1_t b = __riscv_vadd_vx_i8m1 (a, vl, vl); > + __riscv_vse8_v_i8m1(out, b, vl); > +} > + > -- > 2.36.3 >