tint: emit an error for float conversions that are not representable
For example, a large f32 value converted to f16 now fails, instead of resulting in +/-inf. Bug: tint:1581 Bug: tint:1747 Change-Id: I30fd8c61ecc328206e8f73b626af8046dad4b0b9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/110723 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
92b32e8efc
commit
893316014a
|
@ -310,12 +310,10 @@ struct Element : ImplConstant {
|
|||
} else if constexpr (IsFloatingPoint<TO>) {
|
||||
// [x -> floating-point] - number not exactly representable
|
||||
// https://www.w3.org/TR/WGSL/#floating-point-conversion
|
||||
switch (conv.Failure()) {
|
||||
case ConversionFailure::kExceedsNegativeLimit:
|
||||
return builder.create<Element<TO>>(target_ty, -TO::Inf());
|
||||
case ConversionFailure::kExceedsPositiveLimit:
|
||||
return builder.create<Element<TO>>(target_ty, TO::Inf());
|
||||
}
|
||||
builder.Diagnostics().add_error(
|
||||
tint::diag::System::Resolver,
|
||||
OverflowErrorMessage(value, builder.FriendlyName(target_ty)), source);
|
||||
return utils::Failure;
|
||||
} else if constexpr (IsFloatingPoint<FROM>) {
|
||||
// [floating-point -> integer] - number not exactly representable
|
||||
// https://www.w3.org/TR/WGSL/#floating-point-conversion
|
||||
|
|
|
@ -440,38 +440,11 @@ TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_u32) {
|
|||
TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* expr = vec3<f16>(vec3<f32>(1e10_f, -1e20_f, 1e30_f));
|
||||
auto* expr = vec3<f16>(Source{{12, 34}}, vec3<f32>(1e10_f, 0_f, 0_f));
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
constexpr auto kInfinity = std::numeric_limits<double>::infinity();
|
||||
|
||||
auto* sem = Sem().Get(expr);
|
||||
ASSERT_NE(sem, nullptr);
|
||||
auto* vec = sem->Type()->As<sem::Vector>();
|
||||
ASSERT_NE(vec, nullptr);
|
||||
EXPECT_TRUE(vec->type()->Is<sem::F16>());
|
||||
EXPECT_EQ(vec->Width(), 3u);
|
||||
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
|
||||
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
|
||||
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
|
||||
EXPECT_FALSE(sem->ConstantValue()->AllZero());
|
||||
|
||||
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
|
||||
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
|
||||
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
|
||||
EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AFloat>(), kInfinity);
|
||||
|
||||
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
|
||||
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
|
||||
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
|
||||
EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AFloat>(), -kInfinity);
|
||||
|
||||
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
|
||||
EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
|
||||
EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
|
||||
EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AFloat>(), kInfinity);
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: value 10000000000 cannot be represented as 'f16'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverConstEvalTest, Vec3_Convert_Small_f32_to_f16) {
|
||||
|
|
Loading…
Reference in New Issue