[tint][constant] Optimize Value::Equal() for splats
Element-wise comparisons are slow and unnecessary for large `constant::Splat` values.
Bug: chromium:1449538
Change-Id: I17dbfe1fffabbdb45f48920ba8de3af65ed24cae
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/135262
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/constant/value_test.cc b/src/tint/constant/value_test.cc
new file mode 100644
index 0000000..e715c21
--- /dev/null
+++ b/src/tint/constant/value_test.cc
@@ -0,0 +1,78 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/constant/splat.h"
+
+#include "src/tint/constant/scalar.h"
+#include "src/tint/constant/test_helper.h"
+
+namespace tint::constant {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using ConstantTest_Value = TestHelper;
+
+TEST_F(ConstantTest_Value, Equal_Scalar_Scalar) {
+ EXPECT_TRUE(constants.Get(10_i)->Equal(constants.Get(10_i)));
+ EXPECT_FALSE(constants.Get(10_i)->Equal(constants.Get(20_i)));
+ EXPECT_FALSE(constants.Get(20_i)->Equal(constants.Get(10_i)));
+
+ EXPECT_TRUE(constants.Get(10_u)->Equal(constants.Get(10_u)));
+ EXPECT_FALSE(constants.Get(10_u)->Equal(constants.Get(20_u)));
+ EXPECT_FALSE(constants.Get(20_u)->Equal(constants.Get(10_u)));
+
+ EXPECT_TRUE(constants.Get(10_f)->Equal(constants.Get(10_f)));
+ EXPECT_FALSE(constants.Get(10_f)->Equal(constants.Get(20_f)));
+ EXPECT_FALSE(constants.Get(20_f)->Equal(constants.Get(10_f)));
+}
+
+TEST_F(ConstantTest_Value, Equal_Splat_Splat) {
+ auto* vec3f = create<type::Vector>(create<type::F32>(), 3u);
+
+ auto* vec3f_1_1_1 = constants.Splat(vec3f, constants.Get(1_f), 3);
+ auto* vec3f_2_2_2 = constants.Splat(vec3f, constants.Get(2_f), 3);
+
+ EXPECT_TRUE(vec3f_1_1_1->Equal(vec3f_1_1_1));
+ EXPECT_FALSE(vec3f_2_2_2->Equal(vec3f_1_1_1));
+ EXPECT_FALSE(vec3f_1_1_1->Equal(vec3f_2_2_2));
+}
+
+TEST_F(ConstantTest_Value, Equal_Composite_Composite) {
+ auto* vec3f = create<type::Vector>(create<type::F32>(), 3u);
+
+ auto* vec3f_1_1_2 = constants.Composite(
+ vec3f, utils::Vector{constants.Get(1_f), constants.Get(1_f), constants.Get(2_f)});
+ auto* vec3f_1_2_1 = constants.Composite(
+ vec3f, utils::Vector{constants.Get(1_f), constants.Get(2_f), constants.Get(1_f)});
+
+ EXPECT_TRUE(vec3f_1_1_2->Equal(vec3f_1_1_2));
+ EXPECT_FALSE(vec3f_1_2_1->Equal(vec3f_1_1_2));
+ EXPECT_FALSE(vec3f_1_1_2->Equal(vec3f_1_2_1));
+}
+
+TEST_F(ConstantTest_Value, Equal_Splat_Composite) {
+ auto* vec3f = create<type::Vector>(create<type::F32>(), 3u);
+
+ auto* vec3f_1_1_1 = constants.Splat(vec3f, constants.Get(1_f), 3);
+ auto* vec3f_1_2_1 = constants.Composite(
+ vec3f, utils::Vector{constants.Get(1_f), constants.Get(2_f), constants.Get(1_f)});
+
+ EXPECT_TRUE(vec3f_1_1_1->Equal(vec3f_1_1_1));
+ EXPECT_FALSE(vec3f_1_2_1->Equal(vec3f_1_1_1));
+ EXPECT_FALSE(vec3f_1_1_1->Equal(vec3f_1_2_1));
+}
+
+} // namespace
+} // namespace tint::constant