tint/resolver: Simplify array size evaluation

Use the constant evaluated value instead of manually traversing
variables to find the literal value. This is a small step towards
supporting 'const' values for array sizes.

Also make our OOB-byte related error diagnostics consistent.

Bug: tint:1580
Change-Id: Idf9eb22cdbf69d750218c554e9f826c30458c6b9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94600
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index e0dc192..fc78fb2 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -2148,69 +2148,58 @@
 
     uint64_t stride = explicit_stride ? explicit_stride : implicit_stride;
 
+    int64_t count = 0;  // sem::Array uses a size of 0 for a runtime-sized array.
+
     // Evaluate the constant array size expression.
-    // sem::Array uses a size of 0 for a runtime-sized array.
-    uint32_t count = 0;
     if (auto* count_expr = arr->count) {
         const auto* count_sem = Materialize(Expression(count_expr));
         if (!count_sem) {
             return nullptr;
         }
 
-        auto size_source = count_expr->source;
-
-        auto* ty = count_sem->Type()->UnwrapRef();
-        if (!ty->is_integer_scalar()) {
-            AddError("array size must be integer scalar", size_source);
-            return nullptr;
-        }
-
-        constexpr const char* kErrInvalidExpr =
-            "array size identifier must be a literal or a module-scope 'let'";
-
-        if (auto* ident = count_expr->As<ast::IdentifierExpression>()) {
-            // Make sure the identifier is a non-overridable module-scope 'let'.
-            auto* global = sem_.ResolvedSymbol<sem::GlobalVariable>(ident);
-            if (!global || !global->Declaration()->Is<ast::Let>()) {
-                AddError(kErrInvalidExpr, size_source);
-                return nullptr;
-            }
-            count_expr = global->Declaration()->constructor;
-        } else if (!count_expr->Is<ast::LiteralExpression>()) {
-            AddError(kErrInvalidExpr, size_source);
+        // TODO(crbug.com/tint/1580): Temporary seatbelt to used to ensure that a function-scope
+        // `let` cannot be used to propagate a constant expression to an array size. Once we
+        // implement `const`, this can be removed.
+        if (auto* user = count_sem->UnwrapMaterialize()->As<sem::VariableUser>();
+            user && user->Variable()->Is<sem::LocalVariable>() &&
+            user->Variable()->Declaration()->Is<ast::Let>()) {
+            AddError("array size must evaluate to a constant integer expression",
+                     count_expr->source);
             return nullptr;
         }
 
         auto count_val = count_sem->ConstantValue();
         if (!count_val) {
-            TINT_ICE(Resolver, diagnostics_) << "could not resolve array size expression";
+            AddError("array size must evaluate to a constant integer expression",
+                     count_expr->source);
             return nullptr;
         }
 
-        if (count_val.Element<AInt>(0).value < 1) {
-            AddError("array size must be at least 1", size_source);
+        if (auto* ty = count_val.Type(); !ty->is_integer_scalar()) {
+            AddError("array size must evaluate to a constant integer expression, but is type '" +
+                         builder_->FriendlyName(ty) + "'",
+                     count_expr->source);
             return nullptr;
         }
 
-        count = count_val.Element<uint32_t>(0);
+        count = count_val.Element<AInt>(0).value;
+        if (count < 1) {
+            AddError("array size (" + std::to_string(count) + ") must be greater than 0",
+                     count_expr->source);
+            return nullptr;
+        }
     }
 
-    auto size = std::max<uint64_t>(count, 1) * stride;
+    auto size = std::max<uint64_t>(count, 1u) * stride;
     if (size > std::numeric_limits<uint32_t>::max()) {
         std::stringstream msg;
-        msg << "array size in bytes must not exceed 0x" << std::hex
-            << std::numeric_limits<uint32_t>::max() << ", but is 0x" << std::hex << size;
+        msg << "array size (0x" << std::hex << size << ") must not exceed 0xffffffff bytes";
         AddError(msg.str(), arr->source);
         return nullptr;
     }
-    if (stride > std::numeric_limits<uint32_t>::max() ||
-        implicit_stride > std::numeric_limits<uint32_t>::max()) {
-        TINT_ICE(Resolver, diagnostics_) << "calculated array stride exceeds uint32";
-        return nullptr;
-    }
     auto* out = builder_->create<sem::Array>(
-        elem_type, count, el_align, static_cast<uint32_t>(size), static_cast<uint32_t>(stride),
-        static_cast<uint32_t>(implicit_stride));
+        elem_type, static_cast<uint32_t>(count), el_align, static_cast<uint32_t>(size),
+        static_cast<uint32_t>(stride), static_cast<uint32_t>(implicit_stride));
 
     if (!validator_.Array(out, source)) {
         return nullptr;
@@ -2338,8 +2327,8 @@
         offset = utils::RoundUp(align, offset);
         if (offset > std::numeric_limits<uint32_t>::max()) {
             std::stringstream msg;
-            msg << "struct member has byte offset 0x" << std::hex << offset
-                << ", but must not exceed 0x" << std::hex << std::numeric_limits<uint32_t>::max();
+            msg << "struct member offset (0x" << std::hex << offset << ") must not exceed 0x"
+                << std::hex << std::numeric_limits<uint32_t>::max() << " bytes";
             AddError(msg.str(), member->source);
             return nullptr;
         }
@@ -2360,8 +2349,7 @@
 
     if (struct_size > std::numeric_limits<uint32_t>::max()) {
         std::stringstream msg;
-        msg << "struct size in bytes must not exceed 0x" << std::hex
-            << std::numeric_limits<uint32_t>::max() << ", but is 0x" << std::hex << struct_size;
+        msg << "struct size (0x" << std::hex << struct_size << ") must not exceed 0xffffffff bytes";
         AddError(msg.str(), str->source);
         return nullptr;
     }
diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc
index 3277ee8..5d891fc 100644
--- a/src/tint/resolver/type_constructor_validation_test.cc
+++ b/src/tint/resolver/type_constructor_validation_test.cc
@@ -581,8 +581,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: array constructor has too few elements: expected 4, "
-              "found 3");
+              "12:34 error: array constructor has too few elements: expected 4, found 3");
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_TooManyElements) {
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index e79026e..9f03e05 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -216,28 +216,28 @@
     // var<private> a : array<f32, 0>;
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) {
     // var<private> a : array<f32, 0u>;
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Zero) {
     // var<private> a : array<f32, 0i>;
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
     // var<private> a : array<f32, -10i>;
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (-10) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Zero) {
@@ -246,7 +246,7 @@
     GlobalConst("size", nullptr, Expr(0_u));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Zero) {
@@ -255,7 +255,7 @@
     GlobalConst("size", nullptr, Expr(0_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Negative) {
@@ -264,14 +264,16 @@
     GlobalConst("size", nullptr, Expr(-10_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
+    EXPECT_EQ(r()->error(), "12:34 error: array size (-10) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_FloatLiteral) {
     // var<private> a : array<f32, 10.0>;
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+    EXPECT_EQ(r()->error(),
+              "12:34 error: array size must evaluate to a constant integer expression, but is type "
+              "'f32'");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
@@ -279,7 +281,9 @@
     Global("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
            ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+    EXPECT_EQ(r()->error(),
+              "12:34 error: array size must evaluate to a constant integer expression, but is type "
+              "'vec2<i32>'");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_FloatLet) {
@@ -288,7 +292,9 @@
     GlobalConst("size", nullptr, Expr(10_f));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+    EXPECT_EQ(r()->error(),
+              "12:34 error: array size must evaluate to a constant integer expression, but is type "
+              "'f32'");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecLet) {
@@ -297,7 +303,9 @@
     GlobalConst("size", nullptr, Construct(ty.vec2<i32>(), 100_i, 100_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
+    EXPECT_EQ(r()->error(),
+              "12:34 error: array size must evaluate to a constant integer expression, but is type "
+              "'vec2<i32>'");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ImplicitStride) {
@@ -305,8 +313,7 @@
     Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x40000000_u), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: array size in bytes must not exceed 0xffffffff, but "
-              "is 0x100000000");
+              "12:34 error: array size (0x100000000) must not exceed 0xffffffff bytes");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
@@ -314,8 +321,7 @@
     Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x20000000_u, 8), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: array size in bytes must not exceed 0xffffffff, but "
-              "is 0x100000000");
+              "12:34 error: array size (0x100000000) must not exceed 0xffffffff bytes");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_Overridable) {
@@ -325,7 +331,7 @@
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+              "12:34 error: array size must evaluate to a constant integer expression");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_ModuleVar) {
@@ -335,7 +341,7 @@
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+              "12:34 error: array size must evaluate to a constant integer expression");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_FunctionLet) {
@@ -345,19 +351,17 @@
     // }
     auto* size = Let("size", nullptr, Expr(10_i));
     auto* a = Var("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")));
