Commit d9c8bdcd authored by Lu Yahan's avatar Lu Yahan Committed by Yahan Lu

[riscv64] Add check_fn before calculating the expected value

Change-Id: I4b83907b735994a729b57b9c4a75d3672ce78b15
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3482916Reviewed-by: 's avatarji qiu <qiuji@iscas.ac.cn>
Auto-Submit: Yahan Lu <yahan@iscas.ac.cn>
Reviewed-by: 's avatarYahan Lu <yahan@iscas.ac.cn>
Commit-Queue: Yahan Lu <yahan@iscas.ac.cn>
Cr-Commit-Position: refs/heads/main@{#79218}
parent 877dcdfc
......@@ -844,54 +844,54 @@ struct type_sew_t<128> {
RVV_VI_VFP_LOOP_END \
rvv_trace_vd();
#define RVV_VI_VFP_VF_LOOP_WIDEN(BODY32, vs2_is_widen) \
RVV_VI_VFP_LOOP_BASE \
switch (rvv_vsew()) { \
case E16: \
case E64: { \
UNIMPLEMENTED(); \
break; \
} \
case E32: { \
double& vd = Rvvelt<double>(rvv_vd_reg(), i, true); \
float fs1 = (get_fpu_register_float(rs1_reg())); \
float vs2 = vs2_is_widen \
? static_cast<float>(Rvvelt<double>(rvv_vs2_reg(), i)) \
: Rvvelt<float>(rvv_vs2_reg(), i); \
float vs3 = static_cast<float>(Rvvelt<float>(rvv_vd_reg(), i)); \
BODY32; \
break; \
} \
default: \
UNREACHABLE(); \
break; \
} \
RVV_VI_VFP_LOOP_END \
#define RVV_VI_VFP_VF_LOOP_WIDEN(BODY32, vs2_is_widen) \
RVV_VI_VFP_LOOP_BASE \
switch (rvv_vsew()) { \
case E16: \
case E64: { \
UNIMPLEMENTED(); \
break; \
} \
case E32: { \
double& vd = Rvvelt<double>(rvv_vd_reg(), i, true); \
double fs1 = static_cast<double>(get_fpu_register_float(rs1_reg())); \
double vs2 = vs2_is_widen \
? Rvvelt<double>(rvv_vs2_reg(), i) \
: static_cast<double>(Rvvelt<float>(rvv_vs2_reg(), i)); \
double vs3 = static_cast<double>(Rvvelt<float>(rvv_vd_reg(), i)); \
BODY32; \
break; \
} \
default: \
UNREACHABLE(); \
break; \
} \
RVV_VI_VFP_LOOP_END \
rvv_trace_vd();
#define RVV_VI_VFP_VV_LOOP_WIDEN(BODY32, vs2_is_widen) \
RVV_VI_VFP_LOOP_BASE \
switch (rvv_vsew()) { \
case E16: \
case E64: { \
UNIMPLEMENTED(); \
break; \
} \
case E32: { \
double& vd = Rvvelt<double>(rvv_vd_reg(), i, true); \
float vs2 = vs2_is_widen \
? static_cast<float>(Rvvelt<double>(rvv_vs2_reg(), i)) \
: Rvvelt<float>(rvv_vs2_reg(), i); \
float vs1 = Rvvelt<float>(rvv_vs1_reg(), i); \
float vs3 = static_cast<float>(Rvvelt<float>(rvv_vd_reg(), i)); \
BODY32; \
break; \
} \
default: \
require(0); \
break; \
} \
RVV_VI_VFP_LOOP_END \
#define RVV_VI_VFP_VV_LOOP_WIDEN(BODY32, vs2_is_widen) \
RVV_VI_VFP_LOOP_BASE \
switch (rvv_vsew()) { \
case E16: \
case E64: { \
UNIMPLEMENTED(); \
break; \
} \
case E32: { \
double& vd = Rvvelt<double>(rvv_vd_reg(), i, true); \
double vs2 = vs2_is_widen \
? static_cast<double>(Rvvelt<double>(rvv_vs2_reg(), i)) \
: static_cast<double>(Rvvelt<float>(rvv_vs2_reg(), i)); \
double vs1 = static_cast<double>(Rvvelt<float>(rvv_vs1_reg(), i)); \
double vs3 = static_cast<double>(Rvvelt<float>(rvv_vd_reg(), i)); \
BODY32; \
break; \
} \
default: \
require(0); \
break; \
} \
RVV_VI_VFP_LOOP_END \
rvv_trace_vd();
#define RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(type, check_fn, op) \
......@@ -6475,7 +6475,7 @@ void Simulator::DecodeRvvFVV() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VV_LOOP_WIDEN(
{
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(float, is_invalid_fadd, +);
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(double, is_invalid_fadd, +);
USE(vs3);
},
false)
......@@ -6484,7 +6484,7 @@ void Simulator::DecodeRvvFVV() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VV_LOOP_WIDEN(
{
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(float, is_invalid_fsub, -);
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(double, is_invalid_fsub, -);
USE(vs3);
},
false)
......@@ -6493,7 +6493,7 @@ void Simulator::DecodeRvvFVV() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VV_LOOP_WIDEN(
{
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(float, is_invalid_fadd, +);
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(double, is_invalid_fadd, +);
USE(vs3);
},
true)
......@@ -6502,7 +6502,7 @@ void Simulator::DecodeRvvFVV() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VV_LOOP_WIDEN(
{
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(float, is_invalid_fsub, -);
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(double, is_invalid_fsub, -);
USE(vs3);
},
true)
......@@ -6511,7 +6511,7 @@ void Simulator::DecodeRvvFVV() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VV_LOOP_WIDEN(
{
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(float, is_invalid_fmul, *);
RVV_VI_VFP_VV_ARITH_CHECK_COMPUTE(double, is_invalid_fmul, *);
USE(vs3);
},
false)
......@@ -6661,7 +6661,7 @@ void Simulator::DecodeRvvFVF() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VF_LOOP_WIDEN(
{
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(float, is_invalid_fadd, +);
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(double, is_invalid_fadd, +);
USE(vs3);
},
false)
......@@ -6670,7 +6670,7 @@ void Simulator::DecodeRvvFVF() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VF_LOOP_WIDEN(
{
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(float, is_invalid_fsub, -);
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(double, is_invalid_fsub, -);
USE(vs3);
},
false)
......@@ -6679,7 +6679,7 @@ void Simulator::DecodeRvvFVF() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VF_LOOP_WIDEN(
{
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(float, is_invalid_fadd, +);
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(double, is_invalid_fadd, +);
USE(vs3);
},
true)
......@@ -6688,7 +6688,7 @@ void Simulator::DecodeRvvFVF() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VF_LOOP_WIDEN(
{
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(float, is_invalid_fsub, -);
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(double, is_invalid_fsub, -);
USE(vs3);
},
true)
......@@ -6697,7 +6697,7 @@ void Simulator::DecodeRvvFVF() {
RVV_VI_CHECK_DSS(true);
RVV_VI_VFP_VF_LOOP_WIDEN(
{
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(float, is_invalid_fmul, *);
RVV_VI_VFP_VF_ARITH_CHECK_COMPUTE(double, is_invalid_fmul, *);
USE(vs3);
},
false)
......
......@@ -2273,94 +2273,123 @@ UTEST_RVV_VF_VV_FORM_WITH_OP(vfdiv_vv, /)
// Tests for vector widening floating-point arithmetic instructions between
// vector and vector
#define UTEST_RVV_VFW_VV_FORM_WITH_RES(instr_name, expect_res, \
is_first_double) \
TEST(RISCV_UTEST_FLOAT_WIDENING_##instr_name) { \
if (!CpuFeatures::IsSupported(RISCV_SIMD)) return; \
CcTest::InitializeVM(); \
constexpr size_t n = kRvvVLEN / 32; \
double result[n] = {0.0}; \
auto fn = [&result](MacroAssembler& assm) { \
if (is_first_double) { \
__ fcvt_d_s(fa0, fa0); \
__ VU.set(t0, VSew::E64, Vlmul::m2); \
__ vfmv_vf(v2, fa0); \
} \
__ VU.set(t0, VSew::E32, Vlmul::m1); \
if (!is_first_double) { \
__ vfmv_vf(v2, fa0); \
} \
__ vfmv_vf(v4, fa1); \
__ instr_name(v0, v2, v4); \
__ li(t1, Operand(int64_t(result))); \
__ vs(v0, t1, 0, VSew::E64); \
}; \
for (float rs1_fval : compiler::ValueHelper::GetVector<float>()) { \
for (float rs2_fval : compiler::ValueHelper::GetVector<float>()) { \
GenAndRunTest<double, float>(rs1_fval, rs2_fval, fn); \
for (size_t i = 0; i < n; i++) { \
CHECK_DOUBLE_EQ(UseCanonicalNan<double>(expect_res), result[i]); \
result[i] = 0.0; \
} \
} \
} \
#define UTEST_RVV_VFW_VV_FORM_WITH_RES(instr_name, tested_op, is_first_double, \
check_fn) \
TEST(RISCV_UTEST_FLOAT_WIDENING_##instr_name) { \
if (!CpuFeatures::IsSupported(RISCV_SIMD)) return; \
CcTest::InitializeVM(); \
constexpr size_t n = kRvvVLEN / 32; \
double result[n] = {0.0}; \
auto fn = [&result](MacroAssembler& assm) { \
if (is_first_double) { \
__ fcvt_d_s(fa0, fa0); \
__ VU.set(t0, VSew::E64, Vlmul::m2); \
__ vfmv_vf(v2, fa0); \
} \
__ VU.set(t0, VSew::E32, Vlmul::m1); \
if (!is_first_double) { \
__ vfmv_vf(v2, fa0); \
} \
__ vfmv_vf(v4, fa1); \
__ instr_name(v0, v2, v4); \
__ li(t1, Operand(int64_t(result))); \
__ vs(v0, t1, 0, VSew::E64); \
}; \
for (float rs1_fval : compiler::ValueHelper::GetVector<float>()) { \
for (float rs2_fval : compiler::ValueHelper::GetVector<float>()) { \
GenAndRunTest<double, float>(rs1_fval, rs2_fval, fn); \
for (size_t i = 0; i < n; i++) { \
CHECK_DOUBLE_EQ( \
check_fn(rs1_fval, rs2_fval) \
? std::numeric_limits<double>::quiet_NaN() \
: UseCanonicalNan<double>(static_cast<double>( \
rs1_fval) tested_op static_cast<double>(rs2_fval)), \
result[i]); \
result[i] = 0.0; \
} \
} \
} \
}
// Tests for vector widening floating-point arithmetic instructions between
// vector and scalar
#define UTEST_RVV_VFW_VF_FORM_WITH_RES(instr_name, expect_res, \
is_first_double) \
TEST(RISCV_UTEST_FLOAT_WIDENING_##instr_name) { \
if (!CpuFeatures::IsSupported(RISCV_SIMD)) return; \
CcTest::InitializeVM(); \
constexpr size_t n = kRvvVLEN / 32; \
double result[n] = {0.0}; \
auto fn = [&result](MacroAssembler& assm) { \
__ VU.set(t0, VSew::E32, Vlmul::m1); \
if (is_first_double) { \
__ fcvt_d_s(fa0, fa0); \
__ VU.set(t0, VSew::E64, Vlmul::m2); \
__ vfmv_vf(v2, fa0); \
} \
__ VU.set(t0, VSew::E32, Vlmul::m1); \
if (!is_first_double) { \
__ vfmv_vf(v2, fa0); \
} \
__ instr_name(v0, v2, fa1); \
__ li(t1, Operand(int64_t(result))); \
__ li(t2, Operand(int64_t(&result[n / 2]))); \
__ vs(v0, t1, 0, VSew::E64); \
__ vs(v1, t2, 0, VSew::E64); \
}; \
for (float rs1_fval : compiler::ValueHelper::GetVector<float>()) { \
for (float rs2_fval : compiler::ValueHelper::GetVector<float>()) { \
GenAndRunTest<double, float>(rs1_fval, rs2_fval, fn); \
for (size_t i = 0; i < n; i++) { \
CHECK_DOUBLE_EQ(UseCanonicalNan<double>(expect_res), result[i]); \
result[i] = 0.0; \
} \
} \
} \
}
#define UTEST_RVV_VFW_VF_FORM_WITH_RES(instr_name, tested_op, is_first_double, \
check_fn) \
TEST(RISCV_UTEST_FLOAT_WIDENING_##instr_name) { \
if (!CpuFeatures::IsSupported(RISCV_SIMD)) return; \
CcTest::InitializeVM(); \
constexpr size_t n = kRvvVLEN / 32; \
double result[n] = {0.0}; \
auto fn = [&result](MacroAssembler& assm) { \
__ VU.set(t0, VSew::E32, Vlmul::m1); \
if (is_first_double) { \
__ fcvt_d_s(fa0, fa0); \
__ VU.set(t0, VSew::E64, Vlmul::m2); \
__ vfmv_vf(v2, fa0); \
} \
__ VU.set(t0, VSew::E32, Vlmul::m1); \
if (!is_first_double) { \
__ vfmv_vf(v2, fa0); \
} \
__ instr_name(v0, v2, fa1); \
__ li(t1, Operand(int64_t(result))); \
__ li(t2, Operand(int64_t(&result[n / 2]))); \
__ vs(v0, t1, 0, VSew::E64); \
__ vs(v1, t2, 0, VSew::E64); \
}; \
for (float rs1_fval : compiler::ValueHelper::GetVector<float>()) { \
for (float rs2_fval : compiler::ValueHelper::GetVector<float>()) { \
GenAndRunTest<double, float>(rs1_fval, rs2_fval, fn); \
for (size_t i = 0; i < n; i++) { \
CHECK_DOUBLE_EQ( \
check_fn(rs1_fval, rs2_fval) \
? std::numeric_limits<double>::quiet_NaN() \
: UseCanonicalNan<double>(static_cast<double>( \
rs1_fval) tested_op static_cast<double>(rs2_fval)), \
result[i]); \
result[i] = 0.0; \
} \
} \
} \
}
#define UTEST_RVV_VFW_VV_FORM_WITH_OP(instr_name, tested_op, is_first_double, \
check_fn) \
UTEST_RVV_VFW_VV_FORM_WITH_RES(instr_name, tested_op, is_first_double, \
check_fn)
#define UTEST_RVV_VFW_VF_FORM_WITH_OP(instr_name, tested_op, is_first_double, \
check_fn) \
UTEST_RVV_VFW_VF_FORM_WITH_RES(instr_name, tested_op, is_first_double, \
check_fn)
template <typename T>
static inline bool is_invalid_fmul(T src1, T src2) {
return (isinf(src1) && src2 == static_cast<T>(0.0)) ||
(src1 == static_cast<T>(0.0) && isinf(src2));
}
template <typename T>
static inline bool is_invalid_fadd(T src1, T src2) {
return (isinf(src1) && isinf(src2) &&
std::signbit(src1) != std::signbit(src2));
}
template <typename T>
static inline bool is_invalid_fsub(T src1, T src2) {
return (isinf(src1) && isinf(src2) &&
std::signbit(src1) == std::signbit(src2));
}
#define UTEST_RVV_VFW_VV_FORM_WITH_OP(instr_name, tested_op, is_first_double) \
UTEST_RVV_VFW_VV_FORM_WITH_RES(instr_name, ((rs1_fval)tested_op(rs2_fval)), \
is_first_double)
#define UTEST_RVV_VFW_VF_FORM_WITH_OP(instr_name, tested_op, is_first_double) \
UTEST_RVV_VFW_VF_FORM_WITH_RES(instr_name, ((rs1_fval)tested_op(rs2_fval)), \
is_first_double)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwadd_vv, +, false)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwadd_vf, +, false)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwsub_vv, -, false)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwsub_vf, -, false)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwadd_wv, +, true)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwadd_wf, +, true)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwsub_wv, -, true)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwsub_wf, -, true)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwmul_vv, *, false)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwmul_vf, *, false)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwadd_vv, +, false, is_invalid_fadd)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwadd_vf, +, false, is_invalid_fadd)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwsub_vv, -, false, is_invalid_fsub)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwsub_vf, -, false, is_invalid_fsub)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwadd_wv, +, true, is_invalid_fadd)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwadd_wf, +, true, is_invalid_fadd)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwsub_wv, -, true, is_invalid_fsub)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwsub_wf, -, true, is_invalid_fsub)
UTEST_RVV_VFW_VV_FORM_WITH_OP(vfwmul_vv, *, false, is_invalid_fmul)
UTEST_RVV_VFW_VF_FORM_WITH_OP(vfwmul_vf, *, false, is_invalid_fmul)
#undef UTEST_RVV_VF_VV_FORM_WITH_OP
#undef UTEST_RVV_VF_VF_FORM_WITH_OP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment