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>
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index daa66e5..713ad36 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -310,12 +310,10 @@
} 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
diff --git a/src/tint/resolver/const_eval_conversion_test.cc b/src/tint/resolver/const_eval_conversion_test.cc
index 7e6a6fc..ed68725 100644
--- a/src/tint/resolver/const_eval_conversion_test.cc
+++ b/src/tint/resolver/const_eval_conversion_test.cc
@@ -440,38 +440,11 @@
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) {