tint: make const eval of binary ops on concrete values fail on NaN/Inf
With this CL, binary ops add, subtract, multiply, and divide of concrete values will now produce an error if the result is inf/NaN, as it was doing with abstract values. This also affects the cross builtin, which is written in terms of subtract and multiply. Bug: tint:1581 Bug: tint:1747 Change-Id: Ib1d0d8deddc82c67ab53729a6011937636fcc1a5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/110163 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
e956a04daf
commit
0da91e06c5
|
@ -375,7 +375,7 @@ TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, TwoParams_Vector_f32) {
|
||||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Scalar_f32) {
|
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Scalar_f32) {
|
||||||
auto param = GetParam();
|
auto param = GetParam();
|
||||||
|
|
||||||
auto* call = Call(param.name, 1_f, 1_f, 1_f);
|
auto* call = Call(param.name, 0_f, 1_f, 2_f);
|
||||||
WrapInFunction(call);
|
WrapInFunction(call);
|
||||||
|
|
||||||
if (param.args_number == 3u) {
|
if (param.args_number == 3u) {
|
||||||
|
@ -396,8 +396,8 @@ TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Scalar_f32) {
|
||||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Vector_f32) {
|
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Vector_f32) {
|
||||||
auto param = GetParam();
|
auto param = GetParam();
|
||||||
|
|
||||||
auto* call = Call(param.name, vec3<f32>(1_f, 1_f, 3_f), vec3<f32>(1_f, 1_f, 3_f),
|
auto* call = Call(param.name, vec3<f32>(0_f, 0_f, 0_f), vec3<f32>(1_f, 1_f, 1_f),
|
||||||
vec3<f32>(1_f, 1_f, 3_f));
|
vec3<f32>(2_f, 2_f, 2_f));
|
||||||
WrapInFunction(call);
|
WrapInFunction(call);
|
||||||
|
|
||||||
if (param.args_number == 3u) {
|
if (param.args_number == 3u) {
|
||||||
|
@ -577,7 +577,7 @@ TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Scalar_f16) {
|
||||||
|
|
||||||
Enable(ast::Extension::kF16);
|
Enable(ast::Extension::kF16);
|
||||||
|
|
||||||
auto* call = Call(param.name, 1_h, 1_h, 1_h);
|
auto* call = Call(param.name, 0_h, 1_h, 2_h);
|
||||||
WrapInFunction(call);
|
WrapInFunction(call);
|
||||||
|
|
||||||
if (param.args_number == 3u) {
|
if (param.args_number == 3u) {
|
||||||
|
@ -600,8 +600,8 @@ TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Vector_f16) {
|
||||||
|
|
||||||
Enable(ast::Extension::kF16);
|
Enable(ast::Extension::kF16);
|
||||||
|
|
||||||
auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h),
|
auto* call = Call(param.name, vec3<f16>(0_h, 0_h, 0_h), vec3<f16>(1_h, 1_h, 1_h),
|
||||||
vec3<f16>(1_h, 1_h, 3_h));
|
vec3<f16>(2_h, 2_h, 2_h));
|
||||||
WrapInFunction(call);
|
WrapInFunction(call);
|
||||||
|
|
||||||
if (param.args_number == 3u) {
|
if (param.args_number == 3u) {
|
||||||
|
|
|
@ -1099,7 +1099,7 @@ TEST_P(FloatAllMatching, Scalar) {
|
||||||
|
|
||||||
utils::Vector<const ast::Expression*, 8> params;
|
utils::Vector<const ast::Expression*, 8> params;
|
||||||
for (uint32_t i = 0; i < num_params; ++i) {
|
for (uint32_t i = 0; i < num_params; ++i) {
|
||||||
params.Push(Expr(1_f));
|
params.Push(Expr(f32(i)));
|
||||||
}
|
}
|
||||||
auto* builtin = Call(name, params);
|
auto* builtin = Call(name, params);
|
||||||
Func("func", utils::Empty, ty.void_(),
|
Func("func", utils::Empty, ty.void_(),
|
||||||
|
@ -1120,7 +1120,7 @@ TEST_P(FloatAllMatching, Vec2) {
|
||||||
|
|
||||||
utils::Vector<const ast::Expression*, 8> params;
|
utils::Vector<const ast::Expression*, 8> params;
|
||||||
for (uint32_t i = 0; i < num_params; ++i) {
|
for (uint32_t i = 0; i < num_params; ++i) {
|
||||||
params.Push(vec2<f32>(1_f, 1_f));
|
params.Push(vec2<f32>(f32(i), f32(i)));
|
||||||
}
|
}
|
||||||
auto* builtin = Call(name, params);
|
auto* builtin = Call(name, params);
|
||||||
Func("func", utils::Empty, ty.void_(),
|
Func("func", utils::Empty, ty.void_(),
|
||||||
|
@ -1141,7 +1141,7 @@ TEST_P(FloatAllMatching, Vec3) {
|
||||||
|
|
||||||
utils::Vector<const ast::Expression*, 8> params;
|
utils::Vector<const ast::Expression*, 8> params;
|
||||||
for (uint32_t i = 0; i < num_params; ++i) {
|
for (uint32_t i = 0; i < num_params; ++i) {
|
||||||
params.Push(vec3<f32>(1_f, 1_f, 1_f));
|
params.Push(vec3<f32>(f32(i), f32(i), f32(i)));
|
||||||
}
|
}
|
||||||
auto* builtin = Call(name, params);
|
auto* builtin = Call(name, params);
|
||||||
Func("func", utils::Empty, ty.void_(),
|
Func("func", utils::Empty, ty.void_(),
|
||||||
|
@ -1162,7 +1162,7 @@ TEST_P(FloatAllMatching, Vec4) {
|
||||||
|
|
||||||
utils::Vector<const ast::Expression*, 8> params;
|
utils::Vector<const ast::Expression*, 8> params;
|
||||||
for (uint32_t i = 0; i < num_params; ++i) {
|
for (uint32_t i = 0; i < num_params; ++i) {
|
||||||
params.Push(vec4<f32>(1_f, 1_f, 1_f, 1_f));
|
params.Push(vec4<f32>(f32(i), f32(i), f32(i), f32(i)));
|
||||||
}
|
}
|
||||||
auto* builtin = Call(name, params);
|
auto* builtin = Call(name, params);
|
||||||
Func("func", utils::Empty, ty.void_(),
|
Func("func", utils::Empty, ty.void_(),
|
||||||
|
|
|
@ -655,8 +655,7 @@ ConstEval::ConstEval(ProgramBuilder& b) : builder(b) {}
|
||||||
template <typename NumberT>
|
template <typename NumberT>
|
||||||
utils::Result<NumberT> ConstEval::Add(NumberT a, NumberT b) {
|
utils::Result<NumberT> ConstEval::Add(NumberT a, NumberT b) {
|
||||||
NumberT result;
|
NumberT result;
|
||||||
if constexpr (IsAbstract<NumberT>) {
|
if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
|
||||||
// Check for over/underflow for abstract values
|
|
||||||
if (auto r = CheckedAdd(a, b)) {
|
if (auto r = CheckedAdd(a, b)) {
|
||||||
result = r->value;
|
result = r->value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -682,8 +681,7 @@ utils::Result<NumberT> ConstEval::Add(NumberT a, NumberT b) {
|
||||||
template <typename NumberT>
|
template <typename NumberT>
|
||||||
utils::Result<NumberT> ConstEval::Sub(NumberT a, NumberT b) {
|
utils::Result<NumberT> ConstEval::Sub(NumberT a, NumberT b) {
|
||||||
NumberT result;
|
NumberT result;
|
||||||
if constexpr (IsAbstract<NumberT>) {
|
if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
|
||||||
// Check for over/underflow for abstract values
|
|
||||||
if (auto r = CheckedSub(a, b)) {
|
if (auto r = CheckedSub(a, b)) {
|
||||||
result = r->value;
|
result = r->value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -710,7 +708,7 @@ template <typename NumberT>
|
||||||
utils::Result<NumberT> ConstEval::Mul(NumberT a, NumberT b) {
|
utils::Result<NumberT> ConstEval::Mul(NumberT a, NumberT b) {
|
||||||
using T = UnwrapNumber<NumberT>;
|
using T = UnwrapNumber<NumberT>;
|
||||||
NumberT result;
|
NumberT result;
|
||||||
if constexpr (IsAbstract<NumberT>) {
|
if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
|
||||||
// Check for over/underflow for abstract values
|
// Check for over/underflow for abstract values
|
||||||
if (auto r = CheckedMul(a, b)) {
|
if (auto r = CheckedMul(a, b)) {
|
||||||
result = r->value;
|
result = r->value;
|
||||||
|
@ -736,7 +734,7 @@ utils::Result<NumberT> ConstEval::Mul(NumberT a, NumberT b) {
|
||||||
template <typename NumberT>
|
template <typename NumberT>
|
||||||
utils::Result<NumberT> ConstEval::Div(NumberT a, NumberT b) {
|
utils::Result<NumberT> ConstEval::Div(NumberT a, NumberT b) {
|
||||||
NumberT result;
|
NumberT result;
|
||||||
if constexpr (IsAbstract<NumberT>) {
|
if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
|
||||||
// Check for over/underflow for abstract values
|
// Check for over/underflow for abstract values
|
||||||
if (auto r = CheckedDiv(a, b)) {
|
if (auto r = CheckedDiv(a, b)) {
|
||||||
result = r->value;
|
result = r->value;
|
||||||
|
@ -1922,8 +1920,6 @@ ConstEval::Result ConstEval::cross(const sem::Type* ty,
|
||||||
auto* v1 = v->Index(1);
|
auto* v1 = v->Index(1);
|
||||||
auto* v2 = v->Index(2);
|
auto* v2 = v->Index(2);
|
||||||
|
|
||||||
// auto x = Dispatch_fa_f32_f16(ab_minus_cd_func(elem_ty), u->Index(1), v->Index(2),
|
|
||||||
// v->Index(1), u->Index(2));
|
|
||||||
auto x = Dispatch_fa_f32_f16(Det2Func(elem_ty), u1, u2, v1, v2);
|
auto x = Dispatch_fa_f32_f16(Det2Func(elem_ty), u1, u2, v1, v2);
|
||||||
if (!x) {
|
if (!x) {
|
||||||
return utils::Failure;
|
return utils::Failure;
|
||||||
|
|
|
@ -144,46 +144,41 @@ std::vector<Case> OpAddIntCases() {
|
||||||
C(T::Highest(), Negate(T{1}), T{T::Highest() - 1}),
|
C(T::Highest(), Negate(T{1}), T{T::Highest() - 1}),
|
||||||
C(T::Lowest(), T::Highest(), Negate(T{1})),
|
C(T::Lowest(), T::Highest(), Negate(T{1})),
|
||||||
};
|
};
|
||||||
ConcatIntoIf<!IsAbstract<T>>( //
|
if constexpr (IsAbstract<T>) {
|
||||||
r, std::vector<Case>{
|
|
||||||
C(T::Highest(), T{1}, T::Lowest()),
|
|
||||||
C(T::Lowest(), Negate(T{1}), T::Highest()),
|
|
||||||
});
|
|
||||||
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
auto error_msg = [](auto a, auto b) {
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "+", b);
|
return "12:34 error: " + OverflowErrorMessage(a, "+", b);
|
||||||
};
|
};
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
ConcatInto( //
|
||||||
r, std::vector<Case>{
|
r, std::vector<Case>{
|
||||||
E(T::Highest(), T{1}, error_msg(T::Highest(), T{1})),
|
E(T::Highest(), T{1}, error_msg(T::Highest(), T{1})),
|
||||||
E(T::Lowest(), Negate(T{1}), error_msg(T::Lowest(), Negate(T{1}))),
|
E(T::Lowest(), Negate(T{1}), error_msg(T::Lowest(), Negate(T{1}))),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
ConcatInto( //
|
||||||
|
r, std::vector<Case>{
|
||||||
|
C(T::Highest(), T{1}, T::Lowest()),
|
||||||
|
C(T::Lowest(), Negate(T{1}), T::Highest()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<Case> OpAddFloatCases() {
|
std::vector<Case> OpAddFloatCases() {
|
||||||
static_assert(IsFloatingPoint<T>);
|
static_assert(IsFloatingPoint<T>);
|
||||||
auto r = std::vector<Case>{
|
auto error_msg = [](auto a, auto b) {
|
||||||
|
return "12:34 error: " + OverflowErrorMessage(a, "+", b);
|
||||||
|
};
|
||||||
|
return std::vector<Case>{
|
||||||
C(T{0}, T{0}, T{0}),
|
C(T{0}, T{0}, T{0}),
|
||||||
C(T{1}, T{2}, T{3}),
|
C(T{1}, T{2}, T{3}),
|
||||||
C(T::Lowest(), T{1}, T{T::Lowest() + 1}),
|
C(T::Lowest(), T{1}, T{T::Lowest() + 1}),
|
||||||
C(T::Highest(), Negate(T{1}), T{T::Highest() - 1}),
|
C(T::Highest(), Negate(T{1}), T{T::Highest() - 1}),
|
||||||
C(T::Lowest(), T::Highest(), T{0}),
|
C(T::Lowest(), T::Highest(), T{0}),
|
||||||
};
|
|
||||||
ConcatIntoIf<!IsAbstract<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
C(T::Highest(), T::Highest(), T::Inf()),
|
|
||||||
C(T::Lowest(), Negate(T::Highest()), -T::Inf()),
|
|
||||||
});
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "+", b);
|
|
||||||
};
|
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
E(T::Highest(), T::Highest(), error_msg(T::Highest(), T::Highest())),
|
E(T::Highest(), T::Highest(), error_msg(T::Highest(), T::Highest())),
|
||||||
E(T::Lowest(), Negate(T::Highest()), error_msg(T::Lowest(), Negate(T::Highest()))),
|
E(T::Lowest(), Negate(T::Highest()), error_msg(T::Lowest(), Negate(T::Highest()))),
|
||||||
});
|
};
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(Add,
|
INSTANTIATE_TEST_SUITE_P(Add,
|
||||||
ResolverConstEvalBinaryOpTest,
|
ResolverConstEvalBinaryOpTest,
|
||||||
|
@ -206,45 +201,40 @@ std::vector<Case> OpSubIntCases() {
|
||||||
C(T{T::Highest() - 1}, Negate(T{1}), T::Highest()),
|
C(T{T::Highest() - 1}, Negate(T{1}), T::Highest()),
|
||||||
C(Negate(T{1}), T::Highest(), T::Lowest()),
|
C(Negate(T{1}), T::Highest(), T::Lowest()),
|
||||||
};
|
};
|
||||||
ConcatIntoIf<!IsAbstract<T>>( //
|
if constexpr (IsAbstract<T>) {
|
||||||
r, std::vector<Case>{
|
|
||||||
C(T::Lowest(), T{1}, T::Highest()),
|
|
||||||
C(T::Highest(), Negate(T{1}), T::Lowest()),
|
|
||||||
});
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
auto error_msg = [](auto a, auto b) {
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "-", b);
|
return "12:34 error: " + OverflowErrorMessage(a, "-", b);
|
||||||
};
|
};
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
ConcatInto( //
|
||||||
r, std::vector<Case>{
|
r, std::vector<Case>{
|
||||||
E(T::Lowest(), T{1}, error_msg(T::Lowest(), T{1})),
|
E(T::Lowest(), T{1}, error_msg(T::Lowest(), T{1})),
|
||||||
E(T::Highest(), Negate(T{1}), error_msg(T::Highest(), Negate(T{1}))),
|
E(T::Highest(), Negate(T{1}), error_msg(T::Highest(), Negate(T{1}))),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
ConcatInto( //
|
||||||
|
r, std::vector<Case>{
|
||||||
|
C(T::Lowest(), T{1}, T::Highest()),
|
||||||
|
C(T::Highest(), Negate(T{1}), T::Lowest()),
|
||||||
|
});
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<Case> OpSubFloatCases() {
|
std::vector<Case> OpSubFloatCases() {
|
||||||
static_assert(IsFloatingPoint<T>);
|
static_assert(IsFloatingPoint<T>);
|
||||||
auto r = std::vector<Case>{
|
auto error_msg = [](auto a, auto b) {
|
||||||
|
return "12:34 error: " + OverflowErrorMessage(a, "-", b);
|
||||||
|
};
|
||||||
|
return std::vector<Case>{
|
||||||
C(T{0}, T{0}, T{0}),
|
C(T{0}, T{0}, T{0}),
|
||||||
C(T{3}, T{2}, T{1}),
|
C(T{3}, T{2}, T{1}),
|
||||||
C(T::Highest(), T{1}, T{T::Highest() - 1}),
|
C(T::Highest(), T{1}, T{T::Highest() - 1}),
|
||||||
C(T::Lowest(), Negate(T{1}), T{T::Lowest() + 1}),
|
C(T::Lowest(), Negate(T{1}), T{T::Lowest() + 1}),
|
||||||
C(T{0}, T::Highest(), T::Lowest()),
|
C(T{0}, T::Highest(), T::Lowest()),
|
||||||
};
|
|
||||||
ConcatIntoIf<!IsAbstract<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
C(T::Highest(), Negate(T::Highest()), T::Inf()),
|
|
||||||
C(T::Lowest(), T::Highest(), -T::Inf()),
|
|
||||||
});
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "-", b);
|
|
||||||
};
|
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
E(T::Highest(), Negate(T::Highest()), error_msg(T::Highest(), Negate(T::Highest()))),
|
E(T::Highest(), Negate(T::Highest()), error_msg(T::Highest(), Negate(T::Highest()))),
|
||||||
E(T::Lowest(), T::Highest(), error_msg(T::Lowest(), T::Highest())),
|
E(T::Lowest(), T::Highest(), error_msg(T::Lowest(), T::Highest())),
|
||||||
});
|
};
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(Sub,
|
INSTANTIATE_TEST_SUITE_P(Sub,
|
||||||
ResolverConstEvalBinaryOpTest,
|
ResolverConstEvalBinaryOpTest,
|
||||||
|
@ -267,21 +257,25 @@ std::vector<Case> OpMulScalarCases() {
|
||||||
C(T::Highest(), T{1}, T::Highest()),
|
C(T::Highest(), T{1}, T::Highest()),
|
||||||
C(T::Lowest(), T{1}, T::Lowest()),
|
C(T::Lowest(), T{1}, T::Lowest()),
|
||||||
};
|
};
|
||||||
ConcatIntoIf<!IsAbstract<T>>( //
|
if constexpr (IsAbstract<T> || IsFloatingPoint<T>) {
|
||||||
r, std::vector<Case>{
|
|
||||||
C(T::Highest(), T::Highest(), Mul(T::Highest(), T::Highest())),
|
|
||||||
C(T::Lowest(), T::Lowest(), Mul(T::Lowest(), T::Lowest())),
|
|
||||||
});
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
auto error_msg = [](auto a, auto b) {
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "*", b);
|
return "12:34 error: " + OverflowErrorMessage(a, "*", b);
|
||||||
};
|
};
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
ConcatInto( //
|
||||||
r, std::vector<Case>{
|
r, std::vector<Case>{
|
||||||
|
// Fail if result is +/-inf
|
||||||
E(T::Highest(), T::Highest(), error_msg(T::Highest(), T::Highest())),
|
E(T::Highest(), T::Highest(), error_msg(T::Highest(), T::Highest())),
|
||||||
E(T::Lowest(), T::Lowest(), error_msg(T::Lowest(), T::Lowest())),
|
E(T::Lowest(), T::Lowest(), error_msg(T::Lowest(), T::Lowest())),
|
||||||
E(T::Highest(), T{2}, error_msg(T::Highest(), T{2})),
|
E(T::Highest(), T{2}, error_msg(T::Highest(), T{2})),
|
||||||
E(T::Lowest(), Negate(T{2}), error_msg(T::Lowest(), Negate(T{2}))),
|
E(T::Lowest(), Negate(T{2}), error_msg(T::Lowest(), Negate(T{2}))),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
ConcatInto( //
|
||||||
|
r, std::vector<Case>{
|
||||||
|
C(T::Highest(), T::Highest(), Mul(T::Highest(), T::Highest())),
|
||||||
|
C(T::Lowest(), T::Lowest(), Mul(T::Lowest(), T::Lowest())),
|
||||||
|
});
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,14 +289,24 @@ std::vector<Case> OpMulVecCases() {
|
||||||
// vec3 * vec3 = vec3
|
// vec3 * vec3 = vec3
|
||||||
C(Vec(T{1.25}, T{2.25}, T{3.25}), Vec(T{2.0}, T{2.0}, T{2.0}), Vec(T{2.5}, T{4.5}, T{6.5})),
|
C(Vec(T{1.25}, T{2.25}, T{3.25}), Vec(T{2.0}, T{2.0}, T{2.0}), Vec(T{2.5}, T{4.5}, T{6.5})),
|
||||||
};
|
};
|
||||||
|
if constexpr (IsAbstract<T> || IsFloatingPoint<T>) {
|
||||||
auto error_msg = [](auto a, auto b) {
|
auto error_msg = [](auto a, auto b) {
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "*", b);
|
return "12:34 error: " + OverflowErrorMessage(a, "*", b);
|
||||||
};
|
};
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
ConcatInto( //
|
||||||
r, std::vector<Case>{
|
r,
|
||||||
|
std::vector<Case>{
|
||||||
|
// Fail if result is +/-inf
|
||||||
E(Val(T::Highest()), Vec(T{2}, T{1}), error_msg(T::Highest(), T{2})),
|
E(Val(T::Highest()), Vec(T{2}, T{1}), error_msg(T::Highest(), T{2})),
|
||||||
E(Val(T::Lowest()), Vec(Negate(T{2}), T{1}), error_msg(T::Lowest(), Negate(T{2}))),
|
E(Val(T::Lowest()), Vec(Negate(T{2}), T{1}), error_msg(T::Lowest(), Negate(T{2}))),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
ConcatInto( //
|
||||||
|
r, std::vector<Case>{
|
||||||
|
C(Val(T::Highest()), Vec(T{2}, T{1}), Vec(T{-2}, T::Highest())),
|
||||||
|
C(Val(T::Lowest()), Vec(Negate(T{2}), T{1}), Vec(T{0}, T{T::Lowest()})),
|
||||||
|
});
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +351,7 @@ std::vector<Case> OpMulMatCases() {
|
||||||
auto error_msg = [](auto a, const char* op, auto b) {
|
auto error_msg = [](auto a, const char* op, auto b) {
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, op, b);
|
return "12:34 error: " + OverflowErrorMessage(a, op, b);
|
||||||
};
|
};
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
ConcatIntoIf<IsAbstract<T> || IsFloatingPoint<T>>( //
|
||||||
r, std::vector<Case>{
|
r, std::vector<Case>{
|
||||||
// vector-matrix multiply
|
// vector-matrix multiply
|
||||||
|
|
||||||
|
@ -389,10 +393,10 @@ std::vector<Case> OpMulMatCases() {
|
||||||
// Overflow from second multiplication of dot product of lhs row 0 and rhs column 0
|
// Overflow from second multiplication of dot product of lhs row 0 and rhs column 0
|
||||||
// i.e. m1[0][0] * m2[0][0] + m1[0][1] * m[1][0]
|
// i.e. m1[0][0] * m2[0][0] + m1[0][1] * m[1][0]
|
||||||
// ^
|
// ^
|
||||||
E(Mat({T{1.0}, T::Highest()}, //
|
E(Mat({T{1.0}, T{1.0}}, //
|
||||||
|
{T::Highest(), T{1.0}}), //
|
||||||
|
Mat({T{1.0}, T{2.0}}, //
|
||||||
{T{1.0}, T{1.0}}), //
|
{T{1.0}, T{1.0}}), //
|
||||||
Mat({T{1.0}, T{1.0}}, //
|
|
||||||
{T{2.0}, T{1.0}}), //
|
|
||||||
error_msg(T::Highest(), "*", T{2.0})),
|
error_msg(T::Highest(), "*", T{2.0})),
|
||||||
|
|
||||||
// Overflow from addition of dot product of lhs row 0 and rhs column 0
|
// Overflow from addition of dot product of lhs row 0 and rhs column 0
|
||||||
|
@ -453,11 +457,23 @@ std::vector<Case> OpDivIntCases() {
|
||||||
// e1, when e1 is the most negative value in T, and e2 is -1.
|
// e1, when e1 is the most negative value in T, and e2 is -1.
|
||||||
C(T::Smallest(), T{-1}, T::Smallest()),
|
C(T::Smallest(), T{-1}, T::Smallest()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto error_msg = [](auto a, auto b) {
|
||||||
|
return "12:34 error: " + OverflowErrorMessage(a, "/", b);
|
||||||
|
};
|
||||||
|
ConcatIntoIf<IsAbstract<T>>( //
|
||||||
|
r, std::vector<Case>{
|
||||||
|
// Most negative value divided by -1
|
||||||
|
E(AInt::Lowest(), -1_a, error_msg(AInt::Lowest(), -1_a)),
|
||||||
|
});
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<Case> OpDivFloatCases() {
|
std::vector<Case> OpDivFloatCases() {
|
||||||
|
auto error_msg = [](auto a, auto b) {
|
||||||
|
return "12:34 error: " + OverflowErrorMessage(a, "/", b);
|
||||||
|
};
|
||||||
std::vector<Case> r = {
|
std::vector<Case> r = {
|
||||||
C(Val(T{0}), Val(T{1}), Val(T{0})),
|
C(Val(T{0}), Val(T{1}), Val(T{0})),
|
||||||
C(Val(T{1}), Val(T{1}), Val(T{1})),
|
C(Val(T{1}), Val(T{1}), Val(T{1})),
|
||||||
|
@ -469,32 +485,13 @@ std::vector<Case> OpDivFloatCases() {
|
||||||
C(Val(T::Highest()), Val(T::Highest()), Val(T{1})),
|
C(Val(T::Highest()), Val(T::Highest()), Val(T{1})),
|
||||||
C(Val(T{0}), Val(T::Highest()), Val(T{0})),
|
C(Val(T{0}), Val(T::Highest()), Val(T{0})),
|
||||||
C(Val(T{0}), Val(T::Lowest()), Val(-T{0})),
|
C(Val(T{0}), Val(T::Lowest()), Val(-T{0})),
|
||||||
};
|
|
||||||
ConcatIntoIf<!IsAbstract<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
C(T{123}, T{0}, T::Inf()),
|
|
||||||
C(T{-123}, -T{0}, T::Inf()),
|
|
||||||
C(T{-123}, T{0}, -T::Inf()),
|
|
||||||
C(T{123}, -T{0}, -T::Inf()),
|
|
||||||
});
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "/", b);
|
|
||||||
};
|
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
// Divide by zero
|
// Divide by zero
|
||||||
E(T{123}, T{0}, error_msg(T{123}, T{0})),
|
E(T{123}, T{0}, error_msg(T{123}, T{0})),
|
||||||
E(Negate(T{123}), Negate(T{0}), error_msg(Negate(T{123}), Negate(T{0}))),
|
E(Negate(T{123}), Negate(T{0}), error_msg(Negate(T{123}), Negate(T{0}))),
|
||||||
E(Negate(T{123}), T{0}, error_msg(Negate(T{123}), T{0})),
|
E(Negate(T{123}), T{0}, error_msg(Negate(T{123}), T{0})),
|
||||||
E(T{123}, Negate(T{0}), error_msg(T{123}, Negate(T{0}))),
|
E(T{123}, Negate(T{0}), error_msg(T{123}, Negate(T{0}))),
|
||||||
});
|
};
|
||||||
|
|
||||||
ConcatIntoIf<std::is_same_v<T, AInt>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
// Most negative value divided by -1
|
|
||||||
E(AInt::Lowest(), -1_a, error_msg(AInt::Lowest(), -1_a)),
|
|
||||||
});
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(Div,
|
INSTANTIATE_TEST_SUITE_P(Div,
|
||||||
|
|
|
@ -848,7 +848,7 @@ INSTANTIATE_TEST_SUITE_P( //
|
||||||
testing::ValuesIn(Concat(CountOneBitsCases<i32>(), //
|
testing::ValuesIn(Concat(CountOneBitsCases<i32>(), //
|
||||||
CountOneBitsCases<u32>()))));
|
CountOneBitsCases<u32>()))));
|
||||||
|
|
||||||
template <typename T, bool finite_only>
|
template <typename T>
|
||||||
std::vector<Case> CrossCases() {
|
std::vector<Case> CrossCases() {
|
||||||
constexpr auto vec_x = [](T v) { return Vec(T(v), T(0), T(0)); };
|
constexpr auto vec_x = [](T v) { return Vec(T(v), T(0), T(0)); };
|
||||||
constexpr auto vec_y = [](T v) { return Vec(T(0), T(v), T(0)); };
|
constexpr auto vec_y = [](T v) { return Vec(T(0), T(v), T(0)); };
|
||||||
|
@ -870,12 +870,6 @@ std::vector<Case> CrossCases() {
|
||||||
const auto lowest_x = vec_x(T::Lowest());
|
const auto lowest_x = vec_x(T::Lowest());
|
||||||
const auto lowest_y = vec_y(T::Lowest());
|
const auto lowest_y = vec_y(T::Lowest());
|
||||||
const auto lowest_z = vec_z(T::Lowest());
|
const auto lowest_z = vec_z(T::Lowest());
|
||||||
const auto inf_x = vec_x(T::Inf());
|
|
||||||
const auto inf_y = vec_y(T::Inf());
|
|
||||||
const auto inf_z = vec_z(T::Inf());
|
|
||||||
const auto neg_inf_x = vec_x(-T::Inf());
|
|
||||||
const auto neg_inf_y = vec_y(-T::Inf());
|
|
||||||
const auto neg_inf_z = vec_z(-T::Inf());
|
|
||||||
|
|
||||||
std::vector<Case> r = {
|
std::vector<Case> r = {
|
||||||
C({zero, zero}, zero),
|
C({zero, zero}, zero),
|
||||||
|
@ -924,28 +918,11 @@ std::vector<Case> CrossCases() {
|
||||||
Vec(T(-10.75), T(-6.75), T(11.75))),
|
Vec(T(-10.75), T(-6.75), T(11.75))),
|
||||||
};
|
};
|
||||||
|
|
||||||
ConcatIntoIf<!finite_only>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
C({highest_x, highest_y}, inf_z).PosOrNeg(), //
|
|
||||||
C({highest_y, highest_x}, inf_z).PosOrNeg(), //
|
|
||||||
C({highest_z, highest_x}, inf_y).PosOrNeg(), //
|
|
||||||
C({highest_x, highest_z}, inf_y).PosOrNeg(), //
|
|
||||||
C({highest_y, highest_z}, inf_x).PosOrNeg(), //
|
|
||||||
C({highest_z, highest_y}, inf_x).PosOrNeg(), //
|
|
||||||
C({lowest_x, lowest_y}, inf_z).PosOrNeg(), //
|
|
||||||
C({lowest_y, lowest_x}, inf_z).PosOrNeg(), //
|
|
||||||
C({lowest_z, lowest_x}, inf_y).PosOrNeg(), //
|
|
||||||
C({lowest_x, lowest_z}, inf_y).PosOrNeg(), //
|
|
||||||
C({lowest_y, lowest_z}, inf_x).PosOrNeg(), //
|
|
||||||
C({lowest_z, lowest_y}, inf_x).PosOrNeg(),
|
|
||||||
});
|
|
||||||
|
|
||||||
std::string pos_error_msg =
|
std::string pos_error_msg =
|
||||||
"12:34 error: " + OverflowErrorMessage(T::Highest(), "*", T::Highest());
|
"12:34 error: " + OverflowErrorMessage(T::Highest(), "*", T::Highest());
|
||||||
std::string neg_error_msg =
|
std::string neg_error_msg =
|
||||||
"12:34 error: " + OverflowErrorMessage(T::Lowest(), "*", T::Lowest());
|
"12:34 error: " + OverflowErrorMessage(T::Lowest(), "*", T::Lowest());
|
||||||
|
ConcatInto( //
|
||||||
ConcatIntoIf<finite_only>( //
|
|
||||||
r, std::vector<Case>{
|
r, std::vector<Case>{
|
||||||
E({highest_x, highest_y}, pos_error_msg),
|
E({highest_x, highest_y}, pos_error_msg),
|
||||||
E({highest_y, highest_x}, pos_error_msg),
|
E({highest_y, highest_x}, pos_error_msg),
|
||||||
|
@ -967,10 +944,10 @@ INSTANTIATE_TEST_SUITE_P( //
|
||||||
Cross,
|
Cross,
|
||||||
ResolverConstEvalBuiltinTest,
|
ResolverConstEvalBuiltinTest,
|
||||||
testing::Combine(testing::Values(sem::BuiltinType::kCross),
|
testing::Combine(testing::Values(sem::BuiltinType::kCross),
|
||||||
testing::ValuesIn(Concat(CrossCases<AFloat, true>(), //
|
testing::ValuesIn(Concat(CrossCases<AFloat>(), //
|
||||||
CrossCases<f32, false>(),
|
CrossCases<f32>(),
|
||||||
CrossCases<f32, false>(), //
|
CrossCases<f32>(), //
|
||||||
CrossCases<f16, false>()))));
|
CrossCases<f16>()))));
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<Case> FirstLeadingBitCases() {
|
std::vector<Case> FirstLeadingBitCases() {
|
||||||
|
|
|
@ -352,9 +352,11 @@ TEST_P(MaterializeAbstractNumericToConcreteType, Test) {
|
||||||
Structure("S", utils::Vector{Member("v", target_ty())});
|
Structure("S", utils::Vector{Member("v", target_ty())});
|
||||||
WrapInFunction(Construct(ty.type_name("S"), abstract_expr));
|
WrapInFunction(Construct(ty.type_name("S"), abstract_expr));
|
||||||
break;
|
break;
|
||||||
case Method::kBinaryOp:
|
case Method::kBinaryOp: {
|
||||||
WrapInFunction(Add(target_expr(), abstract_expr));
|
// Add 0 to ensure no overflow with max float values
|
||||||
break;
|
auto binary_target_expr = data.target_expr(*this, 0);
|
||||||
|
WrapInFunction(Add(binary_target_expr, abstract_expr));
|
||||||
|
} break;
|
||||||
case Method::kSwitchCond:
|
case Method::kSwitchCond:
|
||||||
WrapInFunction(
|
WrapInFunction(
|
||||||
Switch(abstract_expr, //
|
Switch(abstract_expr, //
|
||||||
|
|
|
@ -146,7 +146,7 @@ OpDecorate %20 Binding 1
|
||||||
%128 = OpLoad %50 %10
|
%128 = OpLoad %50 %10
|
||||||
%129 = OpLoad %52 %20
|
%129 = OpLoad %52 %20
|
||||||
%130 = OpSampledImage %124 %129 %128
|
%130 = OpSampledImage %124 %129 %128
|
||||||
%131 = OpImageSampleProjImplicitLod %v4float %130 %126
|
%131 = OpImageSampleProjImplicitLod %v4float %130 %47
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ OpDecorate %20 Binding 1
|
||||||
%128 = OpLoad %50 %10
|
%128 = OpLoad %50 %10
|
||||||
%129 = OpLoad %52 %20
|
%129 = OpLoad %52 %20
|
||||||
%130 = OpSampledImage %124 %129 %128
|
%130 = OpSampledImage %124 %129 %128
|
||||||
%131 = OpImageSampleProjExplicitLod %v4float %130 %126 Lod %29
|
%131 = OpImageSampleProjExplicitLod %v4float %130 %47 Lod %29
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ OpDecorate %20 Binding 1
|
||||||
%128 = OpLoad %50 %10
|
%128 = OpLoad %50 %10
|
||||||
%129 = OpLoad %52 %20
|
%129 = OpLoad %52 %20
|
||||||
%130 = OpSampledImage %124 %129 %128
|
%130 = OpSampledImage %124 %129 %128
|
||||||
%131 = OpImageSampleProjDrefImplicitLod %float %130 %126 %float_0_200000003
|
%131 = OpImageSampleProjDrefImplicitLod %float %130 %47 %float_0_200000003
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ OpDecorate %20 Binding 1
|
||||||
%128 = OpLoad %50 %10
|
%128 = OpLoad %50 %10
|
||||||
%129 = OpLoad %52 %20
|
%129 = OpLoad %52 %20
|
||||||
%130 = OpSampledImage %124 %129 %128
|
%130 = OpSampledImage %124 %129 %128
|
||||||
%131 = OpImageSampleProjDrefExplicitLod %float %130 %126 %float_0_200000003 Lod %29
|
%131 = OpImageSampleProjDrefExplicitLod %float %130 %47 %float_0_200000003 Lod %29
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
%main = OpFunction %void None %21
|
%main = OpFunction %void None %21
|
||||||
%39 = OpLabel
|
%39 = OpLabel
|
||||||
%undefined = OpVariable %_ptr_Function_float Function
|
%undefined = OpVariable %_ptr_Function_float Function
|
||||||
%40 = OpFMod %float %float_5 %float_0
|
%40 = OpFMod %float %float_5 %float_5
|
||||||
OpStore %undefined %40
|
OpStore %undefined %40
|
||||||
%41 = OpAccessChain %_ptr_Uniform_int %_ %int_0 %int_0
|
%41 = OpAccessChain %_ptr_Uniform_int %_ %int_0 %int_0
|
||||||
%10 = OpLoad %int %41
|
%10 = OpLoad %int %41
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn main_1() {
|
||||||
var undefined : f32;
|
var undefined : f32;
|
||||||
var x_51 : bool;
|
var x_51 : bool;
|
||||||
var x_52_phi : bool;
|
var x_52_phi : bool;
|
||||||
undefined = (5.0 - (0.0 * floor((5.0 / 0.0f))));
|
undefined = (5.0 - (0.0 * floor((5.0 / 5.0f))));
|
||||||
let x_10 : i32 = x_6.x_GLF_uniform_int_values[0].el;
|
let x_10 : i32 = x_6.x_GLF_uniform_int_values[0].el;
|
||||||
let x_11 : i32 = x_6.x_GLF_uniform_int_values[0].el;
|
let x_11 : i32 = x_6.x_GLF_uniform_int_values[0].el;
|
||||||
let x_12 : i32 = x_6.x_GLF_uniform_int_values[1].el;
|
let x_12 : i32 = x_6.x_GLF_uniform_int_values[1].el;
|
||||||
|
|
|
@ -499,6 +499,14 @@ crbug.com/tint/1755 [ win10 ] webgpu:shader,execution,expression,call,builtin,pa
|
||||||
crbug.com/tint/1755 [ win10 ] webgpu:shader,execution,expression,call,builtin,pack4x8snorm:pack:inputSource="const" [ Failure ]
|
crbug.com/tint/1755 [ win10 ] webgpu:shader,execution,expression,call,builtin,pack4x8snorm:pack:inputSource="const" [ Failure ]
|
||||||
crbug.com/tint/1755 [ win10 ] webgpu:shader,execution,expression,call,builtin,pack4x8unorm:pack:inputSource="const" [ Failure ]
|
crbug.com/tint/1755 [ win10 ] webgpu:shader,execution,expression,call,builtin,pack4x8unorm:pack:inputSource="const" [ Failure ]
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Const-eval functions that fail on inf/nan inputs
|
||||||
|
# KEEP
|
||||||
|
################################################################################
|
||||||
|
crbug.com/tint/1581 webgpu:shader,execution,expression,binary,f32_arithmetic:division:inputSource="const";* [ Failure ]
|
||||||
|
crbug.com/tint/1581 [ win ] webgpu:shader,execution,expression,call,builtin,cross:f32:inputSource="const" [ Failure ]
|
||||||
|
crbug.com/tint/1581 [ linux ] webgpu:shader,execution,expression,call,builtin,cross:f32:inputSource="const" [ Failure ]
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# untriaged failures
|
# untriaged failures
|
||||||
# KEEP
|
# KEEP
|
||||||
|
|
Loading…
Reference in New Issue