[tint][ir] Validate store target type

Change-Id: Ic6e959be594c43bd3c5a5b3096786899a2b52558
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/168260
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index e0c73e1..8bd498f 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -903,9 +903,13 @@
 
     if (auto* from = s->From()) {
         if (auto* to = s->To()) {
-            if (from->Type() != to->Type()->UnwrapPtr()) {
-                AddError(s, Store::kFromOperandOffset,
-                         "value type does not match pointer element type");
+            auto* mv = to->Type()->As<core::type::MemoryView>();
+            if (!mv) {
+                AddError(s, Store::kFromOperandOffset, "store target operand is not a memory view");
+                return;
+            }
+            if (from->Type() != mv->StoreType()) {
+                AddError(s, Store::kFromOperandOffset, "value type does not match store type");
             }
         }
     }
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 7a084a3..63fff6d 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -2933,6 +2933,37 @@
 )");
 }
 
+TEST_F(IR_ValidatorTest, Store_TargetNotMemoryView) {
+    auto* f = b.Function("my_func", ty.void_());
+
+    b.Append(f->Block(), [&] {
+        auto* let = b.Let("l", 1_i);
+        b.Append(mod.instructions.Create<ir::Store>(let->Result(0), b.Constant(42_u)));
+        b.Return(f);
+    });
+
+    auto res = ir::Validate(mod);
+    ASSERT_NE(res, Success);
+    EXPECT_EQ(res.Failure().reason.str(),
+              R"(:4:15 error: store target operand is not a memory view
+    store %l, 42u
+              ^^^
+
+:2:3 note: In block
+  %b1 = block {
+  ^^^^^^^^^^^
+
+note: # Disassembly
+%my_func = func():void -> %b1 {
+  %b1 = block {
+    %l:i32 = let 1i
+    store %l, 42u
+    ret
+  }
+}
+)");
+}
+
 TEST_F(IR_ValidatorTest, Store_TypeMismatch) {
     auto* f = b.Function("my_func", ty.void_());
 
@@ -2945,7 +2976,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_EQ(res.Failure().reason.str(),
-              R"(:4:15 error: value type does not match pointer element type
+              R"(:4:15 error: value type does not match store type
     store %2, 42u
               ^^^