-    WrapInFunction(Block(Decl(size), Decl(a)));
+    WrapInFunction(size, a);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+              "12:34 error: array size must evaluate to a constant integer expression");
 }
 
-TEST_F(ResolverTypeValidationTest, ArraySize_InvalidExpr) {
+TEST_F(ResolverTypeValidationTest, ArraySize_ComplexExpr) {
     // var a : array<f32, i32(4i)>;
     auto* a = Var("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.i32(), 4_i)));
-    WrapInFunction(Block(Decl(a)));
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(),
-              "12:34 error: array size identifier must be a literal or a module-scope 'let'");
+    WrapInFunction(a);
+    EXPECT_TRUE(r()->Resolve());
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) {
@@ -417,8 +421,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: struct size in bytes must not exceed 0xffffffff, but "
-              "is 0x100000000");
+              "12:34 error: struct size (0x100000000) must not exceed 0xffffffff bytes");
 }
 
 TEST_F(ResolverTypeValidationTest, Struct_MemberOffset_TooBig) {
@@ -438,8 +441,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: struct member has byte offset 0x100000000, but must "
-              "not exceed 0xffffffff");
+              "12:34 error: struct member offset (0x100000000) must not exceed 0xffffffff bytes");
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLast_Pass) {
@@ -467,8 +469,7 @@
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
-              "12:34 error: an array element type cannot contain a runtime-sized "
-              "array");
+              "12:34 error: an array element type cannot contain a runtime-sized array");
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayInStructInArray) {
@@ -482,8 +483,7 @@
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
-              "12:34 error: an array element type cannot contain a runtime-sized "
-              "array");
+              "12:34 error: an array element type cannot contain a runtime-sized array");
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayInStructInStruct) {
@@ -499,8 +499,8 @@
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
-              "12:34 error: a struct that contains a runtime array cannot be "
-              "nested inside another struct");
+              "12:34 error: a struct that contains a runtime array cannot be nested inside another "
+              "struct");
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) {
@@ -601,8 +601,7 @@
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
-              "12:34 error: runtime arrays may only appear as the last member of "
-              "a struct");
+              "12:34 error: runtime arrays may only appear as the last member of a struct");
 }
 
 TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) {
@@ -629,8 +628,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: texture_2d<f32> cannot be used as an element type of "
-              "an array");
+              "12:34 error: texture_2d<f32> cannot be used as an element type of an array");
 }
 
 TEST_F(ResolverTypeValidationTest, VariableAsType) {
@@ -980,8 +978,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: storage textures currently only support 'write' "
-              "access control");
+              "12:34 error: storage textures currently only support 'write' access control");
 }
 
 TEST_F(StorageTextureAccessTest, ReadOnlyAccess_Fail) {
@@ -995,8 +992,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: storage textures currently only support 'write' "
-              "access control");
+              "12:34 error: storage textures currently only support 'write' access control");
 }
 
 TEST_F(StorageTextureAccessTest, WriteOnlyAccess_Pass) {
@@ -1116,8 +1112,7 @@
            ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: vector element type must be 'bool', 'f32', 'i32' "
-              "or 'u32'");
+              "12:34 error: vector element type must be 'bool', 'f32', 'i32' or 'u32'");
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
                          InvalidVectorElementTypes,
