[hlsl] Fix packed builtin type equality comparisons

The `Equals()` method was unconditionally returning `true` for these
two types, which leads to them being returned by the type manager when
trying to create completely unrelated types.

These types are only used with SM 6.6 or higher.

Bug: 399696817
Change-Id: I1e8b9b89da14229c0da00cb3da1bde3968e33b51
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/230515
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/hlsl/type/int8_t4_packed.cc b/src/tint/lang/hlsl/type/int8_t4_packed.cc
index 20a1f1e..1d2c7c9 100644
--- a/src/tint/lang/hlsl/type/int8_t4_packed.cc
+++ b/src/tint/lang/hlsl/type/int8_t4_packed.cc
@@ -44,8 +44,8 @@
     : Base(static_cast<size_t>(Hash(tint::TypeCode::Of<Int8T4Packed>().bits)),
            core::type::Flags{}) {}
 
-bool Int8T4Packed::Equals([[maybe_unused]] const UniqueNode& other) const {
-    return true;
+bool Int8T4Packed::Equals(const UniqueNode& other) const {
+    return other.Is<Int8T4Packed>();
 }
 
 std::string Int8T4Packed::FriendlyName() const {
diff --git a/src/tint/lang/hlsl/type/int8_t4_packed_test.cc b/src/tint/lang/hlsl/type/int8_t4_packed_test.cc
index 955d7ed..a14484e 100644
--- a/src/tint/lang/hlsl/type/int8_t4_packed_test.cc
+++ b/src/tint/lang/hlsl/type/int8_t4_packed_test.cc
@@ -29,7 +29,6 @@
 
 #include <gtest/gtest.h>
 
-#include "src/tint/lang/core/type/f32.h"
 #include "src/tint/lang/core/type/i32.h"
 
 namespace tint::hlsl::type {
@@ -38,8 +37,10 @@
 TEST(HlslTypeInt8T4Packed, Equals) {
     const Int8T4Packed a;
     const Int8T4Packed b;
+    const core::type::I32 i;
 
     EXPECT_TRUE(a.Equals(b));
+    EXPECT_FALSE(a.Equals(i));
 }
 
 TEST(HlslTypeInt8T4Packed, FriendlyName) {
diff --git a/src/tint/lang/hlsl/type/uint8_t4_packed.cc b/src/tint/lang/hlsl/type/uint8_t4_packed.cc
index 962a6cb..b121ac4 100644
--- a/src/tint/lang/hlsl/type/uint8_t4_packed.cc
+++ b/src/tint/lang/hlsl/type/uint8_t4_packed.cc
@@ -44,8 +44,8 @@
     : Base(static_cast<size_t>(Hash(tint::TypeCode::Of<Uint8T4Packed>().bits)),
            core::type::Flags{}) {}
 
-bool Uint8T4Packed::Equals([[maybe_unused]] const UniqueNode& other) const {
-    return true;
+bool Uint8T4Packed::Equals(const UniqueNode& other) const {
+    return other.Is<Uint8T4Packed>();
 }
 
 std::string Uint8T4Packed::FriendlyName() const {
diff --git a/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc b/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc
index af44acd..98318ca 100644
--- a/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc
+++ b/src/tint/lang/hlsl/type/uint8_t4_packed_test.cc
@@ -29,7 +29,6 @@
 
 #include <gtest/gtest.h>
 
-#include "src/tint/lang/core/type/f32.h"
 #include "src/tint/lang/core/type/i32.h"
 
 namespace tint::hlsl::type {
@@ -38,8 +37,10 @@
 TEST(HlslTypeUint8T4Packed, Equals) {
     const Uint8T4Packed a;
     const Uint8T4Packed b;
+    const core::type::I32 i;
 
     EXPECT_TRUE(a.Equals(b));
+    EXPECT_FALSE(a.Equals(i));
 }
 
 TEST(HlslTypeUint8T4Packed, FriendlyName) {
diff --git a/test/tint/bug/tint/399696817.wgsl b/test/tint/bug/tint/399696817.wgsl
new file mode 100644
index 0000000..eba4fb5
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl
@@ -0,0 +1,7 @@
+// flags: --hlsl-shader-model 66
+var<workgroup> a : atomic<i32>;
+fn foo(in: u32) {
+  let x = unpack4xI8(in);
+  let y = unpack4xU8(in);
+  let z = atomicLoad(&a);
+}
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/399696817.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..19cf533
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.dxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+groupshared int a;
+
+void foo(uint tint_symbol) {
+  int4 x = unpack_s8s32(int8_t4_packed(tint_symbol));
+  uint4 y = unpack_u8u32(uint8_t4_packed(tint_symbol));
+  int atomic_result = 0;
+  InterlockedOr(a, 0, atomic_result);
+  int z = atomic_result;
+}
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/399696817.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..9661831
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.fxc.hlsl
@@ -0,0 +1,21 @@
+SKIP: INVALID
+
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+  return;
+}
+
+groupshared int a;
+
+void foo(uint tint_symbol) {
+  int4 x = unpack_s8s32(int8_t4_packed(tint_symbol));
+  uint4 y = unpack_u8u32(uint8_t4_packed(tint_symbol));
+  int atomic_result = 0;
+  InterlockedOr(a, 0, atomic_result);
+  int z = atomic_result;
+}
+FXC validation failure:
+<scrubbed_path>(9,25-51): error X3004: undeclared identifier 'int8_t4_packed'
+
+
+tint executable returned error: exit status 1
\ No newline at end of file
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.glsl b/test/tint/bug/tint/399696817.wgsl.expected.glsl
new file mode 100644
index 0000000..633adc0
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.glsl
@@ -0,0 +1,15 @@
+#version 310 es
+
+shared int a;
+void foo(uint v) {
+  uvec4 v_1 = uvec4(24u, 16u, 8u, 0u);
+  ivec4 v_2 = ivec4((uvec4(v) << v_1));
+  ivec4 x = (v_2 >> uvec4(24u));
+  uvec4 v_3 = uvec4(0u, 8u, 16u, 24u);
+  uvec4 v_4 = (uvec4(v) >> v_3);
+  uvec4 y = (v_4 & uvec4(255u));
+  int z = atomicOr(a, 0);
+}
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+}
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/399696817.wgsl.expected.ir.dxc.hlsl
new file mode 100644
index 0000000..61d31c9
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.ir.dxc.hlsl
@@ -0,0 +1,14 @@
+
+groupshared int a;
+void foo(uint v) {
+  int4 x = unpack_s8s32(int8_t4_packed(v));
+  uint4 y = unpack_u8u32(uint8_t4_packed(v));
+  int v_1 = int(0);
+  InterlockedOr(a, int(0), v_1);
+  int z = v_1;
+}
+
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+}
+
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/399696817.wgsl.expected.ir.fxc.hlsl
new file mode 100644
index 0000000..c9d28e0
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.ir.fxc.hlsl
@@ -0,0 +1,20 @@
+SKIP: INVALID
+
+groupshared int a;
+void foo(uint v) {
+  int4 x = unpack_s8s32(int8_t4_packed(v));
+  uint4 y = unpack_u8u32(uint8_t4_packed(v));
+  int v_1 = int(0);
+  InterlockedOr(a, int(0), v_1);
+  int z = v_1;
+}
+
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+}
+
+FXC validation failure:
+<scrubbed_path>(4,25-41): error X3004: undeclared identifier 'int8_t4_packed'
+
+
+tint executable returned error: exit status 1
\ No newline at end of file
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.msl b/test/tint/bug/tint/399696817.wgsl.expected.msl
new file mode 100644
index 0000000..2d8fdae
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.msl
@@ -0,0 +1,16 @@
+#include <metal_stdlib>
+using namespace metal;
+
+struct tint_module_vars_struct {
+  threadgroup atomic_int* a;
+};
+
+void foo(uint in, tint_module_vars_struct tint_module_vars) {
+  uint4 const v = uint4(24u, 16u, 8u, 0u);
+  int4 const v_1 = as_type<int4>((uint4(in) << v));
+  int4 const x = (v_1 >> uint4(24u));
+  uint4 const v_2 = uint4(0u, 8u, 16u, 24u);
+  uint4 const v_3 = (uint4(in) >> v_2);
+  uint4 const y = (v_3 & uint4(255u));
+  int const z = atomic_load_explicit(tint_module_vars.a, memory_order_relaxed);
+}
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.spvasm b/test/tint/bug/tint/399696817.wgsl.expected.spvasm
new file mode 100644
index 0000000..15846de7
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.spvasm
@@ -0,0 +1,52 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 1
+; Bound: 33
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+               OpExecutionMode %unused_entry_point LocalSize 1 1 1
+               OpName %a "a"
+               OpName %foo "foo"
+               OpName %in "in"
+               OpName %x "x"
+               OpName %y "y"
+               OpName %z "z"
+               OpName %unused_entry_point "unused_entry_point"
+        %int = OpTypeInt 32 1
+%_ptr_Workgroup_int = OpTypePointer Workgroup %int
+          %a = OpVariable %_ptr_Workgroup_int Workgroup
+       %void = OpTypeVoid
+       %uint = OpTypeInt 32 0
+          %8 = OpTypeFunction %void %uint
+     %v4uint = OpTypeVector %uint 4
+    %uint_24 = OpConstant %uint 24
+    %uint_16 = OpConstant %uint 16
+     %uint_8 = OpConstant %uint 8
+     %uint_0 = OpConstant %uint 0
+      %v4int = OpTypeVector %int 4
+   %uint_255 = OpConstant %uint 255
+     %uint_2 = OpConstant %uint 2
+         %31 = OpTypeFunction %void
+        %foo = OpFunction %void None %8
+         %in = OpFunctionParameter %uint
+          %9 = OpLabel
+         %11 = OpCompositeConstruct %v4uint %uint_24 %uint_16 %uint_8 %uint_0
+         %16 = OpCompositeConstruct %v4uint %in %in %in %in
+         %17 = OpShiftLeftLogical %v4uint %16 %11
+         %19 = OpBitcast %v4int %17
+         %20 = OpCompositeConstruct %v4uint %uint_24 %uint_24 %uint_24 %uint_24
+          %x = OpShiftRightArithmetic %v4int %19 %20
+         %22 = OpCompositeConstruct %v4uint %uint_0 %uint_8 %uint_16 %uint_24
+         %23 = OpCompositeConstruct %v4uint %in %in %in %in
+         %24 = OpShiftRightLogical %v4uint %23 %22
+         %25 = OpCompositeConstruct %v4uint %uint_255 %uint_255 %uint_255 %uint_255
+          %y = OpBitwiseAnd %v4uint %24 %25
+          %z = OpAtomicLoad %int %a %uint_2 %uint_0
+               OpReturn
+               OpFunctionEnd
+%unused_entry_point = OpFunction %void None %31
+         %32 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/bug/tint/399696817.wgsl.expected.wgsl b/test/tint/bug/tint/399696817.wgsl.expected.wgsl
new file mode 100644
index 0000000..f2d0bad
--- /dev/null
+++ b/test/tint/bug/tint/399696817.wgsl.expected.wgsl
@@ -0,0 +1,7 @@
+var<workgroup> a : atomic<i32>;
+
+fn foo(in : u32) {
+  let x = unpack4xI8(in);
+  let y = unpack4xU8(in);
+  let z = atomicLoad(&(a));
+}