Tint: Refactor transform VertexPulling and its unit tests

This CL prepare transform VertexPulling and its unit tests for
implementing f16 pipeline io. This CL distinguishes vertex format type
and WGSL variable type of a vertex shader attribute (location input) in
VertexPuilling transform as both `f32` and `f16` WGSL types would be
mapepd to float vertex format. This CL splits VertexPulling unit tests
by base veretx format (SInt, UInt and Float), make it easier to add
`f16` tests.

Bugs: tint:1473, tint:1502
Change-Id: I649deb61e8eb8dac6ebd653bf77ef96475334a56
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112520
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index d5ee424..0196002 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -34,32 +34,23 @@
 
 namespace {
 
-/// The base type of a component.
+/// The base WGSL type of a component.
 /// The format type is either this type or a vector of this type.
-enum class BaseType {
+enum class BaseWGSLType {
     kInvalid,
     kU32,
     kI32,
     kF32,
 };
 
-/// Writes the BaseType to the std::ostream.
-/// @param out the std::ostream to write to
-/// @param format the BaseType to write
-/// @returns out so calls can be chained
-std::ostream& operator<<(std::ostream& out, BaseType format) {
-    switch (format) {
-        case BaseType::kInvalid:
-            return out << "invalid";
-        case BaseType::kU32:
-            return out << "u32";
-        case BaseType::kI32:
-            return out << "i32";
-        case BaseType::kF32:
-            return out << "f32";
-    }
-    return out << "<unknown>";
-}
+/// The data type of a vertex format.
+/// The format type is either this type or a vector of this type.
+enum class VertexDataType {
+    kInvalid,
+    kUInt,   // unsigned int
+    kSInt,   // signed int
+    kFloat,  // unsigned normalized, signed normalized, and float
+};
 
 /// Writes the VertexFormat to the std::ostream.
 /// @param out the std::ostream to write to
@@ -131,74 +122,94 @@
     return out << "<unknown>";
 }
 
-/// A vertex attribute data format.
-struct DataType {
-    BaseType base_type;
+/// Type information of a vertex input attribute.
+struct AttributeWGSLType {
+    BaseWGSLType base_type;
     uint32_t width;  // 1 for scalar, 2+ for a vector
 };
 
-DataType DataTypeOf(const sem::Type* ty) {
-    if (ty->Is<sem::I32>()) {
-        return {BaseType::kI32, 1};
+/// Type information of a vertex format.
+struct VertexFormatType {
+    VertexDataType base_type;
+    uint32_t width;  // 1 for scalar, 2+ for a vector
+};
+
+// Check if base types match between the WGSL variable and the vertex format
+bool IsTypeCompatible(AttributeWGSLType wgslType, VertexFormatType vertexFormatType) {
+    switch (wgslType.base_type) {
+        case BaseWGSLType::kF32:
+            return (vertexFormatType.base_type == VertexDataType::kFloat);
+        case BaseWGSLType::kU32:
+            return (vertexFormatType.base_type == VertexDataType::kUInt);
+        case BaseWGSLType::kI32:
+            return (vertexFormatType.base_type == VertexDataType::kSInt);
+        default:
+            return false;
     }
-    if (ty->Is<sem::U32>()) {
-        return {BaseType::kU32, 1};
-    }
-    if (ty->Is<sem::F32>()) {
-        return {BaseType::kF32, 1};
-    }
-    if (auto* vec = ty->As<sem::Vector>()) {
-        return {DataTypeOf(vec->type()).base_type, vec->Width()};
-    }
-    return {BaseType::kInvalid, 0};
 }
 
-DataType DataTypeOf(VertexFormat format) {
+AttributeWGSLType WGSLTypeOf(const sem::Type* ty) {
+    if (ty->Is<sem::I32>()) {
+        return {BaseWGSLType::kI32, 1};
+    }
+    if (ty->Is<sem::U32>()) {
+        return {BaseWGSLType::kU32, 1};
+    }
+    if (ty->Is<sem::F32>()) {
+        return {BaseWGSLType::kF32, 1};
+    }
+    if (auto* vec = ty->As<sem::Vector>()) {
+        return {WGSLTypeOf(vec->type()).base_type, vec->Width()};
+    }
+    return {BaseWGSLType::kInvalid, 0};
+}
+
+VertexFormatType VertexFormatTypeOf(VertexFormat format) {
     switch (format) {
         case VertexFormat::kUint32:
-            return {BaseType::kU32, 1};
+            return {VertexDataType::kUInt, 1};
         case VertexFormat::kUint8x2:
         case VertexFormat::kUint16x2:
         case VertexFormat::kUint32x2:
-            return {BaseType::kU32, 2};
+            return {VertexDataType::kUInt, 2};
         case VertexFormat::kUint32x3:
-            return {BaseType::kU32, 3};
+            return {VertexDataType::kUInt, 3};
         case VertexFormat::kUint8x4:
         case VertexFormat::kUint16x4:
         case VertexFormat::kUint32x4:
-            return {BaseType::kU32, 4};
+            return {VertexDataType::kUInt, 4};
         case VertexFormat::kSint32:
-            return {BaseType::kI32, 1};
+            return {VertexDataType::kSInt, 1};
         case VertexFormat::kSint8x2:
         case VertexFormat::kSint16x2:
         case VertexFormat::kSint32x2:
-            return {BaseType::kI32, 2};
+            return {VertexDataType::kSInt, 2};
         case VertexFormat::kSint32x3:
-            return {BaseType::kI32, 3};
+            return {VertexDataType::kSInt, 3};
         case VertexFormat::kSint8x4:
         case VertexFormat::kSint16x4:
         case VertexFormat::kSint32x4:
-            return {BaseType::kI32, 4};
+            return {VertexDataType::kSInt, 4};
         case VertexFormat::kFloat32:
-            return {BaseType::kF32, 1};
+            return {VertexDataType::kFloat, 1};
         case VertexFormat::kUnorm8x2:
         case VertexFormat::kSnorm8x2:
         case VertexFormat::kUnorm16x2:
         case VertexFormat::kSnorm16x2:
         case VertexFormat::kFloat16x2:
         case VertexFormat::kFloat32x2:
-            return {BaseType::kF32, 2};
+            return {VertexDataType::kFloat, 2};
         case VertexFormat::kFloat32x3:
-            return {BaseType::kF32, 3};
+            return {VertexDataType::kFloat, 3};
         case VertexFormat::kUnorm8x4:
         case VertexFormat::kSnorm8x4:
         case VertexFormat::kUnorm16x4:
         case VertexFormat::kSnorm16x4:
         case VertexFormat::kFloat16x4:
         case VertexFormat::kFloat32x4:
-            return {BaseType::kF32, 4};
+            return {VertexDataType::kFloat, 4};
     }
-    return {BaseType::kInvalid, 0};
+    return {VertexDataType::kInvalid, 0};
 }
 
 }  // namespace
@@ -350,12 +361,12 @@
                 auto& var = it->second;
 
                 // Data type of the target WGSL variable
-                auto var_dt = DataTypeOf(var.type);
+                auto var_dt = WGSLTypeOf(var.type);
                 // Data type of the vertex stream attribute
-                auto fmt_dt = DataTypeOf(attribute_desc.format);
+                auto fmt_dt = VertexFormatTypeOf(attribute_desc.format);
 
                 // Base types must match between the vertex stream and the WGSL variable
-                if (var_dt.base_type != fmt_dt.base_type) {
+                if (!IsTypeCompatible(var_dt, fmt_dt)) {
                     std::stringstream err;
                     err << "VertexAttributeDescriptor for location "
                         << std::to_string(attribute_desc.shader_location) << " has format "
@@ -365,13 +376,14 @@
                     return nullptr;
                 }
 
-                // Load the attribute value
+                // Load the attribute value according to vertex format and convert the element type
+                // of result to match target WGSL variable. The result of `Fetch` should be of WGSL
+                // types `f32`, `i32`, `u32`, and their vectors.
                 auto* fetch = Fetch(buffer_array_base, attribute_desc.offset, buffer_idx,
                                     attribute_desc.format);
 
-                // The attribute value may not be of the desired vector width. If it is
-                // not, we'll need to either reduce the width with a swizzle, or append
-                // 0's and / or a 1.
+                // The attribute value may not be of the desired vector width. If it is not, we'll
+                // need to either reduce the width with a swizzle, or append 0's and / or a 1.
                 auto* value = fetch;
                 if (var_dt.width < fmt_dt.width) {
                     // WGSL variable vector width is smaller than the loaded vector width
@@ -390,33 +402,26 @@
                             return nullptr;
                     }
                 } else if (var_dt.width > fmt_dt.width) {
-                    // WGSL variable vector width is wider than the loaded vector width
-                    const ast::Type* ty = nullptr;
+                    // WGSL variable vector width is wider than the loaded vector width, do padding.
+
+                    // The components of result vector variable, initialized with type-converted
+                    // loaded data vector.
                     utils::Vector<const ast::Expression*, 8> values{fetch};
-                    switch (var_dt.base_type) {
-                        case BaseType::kI32:
-                            ty = b.ty.i32();
-                            for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
-                                values.Push(b.Expr((i == 3) ? 1_i : 0_i));
-                            }
-                            break;
-                        case BaseType::kU32:
-                            ty = b.ty.u32();
-                            for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
-                                values.Push(b.Expr((i == 3) ? 1_u : 0_u));
-                            }
-                            break;
-                        case BaseType::kF32:
-                            ty = b.ty.f32();
-                            for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
-                                values.Push(b.Expr((i == 3) ? 1_f : 0_f));
-                            }
-                            break;
-                        default:
-                            TINT_UNREACHABLE(Transform, b.Diagnostics()) << var_dt.base_type;
-                            return nullptr;
+
+                    // Add padding elements. The result must be of vector types of signed/unsigned
+                    // integer or float, so use the abstract integer or abstract float value to do
+                    // padding.
+                    for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
+                        if (var_dt.base_type == BaseWGSLType::kI32 ||
+                            var_dt.base_type == BaseWGSLType::kU32) {
+                            values.Push(b.Expr((i == 3) ? 1_a : 0_a));
+                        } else {
+                            values.Push(b.Expr((i == 3) ? 1.0_a : 0.0_a));
+                        }
                     }
-                    value = b.Construct(b.ty.vec(ty, var_dt.width), values);
+
+                    const ast::Type* target_ty = CreateASTTypeFor(ctx, var.type);
+                    value = b.Construct(target_ty, values);
                 }
 
                 // Assign the value to the WGSL variable
@@ -431,12 +436,14 @@
         return b.Block(std::move(stmts));
     }
 
