[spirv-reader][ir] Better gl_PerVertex handling.

In the case where we've skipped emitting certain variables to the
gl_PerVertex structure, we need to fail on any use of the structure
which is not an `access` as all the members may not be present.

Bug: 42250952
Change-Id: I33e678f680e14f64f4d54da375feccd9ea769977
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/222014
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.cc b/src/tint/lang/spirv/reader/lower/shader_io.cc
index ddff8a4..4e64e64 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io.cc
@@ -196,9 +196,12 @@
             auto var_attributes = var->Attributes();
             auto var_type = var->Result(0)->Type()->UnwrapPtr();
             if (auto* str = var_type->As<core::type::Struct>()) {
+                bool skipped_member_emission = false;
+
                 // Add an output for each member of the struct.
                 for (auto* member : str->Members()) {
                     if (ShouldSkipMemberEmission(var, member)) {
+                        skipped_member_emission = true;
                         continue;
                     }
 
@@ -221,6 +224,15 @@
                         results.Push(b.Load(access)->Result(0));
                     });
                 }
+
+                // If we skipped emission of any member, then we need to make sure the var is only
+                // used through `access` instructions, otherwise the members may no longer match due
+                // to the skipping.
+                if (skipped_member_emission) {
+                    for (auto& usage : var->Result(0)->UsagesUnsorted()) {
+                        TINT_ASSERT(usage->instruction->Is<core::ir::Access>());
+                    }
+                }
             } else {
                 // Load the final result from the original variable.
                 b.Append(wrapper->Block(), [&] {
@@ -305,9 +317,7 @@
             if (!chain) {
                 continue;
             }
-            if (chain->Indices().IsEmpty()) {
-                continue;
-            }
+            TINT_ASSERT(chain->Indices().Length() >= 1);
 
             // A member access has to be a constant index
             auto* cnst = chain->Indices()[0]->As<core::ir::Constant>();