diff --git a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.glsl
index 98b5a53..9f37260 100644
--- a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat2 m = mat2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f));
 mat2 f() {
   mat2 m_1 = mat2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f));
-  return mat2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.hlsl
index 884de04..4e8ff0b 100644
--- a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float2x2 f() {
   const float2x2 m_1 = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
-  return float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.msl
index 2397b00..c464132 100644
--- a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float2x2 f() {
   float2x2 const m_1 = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
-  return float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.spvasm
index 8b08148..b2cc1c4 100644
--- a/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat2x2/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,9 +13,9 @@
       %float = OpTypeFloat 32
     %v2float = OpTypeVector %float 2
 %mat2v2float = OpTypeMatrix %v2float 2
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
-          %6 = OpConstantComposite %v2float %float_0 %float_1
+          %6 = OpConstantComposite %v2float %4 %float_1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %9 = OpConstantComposite %v2float %float_2 %float_3
diff --git a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.glsl
index 98b5a53..9f37260 100644
--- a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat2 m = mat2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f));
 mat2 f() {
   mat2 m_1 = mat2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f));
-  return mat2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.hlsl
index 884de04..4e8ff0b 100644
--- a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float2x2 f() {
   const float2x2 m_1 = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
-  return float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.msl
index 2397b00..c464132 100644
--- a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float2x2 f() {
   float2x2 const m_1 = float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
-  return float2x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.spvasm
index 8b08148..b2cc1c4 100644
--- a/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat2x2/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,9 +13,9 @@
       %float = OpTypeFloat 32
     %v2float = OpTypeVector %float 2
 %mat2v2float = OpTypeMatrix %v2float 2
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
-          %6 = OpConstantComposite %v2float %float_0 %float_1
+          %6 = OpConstantComposite %v2float %4 %float_1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %9 = OpConstantComposite %v2float %float_2 %float_3
diff --git a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.glsl
index b191a03..8b1bb8d 100644
--- a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat2x3 m = mat2x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f));
 mat2x3 f() {
   mat2x3 m_1 = mat2x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f));
-  return mat2x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.hlsl
index 4a428a2..96f3472 100644
--- a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float2x3 f() {
   const float2x3 m_1 = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
-  return float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.msl
index 6e9320e..e0619e1 100644
--- a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float2x3 f() {
   float2x3 const m_1 = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
-  return float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.spvasm
index 0cecb54..075746a 100644
--- a/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat2x3/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,10 +13,10 @@
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat2v3float = OpTypeMatrix %v3float 2
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
-          %7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
+          %7 = OpConstantComposite %v3float %4 %float_1 %float_2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
diff --git a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.glsl
index b191a03..8b1bb8d 100644
--- a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat2x3 m = mat2x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f));
 mat2x3 f() {
   mat2x3 m_1 = mat2x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f));
-  return mat2x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.hlsl
index 4a428a2..96f3472 100644
--- a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float2x3 f() {
   const float2x3 m_1 = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
-  return float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.msl
index 6e9320e..e0619e1 100644
--- a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float2x3 f() {
   float2x3 const m_1 = float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
-  return float2x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.spvasm
index 0cecb54..075746a 100644
--- a/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat2x3/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,10 +13,10 @@
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat2v3float = OpTypeMatrix %v3float 2
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
-          %7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
+          %7 = OpConstantComposite %v3float %4 %float_1 %float_2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
diff --git a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.glsl
index 41253c4..4f30e2f 100644
--- a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat2x4 m = mat2x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f));
 mat2x4 f() {
   mat2x4 m_1 = mat2x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f));
-  return mat2x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.hlsl
index 32b40f8..96e6b19 100644
--- a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float2x4 f() {
   const float2x4 m_1 = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
-  return float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.msl
index d4bd7df..d3c4da9 100644
--- a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float2x4 f() {
   float2x4 const m_1 = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
-  return float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.spvasm
index 6766c86..7cab4d6 100644
--- a/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat2x4/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,11 +13,11 @@
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %mat2v4float = OpTypeMatrix %v4float 2
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
-          %8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+          %8 = OpConstantComposite %v4float %4 %float_1 %float_2 %float_3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
     %float_6 = OpConstant %float 6
diff --git a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.glsl
index 41253c4..4f30e2f 100644
--- a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat2x4 m = mat2x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f));
 mat2x4 f() {
   mat2x4 m_1 = mat2x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f));
-  return mat2x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.hlsl
index 32b40f8..96e6b19 100644
--- a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float2x4 f() {
   const float2x4 m_1 = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
-  return float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.msl
index d4bd7df..d3c4da9 100644
--- a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float2x4 f() {
   float2x4 const m_1 = float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
-  return float2x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.spvasm
index 6766c86..7cab4d6 100644
--- a/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat2x4/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,11 +13,11 @@
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %mat2v4float = OpTypeMatrix %v4float 2
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
-          %8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+          %8 = OpConstantComposite %v4float %4 %float_1 %float_2 %float_3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
     %float_6 = OpConstant %float 6
diff --git a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.glsl
index 49056fe..e067774 100644
--- a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat3x2 m = mat3x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f));
 mat3x2 f() {
   mat3x2 m_1 = mat3x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f));
