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>
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index dc59ccd..e516732 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -714,7 +714,7 @@
} else {
AddError(OverflowErrorMessage(a, "%", b), source);
if (use_runtime_semantics_) {
- return a;
+ return NumberT{0};
} else {
return utils::Failure;
}
@@ -727,7 +727,7 @@
// 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 @@
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;
}
diff --git a/src/tint/resolver/const_eval_runtime_semantics_test.cc b/src/tint/resolver/const_eval_runtime_semantics_test.cc
index 9de1866..bc7f3c8 100644
--- a/src/tint/resolver/const_eval_runtime_semantics_test.cc
+++ b/src/tint/resolver/const_eval_runtime_semantics_test.cc
@@ -212,7 +212,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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')");
}