[tint][type] Fix runtime-sized array implicit stride
Copy the fix for static-sized arrays from:
https://dawn-review.googlesource.com/c/dawn/+/135580
Change-Id: I69a46c5608821e979bfb3b3cd20ec368754a3fb9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/165040
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/tint/lang/core/type/manager.cc b/src/tint/lang/core/type/manager.cc
index 50c1a39..8c9b297 100644
--- a/src/tint/lang/core/type/manager.cc
+++ b/src/tint/lang/core/type/manager.cc
@@ -174,16 +174,19 @@
 
 const core::type::Array* Manager::runtime_array(const core::type::Type* elem_ty,
                                                 uint32_t stride /* = 0 */) {
+    uint32_t implicit_stride = tint::RoundUp(elem_ty->Align(), elem_ty->Size());
     if (stride == 0) {
-        stride = elem_ty->Align();
+        stride = implicit_stride;
     }
+    TINT_ASSERT(stride >= implicit_stride);
+
     return Get<core::type::Array>(
         /* element type */ elem_ty,
         /* element count */ Get<RuntimeArrayCount>(),
         /* array alignment */ elem_ty->Align(),
         /* array size */ stride,
         /* element stride */ stride,
-        /* implicit stride */ elem_ty->Align());
+        /* implicit stride */ implicit_stride);
 }
 
 const core::type::Pointer* Manager::ptr(core::AddressSpace address_space,
diff --git a/src/tint/lang/core/type/manager_test.cc b/src/tint/lang/core/type/manager_test.cc
index 81bcdaa..cd141fb 100644
--- a/src/tint/lang/core/type/manager_test.cc
+++ b/src/tint/lang/core/type/manager_test.cc
@@ -28,15 +28,19 @@
 #include "src/tint/lang/core/type/manager.h"
 
 #include "gtest/gtest.h"
+#include "src/tint/lang/core/type/array.h"
 #include "src/tint/lang/core/type/bool.h"
 #include "src/tint/lang/core/type/f16.h"
 #include "src/tint/lang/core/type/f32.h"
 #include "src/tint/lang/core/type/i32.h"
+#include "src/tint/lang/core/type/matrix.h"
 #include "src/tint/lang/core/type/u32.h"
 
 namespace tint::core::type {
 namespace {
 
+using namespace tint::core::fluent_types;  // NOLINT
+
 template <typename T>
 size_t count(const T& range_loopable) {
     size_t n = 0;
@@ -124,5 +128,19 @@
     EXPECT_EQ(count(outer), 1u);
 }
 
+TEST_F(ManagerTest, ArrayImplicitStride) {
+    Manager tm;
+    auto* arr = tm.array<mat4x4<f32>, 4>();
+    EXPECT_EQ(arr->Stride(), 64u);
+    EXPECT_EQ(arr->ImplicitStride(), 64u);
+}
+
+TEST_F(ManagerTest, RuntimeSizedArrayImplicitStride) {
+    Manager tm;
+    auto* arr = tm.array<mat4x4<f32>>();
+    EXPECT_EQ(arr->Stride(), 64u);
+    EXPECT_EQ(arr->ImplicitStride(), 64u);
+}
+
 }  // namespace
 }  // namespace tint::core::type