-  return mat3x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.hlsl
index 049a998..5897ac6 100644
--- a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float3x2 f() {
   const float3x2 m_1 = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
-  return float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.msl
index 9e216c8..43ec396 100644
--- a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float3x2 f() {
   float3x2 const m_1 = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
-  return float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.spvasm
index 6679e29..95ffb2b 100644
--- a/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat3x2/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,9 +13,9 @@
       %float = OpTypeFloat 32
     %v2float = OpTypeVector %float 2
 %mat3v2float = OpTypeMatrix %v2float 3
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
-          %6 = OpConstantComposite %v2float %float_0 %float_1
+          %6 = OpConstantComposite %v2float %4 %float_1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %9 = OpConstantComposite %v2float %float_2 %float_3
diff --git a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.glsl
index 49056fe..e067774 100644
--- a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat3x2 m = mat3x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f));
 mat3x2 f() {
   mat3x2 m_1 = mat3x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f));
-  return mat3x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.hlsl
index 049a998..5897ac6 100644
--- a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float3x2 f() {
   const float3x2 m_1 = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
-  return float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.msl
index 9e216c8..43ec396 100644
--- a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float3x2 f() {
   float3x2 const m_1 = float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
-  return float3x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.spvasm
index 6679e29..95ffb2b 100644
--- a/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat3x2/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,9 +13,9 @@
       %float = OpTypeFloat 32
     %v2float = OpTypeVector %float 2
 %mat3v2float = OpTypeMatrix %v2float 3
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
-          %6 = OpConstantComposite %v2float %float_0 %float_1
+          %6 = OpConstantComposite %v2float %4 %float_1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %9 = OpConstantComposite %v2float %float_2 %float_3
diff --git a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.glsl
index e99ac3c..e3e750e 100644
--- a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat3 m = mat3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f));
 mat3 f() {
   mat3 m_1 = mat3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f));
-  return mat3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.hlsl
index 63eef11..1795dfb 100644
--- a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float3x3 f() {
   const float3x3 m_1 = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
-  return float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.msl
index d2eac15..f6a7b59 100644
--- a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float3x3 f() {
   float3x3 const m_1 = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
-  return float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.spvasm
index 0386f4e..d213c99 100644
--- a/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat3x3/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,10 +13,10 @@
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat3v3float = OpTypeMatrix %v3float 3
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
-          %7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
+          %7 = OpConstantComposite %v3float %4 %float_1 %float_2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
diff --git a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.glsl
index e99ac3c..e3e750e 100644
--- a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat3 m = mat3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f));
 mat3 f() {
   mat3 m_1 = mat3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f));
-  return mat3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.hlsl
index 63eef11..1795dfb 100644
--- a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float3x3 f() {
   const float3x3 m_1 = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
-  return float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.msl
index d2eac15..f6a7b59 100644
--- a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float3x3 f() {
   float3x3 const m_1 = float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
-  return float3x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.spvasm
index 0386f4e..d213c99 100644
--- a/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat3x3/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,10 +13,10 @@
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat3v3float = OpTypeMatrix %v3float 3
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
-          %7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
+          %7 = OpConstantComposite %v3float %4 %float_1 %float_2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
diff --git a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.glsl
index 075d29b..6c64f68 100644
--- a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat3x4 m = mat3x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f));
 mat3x4 f() {
   mat3x4 m_1 = mat3x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f));
-  return mat3x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.hlsl
index de62d39..77ea8af 100644
--- a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float3x4 f() {
   const float3x4 m_1 = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
-  return float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.msl
index 86e4c2e..4ee3d7b 100644
--- a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float3x4 f() {
   float3x4 const m_1 = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
-  return float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.spvasm
index 8770c7b..8019731 100644
--- a/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat3x4/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,11 +13,11 @@
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %mat3v4float = OpTypeMatrix %v4float 3
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
-          %8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+          %8 = OpConstantComposite %v4float %4 %float_1 %float_2 %float_3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
     %float_6 = OpConstant %float 6
diff --git a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.glsl
index 075d29b..6c64f68 100644
--- a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat3x4 m = mat3x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f));
 mat3x4 f() {
   mat3x4 m_1 = mat3x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f));