-    /// Generates an expression reading from a buffer a specific format.
+    /// Generates an expression reading a specific vertex format from a buffer. Any vertex format of
+    /// signed normailized, unsigned normailized, or float will result in `f32` or `vecN<f32>` WGSL
+    /// type.
     /// @param array_base the symbol of the variable holding the base array offset
     /// of the vertex array (each index is 4-bytes).
     /// @param offset the byte offset of the data from `buffer_base`
     /// @param buffer the index of the vertex buffer
-    /// @param format the format to read
+    /// @param format the vertex format to read
     const ast::Expression* Fetch(Symbol array_base,
                                  uint32_t offset,
                                  uint32_t buffer,
diff --git a/src/tint/transform/vertex_pulling_test.cc b/src/tint/transform/vertex_pulling_test.cc
index 7c774c5..54c348e 100644
--- a/src/tint/transform/vertex_pulling_test.cc
+++ b/src/tint/transform/vertex_pulling_test.cc
@@ -683,7 +683,7 @@
     EXPECT_EQ(expect, str(got));
 }
 
-TEST_F(VertexPullingTest, FloatVectorAttributes) {
+TEST_F(VertexPullingTest, FloatVectorAttributes_F32) {
     auto* src = R"(
 @vertex
 fn main(@location(0) var_a : vec2<f32>,
@@ -785,40 +785,18 @@
     EXPECT_EQ(expect, str(got));
 }
 
-TEST_F(VertexPullingTest, FormatsAligned) {
+TEST_F(VertexPullingTest, FormatsAligned_SInt) {
     auto* src = R"(
 @vertex
 fn main(
-    @location(0) uint8x2 : vec2<u32>,
-    @location(1) uint8x4 : vec4<u32>,
-    @location(2) sint8x2 : vec2<i32>,
-    @location(3) sint8x4 : vec4<i32>,
-    @location(4) unorm8x2 : vec2<f32>,
-    @location(5) unorm8x4 : vec4<f32>,
-    @location(6) snorm8x2 : vec2<f32>,
-    @location(7) snorm8x4 : vec4<f32>,
-    @location(8) uint16x2 : vec2<u32>,
-    @location(9) uint16x4 : vec4<u32>,
-    @location(10) sint16x2 : vec2<i32>,
-    @location(11) sint16x4 : vec4<i32>,
-    @location(12) unorm16x2 : vec2<f32>,
-    @location(13) unorm16x4 : vec4<f32>,
-    @location(14) snorm16x2 : vec2<f32>,
-    @location(15) snorm16x4 : vec4<f32>,
-    @location(16) float16x2 : vec2<f32>,
-    @location(17) float16x4 : vec4<f32>,
-    @location(18) float32 : f32,
-    @location(19) float32x2 : vec2<f32>,
-    @location(20) float32x3 : vec3<f32>,
-    @location(21) float32x4 : vec4<f32>,
-    @location(22) uint32 : u32,
-    @location(23) uint32x2 : vec2<u32>,
-    @location(24) uint32x3 : vec3<u32>,
-    @location(25) uint32x4 : vec4<u32>,
-    @location(26) sint32 : i32,
-    @location(27) sint32x2 : vec2<i32>,
-    @location(28) sint32x3 : vec3<i32>,
-    @location(29) sint32x4 : vec4<i32>
+    @location(0) sint8x2 : vec2<i32>,
+    @location(1) sint8x4 : vec4<i32>,
+    @location(2) sint16x2 : vec2<i32>,
+    @location(3) sint16x4 : vec4<i32>,
+    @location(4) sint32 : i32,
+    @location(5) sint32x2 : vec2<i32>,
+    @location(6) sint32x3 : vec3<i32>,
+    @location(7) sint32x4 : vec4<i32>
   ) -> @builtin(position) vec4<f32> {
   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
 }
@@ -833,64 +811,20 @@
 
 @vertex
 fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
-  var uint8x2 : vec2<u32>;
-  var uint8x4 : vec4<u32>;
   var sint8x2 : vec2<i32>;
   var sint8x4 : vec4<i32>;
-  var unorm8x2 : vec2<f32>;
-  var unorm8x4 : vec4<f32>;
-  var snorm8x2 : vec2<f32>;
-  var snorm8x4 : vec4<f32>;
-  var uint16x2 : vec2<u32>;
-  var uint16x4 : vec4<u32>;
   var sint16x2 : vec2<i32>;
   var sint16x4 : vec4<i32>;
-  var unorm16x2 : vec2<f32>;
-  var unorm16x4 : vec4<f32>;
-  var snorm16x2 : vec2<f32>;
-  var snorm16x4 : vec4<f32>;
-  var float16x2 : vec2<f32>;
-  var float16x4 : vec4<f32>;
-  var float32 : f32;
-  var float32x2 : vec2<f32>;
-  var float32x3 : vec3<f32>;
-  var float32x4 : vec4<f32>;
-  var uint32 : u32;
-  var uint32x2 : vec2<u32>;
-  var uint32x3 : vec3<u32>;
-  var uint32x4 : vec4<u32>;
   var sint32 : i32;
   var sint32x2 : vec2<i32>;
   var sint32x3 : vec3<i32>;
   var sint32x4 : vec4<i32>;
   {
     let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
-    uint8x2 = ((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
-    uint8x4 = ((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
     sint8x2 = ((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
     sint8x4 = ((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
-    unorm8x2 = unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy;
-    unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
-    snorm8x2 = unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy;
-    snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
-    uint16x2 = ((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
-    uint16x4 = ((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
     sint16x2 = ((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
     sint16x4 = ((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
-    unorm16x2 = unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
-    unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
-    snorm16x2 = unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
-    snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
-    float16x2 = unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
-    float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
-    float32 = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
-    float32x2 = vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
-    float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]));
-    float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]));
-    uint32 = tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)];
-    uint32x2 = vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]);
-    uint32x3 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]);
-    uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]);
     sint32 = bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
     sint32x2 = vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
     sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]));
@@ -901,26 +835,18 @@
 )";
 
     VertexPulling::Config cfg;
-    cfg.vertex_state = {
-        {{256,
-          VertexStepMode::kVertex,
-          {
-              {VertexFormat::kUint8x2, 64, 0},    {VertexFormat::kUint8x4, 64, 1},
-              {VertexFormat::kSint8x2, 64, 2},    {VertexFormat::kSint8x4, 64, 3},
-              {VertexFormat::kUnorm8x2, 64, 4},   {VertexFormat::kUnorm8x4, 64, 5},
-              {VertexFormat::kSnorm8x2, 64, 6},   {VertexFormat::kSnorm8x4, 64, 7},
-              {VertexFormat::kUint16x2, 64, 8},   {VertexFormat::kUint16x4, 64, 9},
-              {VertexFormat::kSint16x2, 64, 10},  {VertexFormat::kSint16x4, 64, 11},
-              {VertexFormat::kUnorm16x2, 64, 12}, {VertexFormat::kUnorm16x4, 64, 13},
-              {VertexFormat::kSnorm16x2, 64, 14}, {VertexFormat::kSnorm16x4, 64, 15},
-              {VertexFormat::kFloat16x2, 64, 16}, {VertexFormat::kFloat16x4, 64, 17},
-              {VertexFormat::kFloat32, 64, 18},   {VertexFormat::kFloat32x2, 64, 19},
-              {VertexFormat::kFloat32x3, 64, 20}, {VertexFormat::kFloat32x4, 64, 21},
-              {VertexFormat::kUint32, 64, 22},    {VertexFormat::kUint32x2, 64, 23},
-              {VertexFormat::kUint32x3, 64, 24},  {VertexFormat::kUint32x4, 64, 25},
-              {VertexFormat::kSint32, 64, 26},    {VertexFormat::kSint32x2, 64, 27},
-              {VertexFormat::kSint32x3, 64, 28},  {VertexFormat::kSint32x4, 64, 29},
-          }}}};
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kSint8x2, 64, 0},
+                              {VertexFormat::kSint8x4, 64, 1},
+                              {VertexFormat::kSint16x2, 64, 2},
+                              {VertexFormat::kSint16x4, 64, 3},
+                              {VertexFormat::kSint32, 64, 4},
+                              {VertexFormat::kSint32x2, 64, 5},
+                              {VertexFormat::kSint32x3, 64, 6},
+                              {VertexFormat::kSint32x4, 64, 7},
+                          }}}};
 
     DataMap data;
     data.Add<VertexPulling::Config>(cfg);
