tint/const-eval: Fix runtime semantics for (x % 0)

The result of integer mod is defined to be zero when the RHS is zero
and for (MOST_NEGATIVE / -1). Floating point is expected to be
implementation defined, so also return zero in this case.

Change-Id: Ic25250d637ccb93ba62a5fc0bcebe670d5cd4e3b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121544
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Auto-Submit: James Price <jrprice@google.com>
This commit is contained in:
James Price 2023-02-27 16:02:02 +00:00 committed by Dawn LUCI CQ
parent 35df626efa
commit fe19fee3ea
2 changed files with 9 additions and 9 deletions

View File

@ -714,7 +714,7 @@ utils::Result<NumberT> ConstEval::Mod(const Source& source, NumberT a, NumberT b
} else {
AddError(OverflowErrorMessage(a, "%", b), source);
if (use_runtime_semantics_) {
return a;
return NumberT{0};
} else {
return utils::Failure;
}
@ -727,7 +727,7 @@ utils::Result<NumberT> ConstEval::Mod(const Source& source, NumberT a, NumberT b
// lhs % 0 is an error
AddError(OverflowErrorMessage(a, "%", b), source);
if (use_runtime_semantics_) {
return a;
return NumberT{0};
} else {
return utils::Failure;
}
@ -738,7 +738,7 @@ utils::Result<NumberT> ConstEval::Mod(const Source& source, NumberT a, NumberT b
if (rhs == -1 && lhs == std::numeric_limits<T>::min()) {
AddError(OverflowErrorMessage(a, "%", b), source);
if (use_runtime_semantics_) {
return a;
return NumberT{0};
} else {
return utils::Failure;
}

View File

@ -212,7 +212,7 @@ TEST_F(ResolverConstEvalRuntimeSemanticsTest, Mod_AInt_ZeroDenominator) {
auto* b = Scalar(AInt(0));
auto result = const_eval.OpModulo(a->Type(), utils::Vector{a, b}, {});
ASSERT_TRUE(result);
EXPECT_EQ(result.Get()->ValueAs<AInt>(), 42);
EXPECT_EQ(result.Get()->ValueAs<AInt>(), 0);
EXPECT_EQ(error(), R"(warning: '42 % 0' cannot be represented as 'abstract-int')");
}
@ -221,7 +221,7 @@ TEST_F(ResolverConstEvalRuntimeSemanticsTest, Mod_I32_ZeroDenominator) {
auto* b = Scalar(i32(0));
auto result = const_eval.OpModulo(a->Type(), utils::Vector{a, b}, {});
ASSERT_TRUE(result);
EXPECT_EQ(result.Get()->ValueAs<i32>(), 42);
EXPECT_EQ(result.Get()->ValueAs<i32>(), 0);
EXPECT_EQ(error(), R"(warning: '42 % 0' cannot be represented as 'i32')");
}
@ -230,7 +230,7 @@ TEST_F(ResolverConstEvalRuntimeSemanticsTest, Mod_U32_ZeroDenominator) {
auto* b = Scalar(u32(0));
auto result = const_eval.OpModulo(a->Type(), utils::Vector{a, b}, {});
ASSERT_TRUE(result);
EXPECT_EQ(result.Get()->ValueAs<u32>(), 42);
EXPECT_EQ(result.Get()->ValueAs<u32>(), 0);
EXPECT_EQ(error(), R"(warning: '42 % 0' cannot be represented as 'u32')");
}
@ -239,7 +239,7 @@ TEST_F(ResolverConstEvalRuntimeSemanticsTest, Mod_AFloat_ZeroDenominator) {
auto* b = Scalar(AFloat(0));
auto result = const_eval.OpModulo(a->Type(), utils::Vector{a, b}, {});
ASSERT_TRUE(result);
EXPECT_EQ(result.Get()->ValueAs<AFloat>(), 42.f);
EXPECT_EQ(result.Get()->ValueAs<AFloat>(), 0.f);
EXPECT_EQ(error(), R"(warning: '42 % 0' cannot be represented as 'abstract-float')");
}
@ -248,7 +248,7 @@ TEST_F(ResolverConstEvalRuntimeSemanticsTest, Mod_F32_ZeroDenominator) {
auto* b = Scalar(f32(0));
auto result = const_eval.OpModulo(a->Type(), utils::Vector{a, b}, {});
ASSERT_TRUE(result);
EXPECT_EQ(result.Get()->ValueAs<f32>(), 42.f);
EXPECT_EQ(result.Get()->ValueAs<f32>(), 0.f);
EXPECT_EQ(error(), R"(warning: '42 % 0' cannot be represented as 'f32')");
}
@ -257,7 +257,7 @@ TEST_F(ResolverConstEvalRuntimeSemanticsTest, Mod_I32_MostNegativeByMinInt) {
auto* b = Scalar(i32(-1));
auto result = const_eval.OpModulo(a->Type(), utils::Vector{a, b}, {});
ASSERT_TRUE(result);
EXPECT_EQ(result.Get()->ValueAs<i32>(), i32::Lowest());
EXPECT_EQ(result.Get()->ValueAs<i32>(), 0);
EXPECT_EQ(error(), R"(warning: '-2147483648 % -1' cannot be represented as 'i32')");
}