[Bug target/115458] [15 regression] [RISC-V] ICE in lra_split_hard_reg_for, at lra-assigns.cc:1868 unable to find a register to spill since r15-518-g99b1daae18c095
law at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jan 24 14:39:06 GMT 2025
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()); }
More information about the Gcc-bugs
mailing list