@@ -929,185 +855,18 @@
     EXPECT_EQ(expect, str(got));
 }
 
-TEST_F(VertexPullingTest, FormatsStrideUnaligned) {
+TEST_F(VertexPullingTest, FormatsAligned_UInt) {
     auto* src = R"(
 @vertex
 fn main(
     @location(0) uint8x2 : vec2<u32>,
     @location(1) uint8x4 : vec4<u32>,
-    @location(2) sint8x2 : vec2<i32>,
-    @location(3) sint8x4 : vec4<i32>,
-    @location(4) unorm8x2 : vec2<f32>,
-    @location(5) unorm8x4 : vec4<f32>,
-    @location(6) snorm8x2 : vec2<f32>,
-    @location(7) snorm8x4 : vec4<f32>,
-    @location(8) uint16x2 : vec2<u32>,
-    @location(9) uint16x4 : vec4<u32>,
-    @location(10) sint16x2 : vec2<i32>,
-    @location(11) sint16x4 : vec4<i32>,
-    @location(12) unorm16x2 : vec2<f32>,
-    @location(13) unorm16x4 : vec4<f32>,
-    @location(14) snorm16x2 : vec2<f32>,
-    @location(15) snorm16x4 : vec4<f32>,
-    @location(16) float16x2 : vec2<f32>,
-    @location(17) float16x4 : vec4<f32>,
-    @location(18) float32 : f32,
-    @location(19) float32x2 : vec2<f32>,
-    @location(20) float32x3 : vec3<f32>,
-    @location(21) float32x4 : vec4<f32>,
-    @location(22) uint32 : u32,
-    @location(23) uint32x2 : vec2<u32>,
-    @location(24) uint32x3 : vec3<u32>,
-    @location(25) uint32x4 : vec4<u32>,
-    @location(26) sint32 : i32,
-    @location(27) sint32x2 : vec2<i32>,
-    @location(28) sint32x3 : vec3<i32>,
-    @location(29) sint32x4 : vec4<i32>
-  ) -> @builtin(position) vec4<f32> {
-  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
-}
-)";
-
-    auto* expect =
-        R"(
-struct TintVertexData {
-  tint_vertex_data : array<u32>,
-}
-
-@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
-
-@vertex
-fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
-  var uint8x2 : vec2<u32>;
-  var uint8x4 : vec4<u32>;
-  var sint8x2 : vec2<i32>;
-  var sint8x4 : vec4<i32>;
-  var unorm8x2 : vec2<f32>;
-  var unorm8x4 : vec4<f32>;
-  var snorm8x2 : vec2<f32>;
-  var snorm8x4 : vec4<f32>;
-  var uint16x2 : vec2<u32>;
-  var uint16x4 : vec4<u32>;
-  var sint16x2 : vec2<i32>;
-  var sint16x4 : vec4<i32>;
-  var unorm16x2 : vec2<f32>;
-  var unorm16x4 : vec4<f32>;
-  var snorm16x2 : vec2<f32>;
-  var snorm16x4 : vec4<f32>;
-  var float16x2 : vec2<f32>;
-  var float16x4 : vec4<f32>;
-  var float32 : f32;
-  var float32x2 : vec2<f32>;
-  var float32x3 : vec3<f32>;
-  var float32x4 : vec4<f32>;
-  var uint32 : u32;
-  var uint32x2 : vec2<u32>;
-  var uint32x3 : vec3<u32>;
-  var uint32x4 : vec4<u32>;
-  var sint32 : i32;
-  var sint32x2 : vec2<i32>;
-  var sint32x3 : vec3<i32>;
-  var sint32x4 : vec4<i32>;
-  {
-    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
-    uint8x2 = ((vec2<u32>((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 8u)) & 4294901760u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
-    uint8x4 = ((vec4<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
-    sint8x2 = ((vec2<i32>(bitcast<i32>((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 8u)) & 4294901760u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
-    sint8x4 = ((vec4<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)))) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
-    unorm8x2 = unpack4x8unorm((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u)) & 65535u)).xy;
-    unorm8x4 = unpack4x8unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    snorm8x2 = unpack4x8snorm((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u)) & 65535u)).xy;
-    snorm8x4 = unpack4x8snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    uint16x2 = ((vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
-    uint16x4 = ((vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
-    sint16x2 = ((vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)))) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
-    sint16x4 = ((vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)))).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
-    unorm16x2 = unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    unorm16x4 = vec4<f32>(unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
-    snorm16x2 = unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    snorm16x4 = vec4<f32>(unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
-    float16x2 = unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    float16x4 = vec4<f32>(unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
-    float32 = bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    float32x2 = vec2<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
-    float32x3 = vec3<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))));
-    float32x4 = vec4<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u))));
-    uint32 = ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u));
-    uint32x2 = vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)));
-    uint32x3 = vec3<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u)));
-    uint32x4 = vec4<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u)));
-    sint32 = bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
-    sint32x2 = vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
-    sint32x3 = vec3<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))));
-    sint32x4 = vec4<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u))));
-  }
-  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
-}
-)";
-
-    VertexPulling::Config cfg;
-    cfg.vertex_state = {
-        {{256,
-          VertexStepMode::kVertex,
-          {
-              {VertexFormat::kUint8x2, 63, 0},    {VertexFormat::kUint8x4, 63, 1},
-              {VertexFormat::kSint8x2, 63, 2},    {VertexFormat::kSint8x4, 63, 3},
-              {VertexFormat::kUnorm8x2, 63, 4},   {VertexFormat::kUnorm8x4, 63, 5},
-              {VertexFormat::kSnorm8x2, 63, 6},   {VertexFormat::kSnorm8x4, 63, 7},
-              {VertexFormat::kUint16x2, 63, 8},   {VertexFormat::kUint16x4, 63, 9},
-              {VertexFormat::kSint16x2, 63, 10},  {VertexFormat::kSint16x4, 63, 11},
-              {VertexFormat::kUnorm16x2, 63, 12}, {VertexFormat::kUnorm16x4, 63, 13},
-              {VertexFormat::kSnorm16x2, 63, 14}, {VertexFormat::kSnorm16x4, 63, 15},
-              {VertexFormat::kFloat16x2, 63, 16}, {VertexFormat::kFloat16x4, 63, 17},
-              {VertexFormat::kFloat32, 63, 18},   {VertexFormat::kFloat32x2, 63, 19},
-              {VertexFormat::kFloat32x3, 63, 20}, {VertexFormat::kFloat32x4, 63, 21},
-              {VertexFormat::kUint32, 63, 22},    {VertexFormat::kUint32x2, 63, 23},
-              {VertexFormat::kUint32x3, 63, 24},  {VertexFormat::kUint32x4, 63, 25},
-              {VertexFormat::kSint32, 63, 26},    {VertexFormat::kSint32x2, 63, 27},
-              {VertexFormat::kSint32x3, 63, 28},  {VertexFormat::kSint32x4, 63, 29},
-          }}}};
-
-    DataMap data;
-    data.Add<VertexPulling::Config>(cfg);
-    auto got = Run<VertexPulling>(src, data);
-
-    EXPECT_EQ(expect, str(got));
-}
-
-TEST_F(VertexPullingTest, FormatsWithVectorsResized) {
-    auto* src = R"(
-@vertex
-fn main(
-    @location(0) uint8x2 : vec3<u32>,
-    @location(1) uint8x4 : vec2<u32>,
-    @location(2) sint8x2 : i32,
-    @location(3) sint8x4 : vec2<i32>,
-    @location(4) unorm8x2 : vec4<f32>,
-    @location(5) unorm8x4 : f32,
-    @location(6) snorm8x2 : vec3<f32>,
-    @location(7) snorm8x4 : f32,
-    @location(8) uint16x2 : vec3<u32>,
-    @location(9) uint16x4 : vec2<u32>,
-    @location(10) sint16x2 : vec4<i32>,
-    @location(11) sint16x4 : i32,
-    @location(12) unorm16x2 : vec3<f32>,
-    @location(13) unorm16x4 : f32,
-    @location(14) snorm16x2 : vec4<f32>,
-    @location(15) snorm16x4 : vec3<f32>,
-    @location(16) float16x2 : vec4<f32>,
-    @location(17) float16x4 : f32,
-    @location(18) float32 : vec4<f32>,
-    @location(19) float32x2 : vec4<f32>,
-    @location(20) float32x3 : vec2<f32>,
-    @location(21) float32x4 : vec3<f32>,
-    @location(22) uint32 : vec3<u32>,
-    @location(23) uint32x2 : vec4<u32>,
-    @location(24) uint32x3 : vec4<u32>,
-    @location(25) uint32x4 : vec2<u32>,
-    @location(26) sint32 : vec4<i32>,
-    @location(27) sint32x2 : vec3<i32>,
-    @location(28) sint32x3 : i32,
-    @location(29) sint32x4 : vec2<i32>
+    @location(2) uint16x2 : vec2<u32>,
+    @location(3) uint16x4 : vec4<u32>,
+    @location(4) uint32 : u32,
+    @location(5) uint32x2 : vec2<u32>,
+    @location(6) uint32x3 : vec3<u32>,
+    @location(7) uint32x4 : vec4<u32>,
   ) -> @builtin(position) vec4<f32> {
   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
 }
@@ -1122,68 +881,922 @@
 
 @vertex
 fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
-  var uint8x2 : vec3<u32>;
-  var uint8x4 : vec2<u32>;
-  var sint8x2 : i32;
-  var sint8x4 : vec2<i32>;
-  var unorm8x2 : vec4<f32>;
-  var unorm8x4 : f32;
-  var snorm8x2 : vec3<f32>;
-  var snorm8x4 : f32;
-  var uint16x2 : vec3<u32>;
-  var uint16x4 : vec2<u32>;
-  var sint16x2 : vec4<i32>;
-  var sint16x4 : i32;
-  var unorm16x2 : vec3<f32>;
-  var unorm16x4 : f32;
-  var snorm16x2 : vec4<f32>;
-  var snorm16x4 : vec3<f32>;
-  var float16x2 : vec4<f32>;
-  var float16x4 : f32;
-  var float32 : vec4<f32>;
-  var float32x2 : vec4<f32>;
-  var float32x3 : vec2<f32>;
-  var float32x4 : vec3<f32>;
-  var uint32 : vec3<u32>;
-  var uint32x2 : vec4<u32>;
-  var uint32x3 : vec4<u32>;
-  var uint32x4 : vec2<u32>;
-  var sint32 : vec4<i32>;
-  var sint32x2 : vec3<i32>;
-  var sint32x3 : i32;
-  var sint32x4 : vec2<i32>;
+  var uint8x2 : vec2<u32>;
+  var uint8x4 : vec4<u32>;
+  var uint16x2 : vec2<u32>;
+  var uint16x4 : vec4<u32>;
+  var uint32 : u32;
+  var uint32x2 : vec2<u32>;
+  var uint32x3 : vec3<u32>;
+  var uint32x4 : vec4<u32>;
   {
     let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
-    uint8x2 = vec3<u32>(((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u)), 0u);
-    uint8x4 = (((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy;
-    sint8x2 = (((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u))).x;
-    sint8x4 = (((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy;
-    unorm8x2 = vec4<f32>(unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0f, 1.0f);
-    unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
-    snorm8x2 = vec3<f32>(unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0f);
-    snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
-    uint16x2 = vec3<u32>(((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0u);
-    uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xy;
-    sint16x2 = vec4<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0i, 1i);
-    sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).x;
-    unorm16x2 = vec3<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f);
-    unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
-    snorm16x2 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f, 1.0f);
-    snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xyz;
-    float16x2 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f, 1.0f);
-    float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
-    float32 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f, 0.0f, 1.0f);
-    float32x2 = vec4<f32>(vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0.0f, 1.0f);
-    float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).xy;
-    float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xyz;
-    uint32 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], 0u, 0u);
-    uint32x2 = vec4<u32>(vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), 0u, 1u);
-    uint32x3 = vec4<u32>(vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), 1u);
-    uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]).xy;
-    sint32 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0i, 0i, 1i);
-    sint32x2 = vec3<i32>(vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0i);
-    sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).x;
-    sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xy;
+    uint8x2 = ((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
+    uint8x4 = ((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
+    uint16x2 = ((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
+    uint16x4 = ((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
+    uint32 = tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)];
+    uint32x2 = vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]);
+    uint32x3 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]);
+    uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]);
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUint8x2, 64, 0},
+                              {VertexFormat::kUint8x4, 64, 1},
+                              {VertexFormat::kUint16x2, 64, 2},
+                              {VertexFormat::kUint16x4, 64, 3},
+                              {VertexFormat::kUint32, 64, 4},
+                              {VertexFormat::kUint32x2, 64, 5},
+                              {VertexFormat::kUint32x3, 64, 6},
+                              {VertexFormat::kUint32x4, 64, 7},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsAligned_Float_F32) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0) unorm8x2 : vec2<f32>,
+    @location(1) unorm8x4 : vec4<f32>,
+    @location(2) snorm8x2 : vec2<f32>,
+    @location(3) snorm8x4 : vec4<f32>,
+    @location(4) unorm16x2 : vec2<f32>,
+    @location(5) unorm16x4 : vec4<f32>,
+    @location(6) snorm16x2 : vec2<f32>,
+    @location(7) snorm16x4 : vec4<f32>,
+    @location(8) float16x2 : vec2<f32>,
+    @location(9) float16x4 : vec4<f32>,
+    @location(10) float32 : f32,
+    @location(11) float32x2 : vec2<f32>,
+    @location(12) float32x3 : vec3<f32>,
+    @location(13) float32x4 : vec4<f32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var unorm8x2 : vec2<f32>;
+  var unorm8x4 : vec4<f32>;
+  var snorm8x2 : vec2<f32>;
+  var snorm8x4 : vec4<f32>;
+  var unorm16x2 : vec2<f32>;
+  var unorm16x4 : vec4<f32>;
+  var snorm16x2 : vec2<f32>;
+  var snorm16x4 : vec4<f32>;
+  var float16x2 : vec2<f32>;
+  var float16x4 : vec4<f32>;
+  var float32 : f32;
+  var float32x2 : vec2<f32>;
+  var float32x3 : vec3<f32>;
+  var float32x4 : vec4<f32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    unorm8x2 = unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy;
+    unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
+    snorm8x2 = unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy;
+    snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
+    unorm16x2 = unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
+    unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
+    snorm16x2 = unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
+    snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
+    float16x2 = unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
+    float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
+    float32 = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]);
+    float32x2 = vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
+    float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]));
+    float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]));
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUnorm8x2, 64, 0},
+                              {VertexFormat::kUnorm8x4, 64, 1},
+                              {VertexFormat::kSnorm8x2, 64, 2},
+                              {VertexFormat::kSnorm8x4, 64, 3},
+                              {VertexFormat::kUnorm16x2, 64, 4},
+                              {VertexFormat::kUnorm16x4, 64, 5},
+                              {VertexFormat::kSnorm16x2, 64, 6},
+                              {VertexFormat::kSnorm16x4, 64, 7},
+                              {VertexFormat::kFloat16x2, 64, 8},
+                              {VertexFormat::kFloat16x4, 64, 9},
+                              {VertexFormat::kFloat32, 64, 10},
+                              {VertexFormat::kFloat32x2, 64, 11},
+                              {VertexFormat::kFloat32x3, 64, 12},
+                              {VertexFormat::kFloat32x4, 64, 13},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsUnaligned_SInt) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0) sint8x2 : vec2<i32>,
+    @location(1) sint8x4 : vec4<i32>,
+    @location(2) sint16x2 : vec2<i32>,
+    @location(3) sint16x4 : vec4<i32>,
+    @location(4) sint32 : i32,
+    @location(5) sint32x2 : vec2<i32>,
+    @location(6) sint32x3 : vec3<i32>,
+    @location(7) sint32x4 : vec4<i32>
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var sint8x2 : vec2<i32>;
+  var sint8x4 : vec4<i32>;
+  var sint16x2 : vec2<i32>;
+  var sint16x4 : vec4<i32>;
+  var sint32 : i32;
+  var sint32x2 : vec2<i32>;
+  var sint32x3 : vec3<i32>;
+  var sint32x4 : vec4<i32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    sint8x2 = ((vec2<i32>(bitcast<i32>((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 8u)) & 4294901760u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
+    sint8x4 = ((vec4<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)))) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
+    sint16x2 = ((vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)))) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
+    sint16x4 = ((vec2<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)))).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
+    sint32 = bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    sint32x2 = vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]));
+    sint32x3 = vec3<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))));
+    sint32x4 = vec4<i32>(bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))), bitcast<i32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u))));
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kSint8x2, 63, 0},
+                              {VertexFormat::kSint8x4, 63, 1},
+                              {VertexFormat::kSint16x2, 63, 2},
+                              {VertexFormat::kSint16x4, 63, 3},
+                              {VertexFormat::kSint32, 63, 4},
+                              {VertexFormat::kSint32x2, 64, 5},
+                              {VertexFormat::kSint32x3, 63, 6},
+                              {VertexFormat::kSint32x4, 63, 7},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsUnaligned_UInt) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0) uint8x2 : vec2<u32>,
+    @location(1) uint8x4 : vec4<u32>,
+    @location(2) uint16x2 : vec2<u32>,
+    @location(3) uint16x4 : vec4<u32>,
+    @location(4) uint32 : u32,
+    @location(5) uint32x2 : vec2<u32>,
+    @location(6) uint32x3 : vec3<u32>,
+    @location(7) uint32x4 : vec4<u32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var uint8x2 : vec2<u32>;
+  var uint8x4 : vec4<u32>;
+  var uint16x2 : vec2<u32>;
+  var uint16x4 : vec4<u32>;
+  var uint32 : u32;
+  var uint32x2 : vec2<u32>;
+  var uint32x3 : vec3<u32>;
+  var uint32x4 : vec4<u32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    uint8x2 = ((vec2<u32>((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 8u)) & 4294901760u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u));
+    uint8x4 = ((vec4<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u));
+    uint16x2 = ((vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u));
+    uint16x4 = ((vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u));
+    uint32 = ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u));
+    uint32x2 = vec2<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)));
+    uint32x3 = vec3<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u)));
+    uint32x4 = vec4<u32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u)), ((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u)));
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUint8x2, 63, 0},
+                              {VertexFormat::kUint8x4, 63, 1},
+                              {VertexFormat::kUint16x2, 63, 2},
+                              {VertexFormat::kUint16x4, 63, 3},
+                              {VertexFormat::kUint32, 63, 4},
+                              {VertexFormat::kUint32x2, 63, 5},
+                              {VertexFormat::kUint32x3, 63, 6},
+                              {VertexFormat::kUint32x4, 63, 7},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsUnaligned_Float_F32) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0) unorm8x2 : vec2<f32>,
+    @location(1) unorm8x4 : vec4<f32>,
+    @location(2) snorm8x2 : vec2<f32>,
+    @location(3) snorm8x4 : vec4<f32>,
+    @location(4) unorm16x2 : vec2<f32>,
+    @location(5) unorm16x4 : vec4<f32>,
+    @location(6) snorm16x2 : vec2<f32>,
+    @location(7) snorm16x4 : vec4<f32>,
+    @location(8) float16x2 : vec2<f32>,
+    @location(9) float16x4 : vec4<f32>,
+    @location(10) float32 : f32,
+    @location(11) float32x2 : vec2<f32>,
+    @location(12) float32x3 : vec3<f32>,
+    @location(13) float32x4 : vec4<f32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var unorm8x2 : vec2<f32>;
+  var unorm8x4 : vec4<f32>;
+  var snorm8x2 : vec2<f32>;
+  var snorm8x4 : vec4<f32>;
+  var unorm16x2 : vec2<f32>;
+  var unorm16x4 : vec4<f32>;
+  var snorm16x2 : vec2<f32>;
+  var snorm16x4 : vec4<f32>;
+  var float16x2 : vec2<f32>;
+  var float16x4 : vec4<f32>;
+  var float32 : f32;
+  var float32x2 : vec2<f32>;
+  var float32x3 : vec3<f32>;
+  var float32x4 : vec4<f32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    unorm8x2 = unpack4x8unorm((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u)) & 65535u)).xy;
+    unorm8x4 = unpack4x8unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    snorm8x2 = unpack4x8snorm((((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u)) & 65535u)).xy;
+    snorm8x4 = unpack4x8snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    unorm16x2 = unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    unorm16x4 = vec4<f32>(unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16unorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
+    snorm16x2 = unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    snorm16x4 = vec4<f32>(unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16snorm(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
+    float16x2 = unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    float16x4 = vec4<f32>(unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), unpack2x16float(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
+    float32 = bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u)));
+    float32x2 = vec2<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))));
+    float32x3 = vec3<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))));
+    float32x4 = vec4<f32>(bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 15u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] << 8u))), bitcast<f32>(((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)] >> 24u) | (tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)] << 8u))));
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUnorm8x2, 63, 0},
+                              {VertexFormat::kUnorm8x4, 63, 1},
+                              {VertexFormat::kSnorm8x2, 63, 2},
+                              {VertexFormat::kSnorm8x4, 63, 3},
+                              {VertexFormat::kUnorm16x2, 63, 4},
+                              {VertexFormat::kUnorm16x4, 63, 5},
+                              {VertexFormat::kSnorm16x2, 63, 6},
+                              {VertexFormat::kSnorm16x4, 63, 7},
+                              {VertexFormat::kFloat16x2, 63, 8},
+                              {VertexFormat::kFloat16x4, 63, 9},
+                              {VertexFormat::kFloat32, 63, 10},
+                              {VertexFormat::kFloat32x2, 63, 11},
+                              {VertexFormat::kFloat32x3, 63, 12},
+                              {VertexFormat::kFloat32x4, 63, 13},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsWithVectorsResized_Padding_SInt) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0) vec3_sint8x2 :  vec3<i32>,
+    @location(1) vec4_sint8x2 :  vec4<i32>,
+    @location(2) vec3_sint16x2 : vec3<i32>,
+    @location(3) vec4_sint16x2 : vec4<i32>,
+    @location(4) vec2_sint32 :   vec2<i32>,
+    @location(5) vec3_sint32 :   vec3<i32>,
+    @location(6) vec4_sint32 :   vec4<i32>,
+    @location(7) vec3_sint32x2 : vec3<i32>,
+    @location(8) vec4_sint32x2 : vec4<i32>,
+    @location(9) vec4_sint32x3 : vec4<i32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var vec3_sint8x2 : vec3<i32>;
+  var vec4_sint8x2 : vec4<i32>;
+  var vec3_sint16x2 : vec3<i32>;
+  var vec4_sint16x2 : vec4<i32>;
+  var vec2_sint32 : vec2<i32>;
+  var vec3_sint32 : vec3<i32>;
+  var vec4_sint32 : vec4<i32>;
+  var vec3_sint32x2 : vec3<i32>;
+  var vec4_sint32x2 : vec4<i32>;
+  var vec4_sint32x3 : vec4<i32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    vec3_sint8x2 = vec3<i32>(((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u)), 0);
+    vec4_sint8x2 = vec4<i32>(((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u)), 0, 1);
+    vec3_sint16x2 = vec3<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0);
+    vec4_sint16x2 = vec4<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0, 1);
+    vec2_sint32 = vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0);
+    vec3_sint32 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0, 0);
+    vec4_sint32 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0, 0, 1);
+    vec3_sint32x2 = vec3<i32>(vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0);
+    vec4_sint32x2 = vec4<i32>(vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0, 1);
+    vec4_sint32x3 = vec4<i32>(vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])), 1);
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kSint8x2, 64, 0},
+                              {VertexFormat::kSint8x2, 64, 1},
+                              {VertexFormat::kSint16x2, 64, 2},
+                              {VertexFormat::kSint16x2, 64, 3},
+                              {VertexFormat::kSint32, 64, 4},
+                              {VertexFormat::kSint32, 64, 5},
+                              {VertexFormat::kSint32, 64, 6},
+                              {VertexFormat::kSint32x2, 64, 7},
+                              {VertexFormat::kSint32x2, 64, 8},
+                              {VertexFormat::kSint32x3, 64, 9},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsWithVectorsResized_Padding_UInt) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0) vec3_uint8x2 :  vec3<u32>,
+    @location(1) vec4_uint8x2 :  vec4<u32>,
+    @location(2) vec3_uint16x2 : vec3<u32>,
+    @location(3) vec4_uint16x2 : vec4<u32>,
+    @location(4) vec2_uint32 :   vec2<u32>,
+    @location(5) vec3_uint32 :   vec3<u32>,
+    @location(6) vec4_uint32 :   vec4<u32>,
+    @location(7) vec3_uint32x2 : vec3<u32>,
+    @location(8) vec4_uint32x2 : vec4<u32>,
+    @location(9) vec4_uint32x3 : vec4<u32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var vec3_uint8x2 : vec3<u32>;
+  var vec4_uint8x2 : vec4<u32>;
+  var vec3_uint16x2 : vec3<u32>;
+  var vec4_uint16x2 : vec4<u32>;
+  var vec2_uint32 : vec2<u32>;
+  var vec3_uint32 : vec3<u32>;
+  var vec4_uint32 : vec4<u32>;
+  var vec3_uint32x2 : vec3<u32>;
+  var vec4_uint32x2 : vec4<u32>;
+  var vec4_uint32x3 : vec4<u32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    vec3_uint8x2 = vec3<u32>(((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u)), 0);
+    vec4_uint8x2 = vec4<u32>(((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u)), 0, 1);
+    vec3_uint16x2 = vec3<u32>(((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0);
+    vec4_uint16x2 = vec4<u32>(((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0, 1);
+    vec2_uint32 = vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], 0);
+    vec3_uint32 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], 0, 0);
+    vec4_uint32 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], 0, 0, 1);
+    vec3_uint32x2 = vec3<u32>(vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), 0);
+    vec4_uint32x2 = vec4<u32>(vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), 0, 1);
+    vec4_uint32x3 = vec4<u32>(vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), 1);
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUint8x2, 64, 0},
+                              {VertexFormat::kUint8x2, 64, 1},
+                              {VertexFormat::kUint16x2, 64, 2},
+                              {VertexFormat::kUint16x2, 64, 3},
+                              {VertexFormat::kUint32, 64, 4},
+                              {VertexFormat::kUint32, 64, 5},
+                              {VertexFormat::kUint32, 64, 6},
+                              {VertexFormat::kUint32x2, 64, 7},
+                              {VertexFormat::kUint32x2, 64, 8},
+                              {VertexFormat::kUint32x3, 64, 9},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsWithVectorsResized_Padding_Float_F32) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0)  vec3_unorm8x2 :  vec3<f32>,
+    @location(1)  vec4_unorm8x2 :  vec4<f32>,
+    @location(2)  vec3_snorm8x2 :  vec3<f32>,
+    @location(3)  vec4_snorm8x2 :  vec4<f32>,
+    @location(4)  vec3_unorm16x2 : vec3<f32>,
+    @location(5)  vec4_unorm16x2 : vec4<f32>,
+    @location(6)  vec3_snorm16x2 : vec3<f32>,
+    @location(7)  vec4_snorm16x2 : vec4<f32>,
+    @location(8)  vec3_float16x2 : vec3<f32>,
+    @location(9)  vec4_float16x2 : vec4<f32>,
+    @location(10) vec2_float32 :   vec2<f32>,
+    @location(11) vec3_float32 :   vec3<f32>,
+    @location(12) vec4_float32 :   vec4<f32>,
+    @location(13) vec3_float32x2 : vec3<f32>,
+    @location(14) vec4_float32x2 : vec4<f32>,
+    @location(15) vec4_float32x3 : vec4<f32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var vec3_unorm8x2 : vec3<f32>;
+  var vec4_unorm8x2 : vec4<f32>;
+  var vec3_snorm8x2 : vec3<f32>;
+  var vec4_snorm8x2 : vec4<f32>;
+  var vec3_unorm16x2 : vec3<f32>;
+  var vec4_unorm16x2 : vec4<f32>;
+  var vec3_snorm16x2 : vec3<f32>;
+  var vec4_snorm16x2 : vec4<f32>;
+  var vec3_float16x2 : vec3<f32>;
+  var vec4_float16x2 : vec4<f32>;
+  var vec2_float32 : vec2<f32>;
+  var vec3_float32 : vec3<f32>;
+  var vec4_float32 : vec4<f32>;
+  var vec3_float32x2 : vec3<f32>;
+  var vec4_float32x2 : vec4<f32>;
+  var vec4_float32x3 : vec4<f32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    vec3_unorm8x2 = vec3<f32>(unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0);
+    vec4_unorm8x2 = vec4<f32>(unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0, 1.0);
+    vec3_snorm8x2 = vec3<f32>(unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0);
+    vec4_snorm8x2 = vec4<f32>(unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0, 1.0);
+    vec3_unorm16x2 = vec3<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0);
+    vec4_unorm16x2 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0);
+    vec3_snorm16x2 = vec3<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0);
+    vec4_snorm16x2 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0);
+    vec3_float16x2 = vec3<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0);
+    vec4_float16x2 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0);
+    vec2_float32 = vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0);
+    vec3_float32 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 0.0);
+    vec4_float32 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 0.0, 1.0);
+    vec3_float32x2 = vec3<f32>(vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0.0);
+    vec4_float32x2 = vec4<f32>(vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0.0, 1.0);
+    vec4_float32x3 = vec4<f32>(vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])), 1.0);
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUnorm8x2, 64, 0},
+                              {VertexFormat::kUnorm8x2, 64, 1},
+                              {VertexFormat::kSnorm8x2, 64, 2},
+                              {VertexFormat::kSnorm8x2, 64, 3},
+                              {VertexFormat::kUnorm16x2, 64, 4},
+                              {VertexFormat::kUnorm16x2, 64, 5},
+                              {VertexFormat::kSnorm16x2, 64, 6},
+                              {VertexFormat::kSnorm16x2, 64, 7},
+                              {VertexFormat::kFloat16x2, 64, 8},
+                              {VertexFormat::kFloat16x2, 64, 9},
+                              {VertexFormat::kFloat32, 64, 10},
+                              {VertexFormat::kFloat32, 64, 11},
+                              {VertexFormat::kFloat32, 64, 12},
+                              {VertexFormat::kFloat32x2, 64, 13},
+                              {VertexFormat::kFloat32x2, 64, 14},
+                              {VertexFormat::kFloat32x3, 64, 15},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsWithVectorsResized_Shrinking_SInt) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0)  sclr_sint8x2 :       i32 ,
+    @location(1)  sclr_sint8x4 :       i32 ,
+    @location(2)  vec2_sint8x4 :  vec2<i32>,
+    @location(3)  vec3_sint8x4 :  vec3<i32>,
+    @location(4)  sclr_sint16x2 :      i32 ,
+    @location(5)  sclr_sint16x4 :      i32 ,
+    @location(6)  vec2_sint16x4 : vec2<i32>,
+    @location(7)  vec3_sint16x4 : vec3<i32>,
+    @location(8)  sclr_sint32x2 :      i32 ,
+    @location(9)  sclr_sint32x3 :      i32 ,
+    @location(10) vec2_sint32x3 : vec2<i32>,
+    @location(11) sclr_sint32x4 :      i32 ,
+    @location(12) vec2_sint32x4 : vec2<i32>,
+    @location(13) vec3_sint32x4 : vec3<i32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var sclr_sint8x2 : i32;
+  var sclr_sint8x4 : i32;
+  var vec2_sint8x4 : vec2<i32>;
+  var vec3_sint8x4 : vec3<i32>;
+  var sclr_sint16x2 : i32;
+  var sclr_sint16x4 : i32;
+  var vec2_sint16x4 : vec2<i32>;
+  var vec3_sint16x4 : vec3<i32>;
+  var sclr_sint32x2 : i32;
+  var sclr_sint32x3 : i32;
+  var vec2_sint32x3 : vec2<i32>;
+  var sclr_sint32x4 : i32;
+  var vec2_sint32x4 : vec2<i32>;
+  var vec3_sint32x4 : vec3<i32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    sclr_sint8x2 = (((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u))).x;
+    sclr_sint8x4 = (((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).x;
+    vec2_sint8x4 = (((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy;
+    vec3_sint8x4 = (((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xyz;
+    sclr_sint16x2 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u))).x;
+    sclr_sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).x;
+    vec2_sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xy;
+    vec3_sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xyz;
+    sclr_sint32x2 = vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
+    sclr_sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).x;
+    vec2_sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).xy;
+    sclr_sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).x;
+    vec2_sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xy;
+    vec3_sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xyz;
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kSint8x2, 64, 0},
+                              {VertexFormat::kSint8x4, 64, 1},
+                              {VertexFormat::kSint8x4, 64, 2},
+                              {VertexFormat::kSint8x4, 64, 3},
+                              {VertexFormat::kSint16x2, 64, 4},
+                              {VertexFormat::kSint16x4, 64, 5},
+                              {VertexFormat::kSint16x4, 64, 6},
+                              {VertexFormat::kSint16x4, 64, 7},
+                              {VertexFormat::kSint32x2, 64, 8},
+                              {VertexFormat::kSint32x3, 64, 9},
+                              {VertexFormat::kSint32x3, 64, 10},
+                              {VertexFormat::kSint32x4, 64, 11},
+                              {VertexFormat::kSint32x4, 64, 12},
+                              {VertexFormat::kSint32x4, 64, 13},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsWithVectorsResized_Shrinking_UInt) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0)  sclr_uint8x2 :       u32 ,
+    @location(1)  sclr_uint8x4 :       u32 ,
+    @location(2)  vec2_uint8x4 :  vec2<u32>,
+    @location(3)  vec3_uint8x4 :  vec3<u32>,
+    @location(4)  sclr_uint16x2 :      u32 ,
+    @location(5)  sclr_uint16x4 :      u32 ,
+    @location(6)  vec2_uint16x4 : vec2<u32>,
+    @location(7)  vec3_uint16x4 : vec3<u32>,
+    @location(8)  sclr_uint32x2 :      u32 ,
+    @location(9)  sclr_uint32x3 :      u32 ,
+    @location(10) vec2_uint32x3 : vec2<u32>,
+    @location(11) sclr_uint32x4 :      u32 ,
+    @location(12) vec2_uint32x4 : vec2<u32>,
+    @location(13) vec3_uint32x4 : vec3<u32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var sclr_uint8x2 : u32;
+  var sclr_uint8x4 : u32;
+  var vec2_uint8x4 : vec2<u32>;
+  var vec3_uint8x4 : vec3<u32>;
+  var sclr_uint16x2 : u32;
+  var sclr_uint16x4 : u32;
+  var vec2_uint16x4 : vec2<u32>;
+  var vec3_uint16x4 : vec3<u32>;
+  var sclr_uint32x2 : u32;
+  var sclr_uint32x3 : u32;
+  var vec2_uint32x3 : vec2<u32>;
+  var sclr_uint32x4 : u32;
+  var vec2_uint32x4 : vec2<u32>;
+  var vec3_uint32x4 : vec3<u32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    sclr_uint8x2 = (((vec2<u32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u)) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u))).x;
+    sclr_uint8x4 = (((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).x;
+    vec2_uint8x4 = (((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy;
+    vec3_uint8x4 = (((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xyz;
+    sclr_uint16x2 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u))).x;
+    sclr_uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).x;
+    vec2_uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xy;
+    vec3_uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xyz;
+    sclr_uint32x2 = vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).x;
+    sclr_uint32x3 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]).x;
+    vec2_uint32x3 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]).xy;
+    sclr_uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]).x;
+    vec2_uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]).xy;
+    vec3_uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]).xyz;
+  }
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    VertexPulling::Config cfg;
+    cfg.vertex_state = {{{256,
+                          VertexStepMode::kVertex,
+                          {
+                              {VertexFormat::kUint8x2, 64, 0},
+                              {VertexFormat::kUint8x4, 64, 1},
+                              {VertexFormat::kUint8x4, 64, 2},
+                              {VertexFormat::kUint8x4, 64, 3},
+                              {VertexFormat::kUint16x2, 64, 4},
+                              {VertexFormat::kUint16x4, 64, 5},
+                              {VertexFormat::kUint16x4, 64, 6},
+                              {VertexFormat::kUint16x4, 64, 7},
+                              {VertexFormat::kUint32x2, 64, 8},
+                              {VertexFormat::kUint32x3, 64, 9},
+                              {VertexFormat::kUint32x3, 64, 10},
+                              {VertexFormat::kUint32x4, 64, 11},
+                              {VertexFormat::kUint32x4, 64, 12},
+                              {VertexFormat::kUint32x4, 64, 13},
+                          }}}};
+
+    DataMap data;
+    data.Add<VertexPulling::Config>(cfg);
+    auto got = Run<VertexPulling>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(VertexPullingTest, FormatsWithVectorsResized_Shrinking_Float_F32) {
+    auto* src = R"(
+@vertex
+fn main(
+    @location(0)  sclr_unorm8x2  :      f32 ,
+    @location(1)  sclr_unorm8x4  :      f32 ,
+    @location(2)  vec2_unorm8x4  : vec2<f32>,
+    @location(3)  vec3_unorm8x4  : vec3<f32>,
+    @location(4)  sclr_snorm8x2  :      f32 ,
+    @location(5)  sclr_snorm8x4  :      f32 ,
+    @location(6)  vec2_snorm8x4  : vec2<f32>,
+    @location(7)  vec3_snorm8x4  : vec3<f32>,
+    @location(8)  sclr_unorm16x2 :      f32 ,
+    @location(9)  sclr_unorm16x4 :      f32 ,
+    @location(10) vec2_unorm16x4 : vec2<f32>,
+    @location(11) vec3_unorm16x4 : vec3<f32>,
+    @location(12) sclr_snorm16x2 :      f32 ,
+    @location(13) sclr_snorm16x4 :      f32 ,
+    @location(14) vec2_snorm16x4 : vec2<f32>,
+    @location(15) vec3_snorm16x4 : vec3<f32>,
+    @location(16) sclr_float16x2 :      f32 ,
+    @location(17) sclr_float16x4 :      f32 ,
+    @location(18) vec2_float16x4 : vec2<f32>,
+    @location(19) vec3_float16x4 : vec3<f32>,
+    @location(20) sclr_float32x2 :      f32 ,
+    @location(21) sclr_float32x3 :      f32 ,
+    @location(22) vec2_float32x3 : vec2<f32>,
+    @location(23) sclr_float32x4 :      f32 ,
+    @location(24) vec2_float32x4 : vec2<f32>,
+    @location(25) vec3_float32x4 : vec3<f32>,
+  ) -> @builtin(position) vec4<f32> {
+  return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+}
+)";
+
+    auto* expect = R"(
+struct TintVertexData {
+  tint_vertex_data : array<u32>,
+}
+
+@binding(0) @group(4) var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
+
+@vertex
+fn main(@builtin(vertex_index) tint_pulling_vertex_index : u32) -> @builtin(position) vec4<f32> {
+  var sclr_unorm8x2 : f32;
+  var sclr_unorm8x4 : f32;
+  var vec2_unorm8x4 : vec2<f32>;
+  var vec3_unorm8x4 : vec3<f32>;
+  var sclr_snorm8x2 : f32;
+  var sclr_snorm8x4 : f32;
+  var vec2_snorm8x4 : vec2<f32>;
+  var vec3_snorm8x4 : vec3<f32>;
+  var sclr_unorm16x2 : f32;
+  var sclr_unorm16x4 : f32;
+  var vec2_unorm16x4 : vec2<f32>;
+  var vec3_unorm16x4 : vec3<f32>;
+  var sclr_snorm16x2 : f32;
+  var sclr_snorm16x4 : f32;
+  var vec2_snorm16x4 : vec2<f32>;
+  var vec3_snorm16x4 : vec3<f32>;
+  var sclr_float16x2 : f32;
+  var sclr_float16x4 : f32;
+  var vec2_float16x4 : vec2<f32>;
+  var vec3_float16x4 : vec3<f32>;
+  var sclr_float32x2 : f32;
+  var sclr_float32x3 : f32;
+  var vec2_float32x3 : vec2<f32>;
+  var sclr_float32x4 : f32;
+  var vec2_float32x4 : vec2<f32>;
+  var vec3_float32x4 : vec3<f32>;
+  {
+    let buffer_array_base_0 = (tint_pulling_vertex_index * 64u);
+    sclr_unorm8x2 = unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy.x;
+    sclr_unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
+    vec2_unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).xy;
+    vec3_unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).xyz;
+    sclr_snorm8x2 = unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy.x;
+    sclr_snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
+    vec2_snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).xy;
+    vec3_snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).xyz;
+    sclr_unorm16x2 = unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
+    sclr_unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
+    vec2_unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xy;
+    vec3_unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xyz;
+    sclr_snorm16x2 = unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
+    sclr_snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
+    vec2_snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xy;
+    vec3_snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xyz;
+    sclr_float16x2 = unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
+    sclr_float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
+    vec2_float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xy;
+    vec3_float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xyz;
+    sclr_float32x2 = vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
+    sclr_float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).x;
+    vec2_float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).xy;
+    sclr_float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).x;
+    vec2_float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xy;
+    vec3_float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xyz;
   }
   return vec4<f32>(0.0, 0.0, 0.0, 1.0);
 }