-  return mat3x4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.hlsl
index de62d39..77ea8af 100644
--- a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float3x4 f() {
   const float3x4 m_1 = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
-  return float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.msl
index 86e4c2e..4ee3d7b 100644
--- a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float3x4 f() {
   float3x4 const m_1 = float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
-  return float3x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.spvasm
index 8770c7b..8019731 100644
--- a/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat3x4/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,11 +13,11 @@
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %mat3v4float = OpTypeMatrix %v4float 3
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
-          %8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+          %8 = OpConstantComposite %v4float %4 %float_1 %float_2 %float_3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
     %float_6 = OpConstant %float 6
diff --git a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.glsl
index 899a25f..1adb3c8 100644
--- a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat4x2 m = mat4x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));
 mat4x2 f() {
   mat4x2 m_1 = mat4x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));
-  return mat4x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.hlsl
index de0cb92..a8a20db 100644
--- a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float4x2 f() {
   const float4x2 m_1 = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
-  return float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.msl
index 19ae099..dcef3ec 100644
--- a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float4x2 f() {
   float4x2 const m_1 = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
-  return float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.spvasm
index 045b57c..54757df 100644
--- a/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat4x2/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,9 +13,9 @@
       %float = OpTypeFloat 32
     %v2float = OpTypeVector %float 2
 %mat4v2float = OpTypeMatrix %v2float 4
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
-          %6 = OpConstantComposite %v2float %float_0 %float_1
+          %6 = OpConstantComposite %v2float %4 %float_1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %9 = OpConstantComposite %v2float %float_2 %float_3
diff --git a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.glsl
index 899a25f..1adb3c8 100644
--- a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat4x2 m = mat4x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));
 mat4x2 f() {
   mat4x2 m_1 = mat4x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));
