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:
Antonio Maiorano 2022-11-21 15:29:54 +00:00
parent 92b32e8efc
commit 893316014a
2 changed files with 7 additions and 36 deletions

View File

@ -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

View File

@ -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) {