@@ -1194,21 +1807,19 @@
         {{256,
           VertexStepMode::kVertex,
           {
-              {VertexFormat::kUint8x2, 64, 0},    {VertexFormat::kUint8x4, 64, 1},
-              {VertexFormat::kSint8x2, 64, 2},    {VertexFormat::kSint8x4, 64, 3},
-              {VertexFormat::kUnorm8x2, 64, 4},   {VertexFormat::kUnorm8x4, 64, 5},
-              {VertexFormat::kSnorm8x2, 64, 6},   {VertexFormat::kSnorm8x4, 64, 7},
-              {VertexFormat::kUint16x2, 64, 8},   {VertexFormat::kUint16x4, 64, 9},
-              {VertexFormat::kSint16x2, 64, 10},  {VertexFormat::kSint16x4, 64, 11},
-              {VertexFormat::kUnorm16x2, 64, 12}, {VertexFormat::kUnorm16x4, 64, 13},
-              {VertexFormat::kSnorm16x2, 64, 14}, {VertexFormat::kSnorm16x4, 64, 15},
+              {VertexFormat::kUnorm8x2, 64, 0},   {VertexFormat::kUnorm8x4, 64, 1},
+              {VertexFormat::kUnorm8x4, 64, 2},   {VertexFormat::kUnorm8x4, 64, 3},
+              {VertexFormat::kSnorm8x2, 64, 4},   {VertexFormat::kSnorm8x4, 64, 5},
+              {VertexFormat::kSnorm8x4, 64, 6},   {VertexFormat::kSnorm8x4, 64, 7},
+              {VertexFormat::kUnorm16x2, 64, 8},  {VertexFormat::kUnorm16x4, 64, 9},
+              {VertexFormat::kUnorm16x4, 64, 10}, {VertexFormat::kUnorm16x4, 64, 11},
+              {VertexFormat::kSnorm16x2, 64, 12}, {VertexFormat::kSnorm16x4, 64, 13},
+              {VertexFormat::kSnorm16x4, 64, 14}, {VertexFormat::kSnorm16x4, 64, 15},
               {VertexFormat::kFloat16x2, 64, 16}, {VertexFormat::kFloat16x4, 64, 17},
-              {VertexFormat::kFloat32, 64, 18},   {VertexFormat::kFloat32x2, 64, 19},
-              {VertexFormat::kFloat32x3, 64, 20}, {VertexFormat::kFloat32x4, 64, 21},
-              {VertexFormat::kUint32, 64, 22},    {VertexFormat::kUint32x2, 64, 23},
-              {VertexFormat::kUint32x3, 64, 24},  {VertexFormat::kUint32x4, 64, 25},
-              {VertexFormat::kSint32, 64, 26},    {VertexFormat::kSint32x2, 64, 27},
-              {VertexFormat::kSint32x3, 64, 28},  {VertexFormat::kSint32x4, 64, 29},
+              {VertexFormat::kFloat16x4, 64, 18}, {VertexFormat::kFloat16x4, 64, 19},
+              {VertexFormat::kFloat32x2, 64, 20}, {VertexFormat::kFloat32x3, 64, 21},
+              {VertexFormat::kFloat32x3, 64, 22}, {VertexFormat::kFloat32x4, 64, 23},
+              {VertexFormat::kFloat32x4, 64, 24}, {VertexFormat::kFloat32x4, 64, 25},
           }}}};
 
     DataMap data;