-  return mat4x2(vec2(0.0f, 1.0f), vec2(2.0f, 3.0f), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.hlsl
index de0cb92..a8a20db 100644
--- a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float4x2 f() {
   const float4x2 m_1 = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
-  return float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.msl
index 19ae099..dcef3ec 100644
--- a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float4x2 f() {
   float4x2 const m_1 = float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
-  return float4x2(float2(0.0f, 1.0f), float2(2.0f, 3.0f), float2(4.0f, 5.0f), float2(6.0f, 7.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.spvasm
index 045b57c..54757df 100644
--- a/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat4x2/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,9 +13,9 @@
       %float = OpTypeFloat 32
     %v2float = OpTypeVector %float 2
 %mat4v2float = OpTypeMatrix %v2float 4
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
-          %6 = OpConstantComposite %v2float %float_0 %float_1
+          %6 = OpConstantComposite %v2float %4 %float_1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %9 = OpConstantComposite %v2float %float_2 %float_3
diff --git a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.glsl
index 87a80c9..f506747 100644
--- a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat4x3 m = mat4x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f), vec3(9.0f, 10.0f, 11.0f));
 mat4x3 f() {
   mat4x3 m_1 = mat4x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f), vec3(9.0f, 10.0f, 11.0f));
-  return mat4x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f), vec3(9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.hlsl
index 30ebfbf..8adbbb3 100644
--- a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float4x3 f() {
   const float4x3 m_1 = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
-  return float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.msl
index d7238cd..b4c5eab 100644
--- a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float4x3 f() {
   float4x3 const m_1 = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
-  return float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.spvasm
index 16d9efb..be135b0 100644
--- a/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat4x3/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,10 +13,10 @@
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat4v3float = OpTypeMatrix %v3float 4
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
-          %7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
+          %7 = OpConstantComposite %v3float %4 %float_1 %float_2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
diff --git a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.glsl
index 87a80c9..f506747 100644
--- a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat4x3 m = mat4x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f), vec3(9.0f, 10.0f, 11.0f));
 mat4x3 f() {
   mat4x3 m_1 = mat4x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f), vec3(9.0f, 10.0f, 11.0f));
-  return mat4x3(vec3(0.0f, 1.0f, 2.0f), vec3(3.0f, 4.0f, 5.0f), vec3(6.0f, 7.0f, 8.0f), vec3(9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.hlsl
index 30ebfbf..8adbbb3 100644
--- a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float4x3 f() {
   const float4x3 m_1 = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
-  return float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.msl
index d7238cd..b4c5eab 100644
--- a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float4x3 f() {
   float4x3 const m_1 = float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
-  return float4x3(float3(0.0f, 1.0f, 2.0f), float3(3.0f, 4.0f, 5.0f), float3(6.0f, 7.0f, 8.0f), float3(9.0f, 10.0f, 11.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.spvasm
index 16d9efb..be135b0 100644
--- a/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat4x3/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,10 +13,10 @@
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat4v3float = OpTypeMatrix %v3float 4
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
-          %7 = OpConstantComposite %v3float %float_0 %float_1 %float_2
+          %7 = OpConstantComposite %v3float %4 %float_1 %float_2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
diff --git a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.glsl
index 3c5cf24..737abbe 100644
--- a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat4 m = mat4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f), vec4(12.0f, 13.0f, 14.0f, 15.0f));
 mat4 f() {
   mat4 m_1 = mat4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f), vec4(12.0f, 13.0f, 14.0f, 15.0f));
-  return mat4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f), vec4(12.0f, 13.0f, 14.0f, 15.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.hlsl
index 1f3e190..cdde3bc 100644
--- a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float4x4 f() {
   const float4x4 m_1 = float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
-  return float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.msl
index ffac88e..54f69fa 100644
--- a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float4x4 f() {
   float4x4 const m_1 = float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
-  return float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.spvasm
index a4fc367..43fad62 100644
--- a/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat4x4/explicit/identity/f32.wgsl.expected.spvasm
@@ -13,11 +13,11 @@
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %mat4v4float = OpTypeMatrix %v4float 4
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
-          %8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+          %8 = OpConstantComposite %v4float %4 %float_1 %float_2 %float_3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
     %float_6 = OpConstant %float 6
diff --git a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.glsl b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.glsl
index 3c5cf24..737abbe 100644
--- a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.glsl
+++ b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 const mat4 m = mat4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f), vec4(12.0f, 13.0f, 14.0f, 15.0f));
 mat4 f() {
   mat4 m_1 = mat4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f), vec4(12.0f, 13.0f, 14.0f, 15.0f));
-  return mat4(vec4(0.0f, 1.0f, 2.0f, 3.0f), vec4(4.0f, 5.0f, 6.0f, 7.0f), vec4(8.0f, 9.0f, 10.0f, 11.0f), vec4(12.0f, 13.0f, 14.0f, 15.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.hlsl b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.hlsl
index 1f3e190..cdde3bc 100644
--- a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.hlsl
+++ b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.hlsl
@@ -7,5 +7,5 @@
 
 float4x4 f() {
   const float4x4 m_1 = float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
-  return float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
+  return m_1;
 }
diff --git a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.msl b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.msl
index ffac88e..54f69fa 100644
--- a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.msl
+++ b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.msl
@@ -5,6 +5,6 @@
 
 float4x4 f() {
   float4x4 const m_1 = float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
-  return float4x4(float4(0.0f, 1.0f, 2.0f, 3.0f), float4(4.0f, 5.0f, 6.0f, 7.0f), float4(8.0f, 9.0f, 10.0f, 11.0f), float4(12.0f, 13.0f, 14.0f, 15.0f));
+  return m_1;
 }
 
diff --git a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.spvasm b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.spvasm
index a4fc367..43fad62 100644
--- a/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.spvasm
+++ b/test/tint/expressions/type_ctor/mat4x4/inferred/identity/f32.wgsl.expected.spvasm
@@ -13,11 +13,11 @@
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %mat4v4float = OpTypeMatrix %v4float 4
-    %float_0 = OpConstant %float 0
+          %4 = OpConstantNull %float
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
-          %8 = OpConstantComposite %v4float %float_0 %float_1 %float_2 %float_3
+          %8 = OpConstantComposite %v4float %4 %float_1 %float_2 %float_3
     %float_4 = OpConstant %float 4
     %float_5 = OpConstant %float 5
     %float_6 = OpConstant %float 6