https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115458

--- Comment #6 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Heavily reduced testcase.  -O2 -fpermissive -fno-exceptions -std=c++17
-march=rv64gcv -mabi=lp64d


typedef char int8_t;
typedef unsigned char uint8_t;
template <typename> using MakeUnsigned = unsigned char;
#pragma riscv intrinsic "vector"
template <typename, long> struct Simd {
  using T = int;
  template <typename NewT> using Rebind = Simd<NewT, 0>;
};
template <typename T> struct ClampNAndPow2 {
  using type = Simd<T, 1>;
};
template <typename T> struct ScalableTagChecker {
  using type = typename ClampNAndPow2<T>::type;
};
template <typename T> struct CappedTagChecker {
  using type = typename ClampNAndPow2<T>::type;
};
template <typename T, int>
using ScalableTag = typename ScalableTagChecker<T>::type;
template <typename T, long, int>
using CappedTag = typename CappedTagChecker<T>::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 <class> struct DFromV_t;
template <class V> using DFromV = typename DFromV_t<V>::type;
template <> struct DFromV_t<vint8m8_t> {
  using Lane = int8_t;
  using type = ScalableTag<Lane, 3>;
};
template <long N> void Lanes(Simd<int8_t, N>);
template <long N> vuint8m8_t Set(Simd<uint8_t, N>, uint8_t arg) {
  return __riscv_vmv_v_x_u8m8(arg, 0);
}
template <long N> vint8m8_t Set(Simd<int8_t, N>, int8_t);
template <class D> using VFromD = decltype(Set(D(), TFromD<D>()));
template <class D> VFromD<D> Zero(D d) {
  RebindToUnsigned<decltype(d)> du;
  return BitCast(d, Set(du, 0));
}
template <long N> vint8m8_t BitCastFromByte(Simd<int8_t, N>, vuint8m8_t v) {
  return __riscv_vreinterpret_v_u8m8_i8m8(v);
}
template <class D, class FromV> VFromD<D> BitCast(D d, FromV v) {
  return BitCastFromByte(d, v);
}
vint8m8_t MaskedSubOr(vint8m8_t no, vbool1_t m, vint8m8_t a, vint8m8_t b) {
  return __riscv_vsub_vv_i8m8_mu(m, no, a, b, 0);
}
vbool1_t Lt(vint8m8_t a, vint8m8_t b) {
  return __riscv_vmslt_vv_i8m8_b1(a, b, 0);
}
template <class D, class V> V InterleaveUpper(D, V, V);
template <class D> using Vec = decltype(Zero(D()));
template <class V> V IfNegativeThenNegOrUndefIfZero(V mask, V v) {
  auto zero = Zero(DFromV<V>());
  return MaskedSubOr(v, Lt(mask, zero), zero, v);
}
template <class D> Vec<D> PositiveIota(D);
template <class D> void AssertVecEqual(D, Vec<D>, Vec<D>);
template <typename T, int kMul, class Test, int kPow2> struct ForeachCappedR {
  static Do(long, long) {
    CappedTag<T, kMul, kPow2> d;
    Test()(T(), d);
  }
};
template <class D>
TestMoreThan1LaneIfNegativeThenNegOrUndefIfZero(D d, Vec<D> v2) {
  Vec<D> v1, v4;
  Lanes(d);
  Vec<D> v8 = InterleaveUpper(d, v2, v1);
  AssertVecEqual(d, v8, IfNegativeThenNegOrUndefIfZero(v4, v8));
  Vec<D> zero(IfNegativeThenNegOrUndefIfZero(v4, zero));
  AssertVecEqual(d, zero, IfNegativeThenNegOrUndefIfZero(v8, zero));
}
struct TestIfNegativeThenNegOrUndefIfZero {
  template <typename T, class D> operator()(T, D d) {
    auto v1 = PositiveIota(d), v2(v1), zero = Zero(d), vmin = Set(d, 0),
         vmax(IfNegativeThenNegOrUndefIfZero(vmin, v1));
    AssertVecEqual(d, zero, zero);
    AssertVecEqual(d, v2, IfNegativeThenNegOrUndefIfZero(vmax, v2));
    TestMoreThan1LaneIfNegativeThenNegOrUndefIfZero(d, v2);
  }
};
template <int kPow2> struct ForExtendableVectors {
  template <typename T> operator()(T) {
    constexpr kMaxCapped(sizeof(T));
    long max_lanes;
    constexpr long kMul = kMaxCapped;
    ForeachCappedR<T, kMul, TestIfNegativeThenNegOrUndefIfZero, kPow2>::Do(
        1, max_lanes);
  }
};
struct {
  operator()(char t) { ForExtendableVectors<0>()(t); }
} ForSignedTypes_func;
ForSignedTypes() { ForSignedTypes_func(int8_t()); }

Reply via email to