Add compile-time optimization for transpose().

Change-Id: I9ddb80b8886827250e243dc9174bb3679e70df9b
Bug: skia:12202
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/440262
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/resources/sksl/intrinsics/Transpose.sksl b/resources/sksl/intrinsics/Transpose.sksl
index 129764d..d031511 100644
--- a/resources/sksl/intrinsics/Transpose.sksl
+++ b/resources/sksl/intrinsics/Transpose.sksl
@@ -3,7 +3,7 @@
 uniform half4 colorGreen, colorRed;
 
 half4 main(float2 coords) {
-    const float2x3 testMatrix2x3 = float2x3(1, 2, 3, 4, 5, 6);
+    float2x3 testMatrix2x3 = float2x3(1, 2, 3, 4, 5, 6);
     const float2x4 testMatrix2x4 = float2x4(1, 2, 3, 4, 5, 6, 7, 8);
     const float3x2 testMatrix3x2 = float3x2(1, 2, 3, 4, 5, 6);
     const float3x4 testMatrix3x4 = float3x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
diff --git a/src/sksl/ir/SkSLFunctionCall.cpp b/src/sksl/ir/SkSLFunctionCall.cpp
index 18ac352..bdf6774 100644
--- a/src/sksl/ir/SkSLFunctionCall.cpp
+++ b/src/sksl/ir/SkSLFunctionCall.cpp
@@ -423,7 +423,8 @@
 
 static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& context,
                                                            IntrinsicKind intrinsic,
-                                                           const ExpressionArray& arguments) {
+                                                           const ExpressionArray& arguments,
+                                                           const Type& returnType) {
     // Helper function for accessing a matrix argument by column and row.
     const Expression* matrix = nullptr;
     auto M = [&](int c, int r) -> float {
@@ -617,6 +618,19 @@
         case k_matrixCompMult_IntrinsicKind:
             return evaluate_pairwise_intrinsic(context, arguments,
                                                Intrinsics::evaluate_matrixCompMult);
+        case k_transpose_IntrinsicKind: {
+            matrix = ConstantFolder::GetConstantValueForVariable(*arguments[0]);
+            ExpressionArray array;
+            array.reserve_back(returnType.slotCount());
+            for (int c = 0; c < returnType.columns(); ++c) {
+                for (int r = 0; r < returnType.rows(); ++r) {
+                    array.push_back(FloatLiteral::Make(matrix->fOffset, M(r, c),
+                                                       &returnType.componentType()));
+                }
+            }
+            return ConstructorCompound::Make(context, matrix->fOffset, returnType,
+                                             std::move(array));
+        }
         case k_inverse_IntrinsicKind: {
             matrix = ConstantFolder::GetConstantValueForVariable(*arguments[0]);
             switch (arguments[0]->type().slotCount()) {
@@ -818,8 +832,10 @@
         // We might be able to optimize built-in intrinsics.
         if (function.isIntrinsic() && has_compile_time_constant_arguments(arguments)) {
             // The function is an intrinsic and all inputs are compile-time constants. Optimize it.
-            if (std::unique_ptr<Expression> expr =
-                        optimize_intrinsic_call(context, function.intrinsicKind(), arguments)) {
+            if (std::unique_ptr<Expression> expr = optimize_intrinsic_call(context,
+                                                                           function.intrinsicKind(),
+                                                                           arguments,
+                                                                           *returnType)) {
                 return expr;
             }
         }
diff --git a/tests/sksl/intrinsics/Transpose.asm.frag b/tests/sksl/intrinsics/Transpose.asm.frag
index 449be39..a36d319 100644
--- a/tests/sksl/intrinsics/Transpose.asm.frag
+++ b/tests/sksl/intrinsics/Transpose.asm.frag
@@ -13,12 +13,6 @@
 OpName %_entrypoint_v "_entrypoint_v"
 OpName %main "main"
 OpName %testMatrix2x3 "testMatrix2x3"
-OpName %testMatrix2x4 "testMatrix2x4"
-OpName %testMatrix3x2 "testMatrix3x2"
-OpName %testMatrix3x4 "testMatrix3x4"
-OpName %testMatrix4x2 "testMatrix4x2"
-OpName %testMatrix4x3 "testMatrix4x3"
-OpName %testMatrix4x4 "testMatrix4x4"
 OpDecorate %sk_FragColor RelaxedPrecision
 OpDecorate %sk_FragColor Location 0
 OpDecorate %sk_FragColor Index 0
@@ -36,9 +30,9 @@
 OpDecorate %_UniformBuffer Block
 OpDecorate %10 Binding 0
 OpDecorate %10 DescriptorSet 0
-OpDecorate %318 RelaxedPrecision
-OpDecorate %321 RelaxedPrecision
-OpDecorate %322 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
 %float = OpTypeFloat 32
 %v4float = OpTypeVector %float 4
 %_ptr_Output_v4float = OpTypePointer Output %v4float
@@ -67,37 +61,18 @@
 %float_4 = OpConstant %float 4
 %float_5 = OpConstant %float 5
 %float_6 = OpConstant %float 6
-%mat2v4float = OpTypeMatrix %v4float 2
-%_ptr_Function_mat2v4float = OpTypePointer Function %mat2v4float
-%float_7 = OpConstant %float 7
-%float_8 = OpConstant %float 8
-%mat3v2float = OpTypeMatrix %v2float 3
-%_ptr_Function_mat3v2float = OpTypePointer Function %mat3v2float
-%mat3v4float = OpTypeMatrix %v4float 3
-%_ptr_Function_mat3v4float = OpTypePointer Function %mat3v4float
-%float_9 = OpConstant %float 9
-%float_10 = OpConstant %float 10
-%float_11 = OpConstant %float 11
-%float_12 = OpConstant %float 12
-%mat4v2float = OpTypeMatrix %v2float 4
-%_ptr_Function_mat4v2float = OpTypePointer Function %mat4v2float
-%mat4v3float = OpTypeMatrix %v3float 4
-%_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
-%mat4v4float = OpTypeMatrix %v4float 4
-%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
-%float_13 = OpConstant %float 13
-%float_14 = OpConstant %float 14
-%float_15 = OpConstant %float 15
-%float_16 = OpConstant %float 16
 %false = OpConstantFalse %bool
 %_ptr_Uniform_mat2v2float = OpTypePointer Uniform %mat2v2float
 %int = OpTypeInt 32 1
 %int_0 = OpConstant %int 0
 %v2bool = OpTypeVector %bool 2
-%v3bool = OpTypeVector %bool 3
+%mat3v2float = OpTypeMatrix %v2float 3
 %_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
 %int_1 = OpConstant %int 1
-%v4bool = OpTypeVector %bool 4
+%float_7 = OpConstant %float 7
+%float_8 = OpConstant %float 8
+%float_9 = OpConstant %float 9
+%v3bool = OpTypeVector %bool 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %int_2 = OpConstant %int 2
@@ -114,292 +89,92 @@
 %27 = OpFunctionParameter %_ptr_Function_v2float
 %28 = OpLabel
 %testMatrix2x3 = OpVariable %_ptr_Function_mat2v3float Function
-%testMatrix2x4 = OpVariable %_ptr_Function_mat2v4float Function
-%testMatrix3x2 = OpVariable %_ptr_Function_mat3v2float Function
-%testMatrix3x4 = OpVariable %_ptr_Function_mat3v4float Function
-%testMatrix4x2 = OpVariable %_ptr_Function_mat4v2float Function
-%testMatrix4x3 = OpVariable %_ptr_Function_mat4v3float Function
-%testMatrix4x4 = OpVariable %_ptr_Function_mat4v4float Function
-%310 = OpVariable %_ptr_Function_v4float Function
+%115 = OpVariable %_ptr_Function_v4float Function
 %38 = OpCompositeConstruct %v3float %float_1 %float_2 %float_3
 %39 = OpCompositeConstruct %v3float %float_4 %float_5 %float_6
 %40 = OpCompositeConstruct %mat2v3float %38 %39
 OpStore %testMatrix2x3 %40
-%46 = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
-%47 = OpCompositeConstruct %v4float %float_5 %float_6 %float_7 %float_8
-%48 = OpCompositeConstruct %mat2v4float %46 %47
-OpStore %testMatrix2x4 %48
-%52 = OpCompositeConstruct %v2float %float_1 %float_2
-%53 = OpCompositeConstruct %v2float %float_3 %float_4
-%54 = OpCompositeConstruct %v2float %float_5 %float_6
-%55 = OpCompositeConstruct %mat3v2float %52 %53 %54
-OpStore %testMatrix3x2 %55
-%63 = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
-%64 = OpCompositeConstruct %v4float %float_5 %float_6 %float_7 %float_8
-%65 = OpCompositeConstruct %v4float %float_9 %float_10 %float_11 %float_12
-%66 = OpCompositeConstruct %mat3v4float %63 %64 %65
-OpStore %testMatrix3x4 %66
-%70 = OpCompositeConstruct %v2float %float_1 %float_2
-%71 = OpCompositeConstruct %v2float %float_3 %float_4
-%72 = OpCompositeConstruct %v2float %float_5 %float_6
-%73 = OpCompositeConstruct %v2float %float_7 %float_8
-%74 = OpCompositeConstruct %mat4v2float %70 %71 %72 %73
-OpStore %testMatrix4x2 %74
-%78 = OpCompositeConstruct %v3float %float_1 %float_2 %float_3
-%79 = OpCompositeConstruct %v3float %float_4 %float_5 %float_6
-%80 = OpCompositeConstruct %v3float %float_7 %float_8 %float_9
-%81 = OpCompositeConstruct %v3float %float_10 %float_11 %float_12
-%82 = OpCompositeConstruct %mat4v3float %78 %79 %80 %81
-OpStore %testMatrix4x3 %82
-%90 = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
-%91 = OpCompositeConstruct %v4float %float_5 %float_6 %float_7 %float_8
-%92 = OpCompositeConstruct %v4float %float_9 %float_10 %float_11 %float_12
-%93 = OpCompositeConstruct %v4float %float_13 %float_14 %float_15 %float_16
-%94 = OpCompositeConstruct %mat4v4float %90 %91 %92 %93
-OpStore %testMatrix4x4 %94
-%97 = OpAccessChain %_ptr_Uniform_mat2v2float %10 %int_0
-%101 = OpLoad %mat2v2float %97
-%96 = OpTranspose %mat2v2float %101
-%102 = OpCompositeConstruct %v2float %float_1 %float_3
-%103 = OpCompositeConstruct %v2float %float_2 %float_4
-%104 = OpCompositeConstruct %mat2v2float %102 %103
-%106 = OpCompositeExtract %v2float %96 0
-%107 = OpCompositeExtract %v2float %104 0
-%108 = OpFOrdEqual %v2bool %106 %107
-%109 = OpAll %bool %108
-%110 = OpCompositeExtract %v2float %96 1
-%111 = OpCompositeExtract %v2float %104 1
-%112 = OpFOrdEqual %v2bool %110 %111
-%113 = OpAll %bool %112
-%114 = OpLogicalAnd %bool %109 %113
-OpSelectionMerge %116 None
-OpBranchConditional %114 %115 %116
-%115 = OpLabel
-%118 = OpLoad %mat2v3float %testMatrix2x3
-%117 = OpTranspose %mat3v2float %118
-%119 = OpCompositeConstruct %v2float %float_1 %float_4
-%120 = OpCompositeConstruct %v2float %float_2 %float_5
-%121 = OpCompositeConstruct %v2float %float_3 %float_6
-%122 = OpCompositeConstruct %mat3v2float %119 %120 %121
-%123 = OpCompositeExtract %v2float %117 0
-%124 = OpCompositeExtract %v2float %122 0
-%125 = OpFOrdEqual %v2bool %123 %124
-%126 = OpAll %bool %125
-%127 = OpCompositeExtract %v2float %117 1
-%128 = OpCompositeExtract %v2float %122 1
-%129 = OpFOrdEqual %v2bool %127 %128
-%130 = OpAll %bool %129
-%131 = OpLogicalAnd %bool %126 %130
-%132 = OpCompositeExtract %v2float %117 2
-%133 = OpCompositeExtract %v2float %122 2
-%134 = OpFOrdEqual %v2bool %132 %133
-%135 = OpAll %bool %134
-%136 = OpLogicalAnd %bool %131 %135
-OpBranch %116
-%116 = OpLabel
-%137 = OpPhi %bool %false %28 %136 %115
-OpSelectionMerge %139 None
-OpBranchConditional %137 %138 %139
-%138 = OpLabel
-%141 = OpLoad %mat2v4float %testMatrix2x4
-%140 = OpTranspose %mat4v2float %141
-%142 = OpCompositeConstruct %v2float %float_1 %float_5
-%143 = OpCompositeConstruct %v2float %float_2 %float_6
-%144 = OpCompositeConstruct %v2float %float_3 %float_7
-%145 = OpCompositeConstruct %v2float %float_4 %float_8
-%146 = OpCompositeConstruct %mat4v2float %142 %143 %144 %145
-%147 = OpCompositeExtract %v2float %140 0
-%148 = OpCompositeExtract %v2float %146 0
-%149 = OpFOrdEqual %v2bool %147 %148
-%150 = OpAll %bool %149
-%151 = OpCompositeExtract %v2float %140 1
-%152 = OpCompositeExtract %v2float %146 1
-%153 = OpFOrdEqual %v2bool %151 %152
-%154 = OpAll %bool %153
-%155 = OpLogicalAnd %bool %150 %154
-%156 = OpCompositeExtract %v2float %140 2
-%157 = OpCompositeExtract %v2float %146 2
-%158 = OpFOrdEqual %v2bool %156 %157
-%159 = OpAll %bool %158
-%160 = OpLogicalAnd %bool %155 %159
-%161 = OpCompositeExtract %v2float %140 3
-%162 = OpCompositeExtract %v2float %146 3
-%163 = OpFOrdEqual %v2bool %161 %162
-%164 = OpAll %bool %163
-%165 = OpLogicalAnd %bool %160 %164
-OpBranch %139
-%139 = OpLabel
-%166 = OpPhi %bool %false %116 %165 %138
-OpSelectionMerge %168 None
-OpBranchConditional %166 %167 %168
-%167 = OpLabel
-%170 = OpLoad %mat3v2float %testMatrix3x2
-%169 = OpTranspose %mat2v3float %170
-%171 = OpCompositeConstruct %v3float %float_1 %float_3 %float_5
-%172 = OpCompositeConstruct %v3float %float_2 %float_4 %float_6
-%173 = OpCompositeConstruct %mat2v3float %171 %172
-%175 = OpCompositeExtract %v3float %169 0
-%176 = OpCompositeExtract %v3float %173 0
-%177 = OpFOrdEqual %v3bool %175 %176
-%178 = OpAll %bool %177
-%179 = OpCompositeExtract %v3float %169 1
-%180 = OpCompositeExtract %v3float %173 1
-%181 = OpFOrdEqual %v3bool %179 %180
-%182 = OpAll %bool %181
-%183 = OpLogicalAnd %bool %178 %182
-OpBranch %168
-%168 = OpLabel
-%184 = OpPhi %bool %false %139 %183 %167
-OpSelectionMerge %186 None
-OpBranchConditional %184 %185 %186
-%185 = OpLabel
-%188 = OpAccessChain %_ptr_Uniform_mat3v3float %10 %int_1
-%191 = OpLoad %mat3v3float %188
-%187 = OpTranspose %mat3v3float %191
-%192 = OpCompositeConstruct %v3float %float_1 %float_4 %float_7
-%193 = OpCompositeConstruct %v3float %float_2 %float_5 %float_8
-%194 = OpCompositeConstruct %v3float %float_3 %float_6 %float_9
-%195 = OpCompositeConstruct %mat3v3float %192 %193 %194
-%196 = OpCompositeExtract %v3float %187 0
-%197 = OpCompositeExtract %v3float %195 0
-%198 = OpFOrdEqual %v3bool %196 %197
-%199 = OpAll %bool %198
-%200 = OpCompositeExtract %v3float %187 1
-%201 = OpCompositeExtract %v3float %195 1
-%202 = OpFOrdEqual %v3bool %200 %201
-%203 = OpAll %bool %202
-%204 = OpLogicalAnd %bool %199 %203
-%205 = OpCompositeExtract %v3float %187 2
-%206 = OpCompositeExtract %v3float %195 2
-%207 = OpFOrdEqual %v3bool %205 %206
-%208 = OpAll %bool %207
-%209 = OpLogicalAnd %bool %204 %208
-OpBranch %186
-%186 = OpLabel
-%210 = OpPhi %bool %false %168 %209 %185
-OpSelectionMerge %212 None
-OpBranchConditional %210 %211 %212
-%211 = OpLabel
-%214 = OpLoad %mat3v4float %testMatrix3x4
-%213 = OpTranspose %mat4v3float %214
-%215 = OpCompositeConstruct %v3float %float_1 %float_5 %float_9
-%216 = OpCompositeConstruct %v3float %float_2 %float_6 %float_10
-%217 = OpCompositeConstruct %v3float %float_3 %float_7 %float_11
-%218 = OpCompositeConstruct %v3float %float_4 %float_8 %float_12
-%219 = OpCompositeConstruct %mat4v3float %215 %216 %217 %218
-%220 = OpCompositeExtract %v3float %213 0
-%221 = OpCompositeExtract %v3float %219 0
-%222 = OpFOrdEqual %v3bool %220 %221
-%223 = OpAll %bool %222
-%224 = OpCompositeExtract %v3float %213 1
-%225 = OpCompositeExtract %v3float %219 1
-%226 = OpFOrdEqual %v3bool %224 %225
-%227 = OpAll %bool %226
-%228 = OpLogicalAnd %bool %223 %227
-%229 = OpCompositeExtract %v3float %213 2
-%230 = OpCompositeExtract %v3float %219 2
-%231 = OpFOrdEqual %v3bool %229 %230
-%232 = OpAll %bool %231
-%233 = OpLogicalAnd %bool %228 %232
-%234 = OpCompositeExtract %v3float %213 3
-%235 = OpCompositeExtract %v3float %219 3
-%236 = OpFOrdEqual %v3bool %234 %235
-%237 = OpAll %bool %236
-%238 = OpLogicalAnd %bool %233 %237
-OpBranch %212
-%212 = OpLabel
-%239 = OpPhi %bool %false %186 %238 %211
-OpSelectionMerge %241 None
-OpBranchConditional %239 %240 %241
-%240 = OpLabel
-%243 = OpLoad %mat4v2float %testMatrix4x2
-%242 = OpTranspose %mat2v4float %243
-%244 = OpCompositeConstruct %v4float %float_1 %float_3 %float_5 %float_7
-%245 = OpCompositeConstruct %v4float %float_2 %float_4 %float_6 %float_8
-%246 = OpCompositeConstruct %mat2v4float %244 %245
-%248 = OpCompositeExtract %v4float %242 0
-%249 = OpCompositeExtract %v4float %246 0
-%250 = OpFOrdEqual %v4bool %248 %249
-%251 = OpAll %bool %250
-%252 = OpCompositeExtract %v4float %242 1
-%253 = OpCompositeExtract %v4float %246 1
-%254 = OpFOrdEqual %v4bool %252 %253
-%255 = OpAll %bool %254
-%256 = OpLogicalAnd %bool %251 %255
-OpBranch %241
-%241 = OpLabel
-%257 = OpPhi %bool %false %212 %256 %240
-OpSelectionMerge %259 None
-OpBranchConditional %257 %258 %259
-%258 = OpLabel
-%261 = OpLoad %mat4v3float %testMatrix4x3
-%260 = OpTranspose %mat3v4float %261
-%262 = OpCompositeConstruct %v4float %float_1 %float_4 %float_7 %float_10
-%263 = OpCompositeConstruct %v4float %float_2 %float_5 %float_8 %float_11
-%264 = OpCompositeConstruct %v4float %float_3 %float_6 %float_9 %float_12
-%265 = OpCompositeConstruct %mat3v4float %262 %263 %264
-%266 = OpCompositeExtract %v4float %260 0
-%267 = OpCompositeExtract %v4float %265 0
-%268 = OpFOrdEqual %v4bool %266 %267
-%269 = OpAll %bool %268
-%270 = OpCompositeExtract %v4float %260 1
-%271 = OpCompositeExtract %v4float %265 1
-%272 = OpFOrdEqual %v4bool %270 %271
-%273 = OpAll %bool %272
-%274 = OpLogicalAnd %bool %269 %273
-%275 = OpCompositeExtract %v4float %260 2
-%276 = OpCompositeExtract %v4float %265 2
-%277 = OpFOrdEqual %v4bool %275 %276
-%278 = OpAll %bool %277
-%279 = OpLogicalAnd %bool %274 %278
-OpBranch %259
-%259 = OpLabel
-%280 = OpPhi %bool %false %241 %279 %258
-OpSelectionMerge %282 None
-OpBranchConditional %280 %281 %282
-%281 = OpLabel
-%284 = OpLoad %mat4v4float %testMatrix4x4
-%283 = OpTranspose %mat4v4float %284
-%285 = OpCompositeConstruct %v4float %float_1 %float_5 %float_9 %float_13
-%286 = OpCompositeConstruct %v4float %float_2 %float_6 %float_10 %float_14
-%287 = OpCompositeConstruct %v4float %float_3 %float_7 %float_11 %float_15
-%288 = OpCompositeConstruct %v4float %float_4 %float_8 %float_12 %float_16
-%289 = OpCompositeConstruct %mat4v4float %285 %286 %287 %288
-%290 = OpCompositeExtract %v4float %283 0
-%291 = OpCompositeExtract %v4float %289 0
-%292 = OpFOrdEqual %v4bool %290 %291
-%293 = OpAll %bool %292
-%294 = OpCompositeExtract %v4float %283 1
-%295 = OpCompositeExtract %v4float %289 1
-%296 = OpFOrdEqual %v4bool %294 %295
-%297 = OpAll %bool %296
-%298 = OpLogicalAnd %bool %293 %297
-%299 = OpCompositeExtract %v4float %283 2
-%300 = OpCompositeExtract %v4float %289 2
-%301 = OpFOrdEqual %v4bool %299 %300
-%302 = OpAll %bool %301
-%303 = OpLogicalAnd %bool %298 %302
-%304 = OpCompositeExtract %v4float %283 3
-%305 = OpCompositeExtract %v4float %289 3
-%306 = OpFOrdEqual %v4bool %304 %305
-%307 = OpAll %bool %306
-%308 = OpLogicalAnd %bool %303 %307
-OpBranch %282
-%282 = OpLabel
-%309 = OpPhi %bool %false %259 %308 %281
-OpSelectionMerge %314 None
-OpBranchConditional %309 %312 %313
-%312 = OpLabel
-%315 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
-%318 = OpLoad %v4float %315
-OpStore %310 %318
-OpBranch %314
-%313 = OpLabel
-%319 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
-%321 = OpLoad %v4float %319
-OpStore %310 %321
-OpBranch %314
-%314 = OpLabel
-%322 = OpLoad %v4float %310
-OpReturnValue %322
+%43 = OpAccessChain %_ptr_Uniform_mat2v2float %10 %int_0
+%47 = OpLoad %mat2v2float %43
+%42 = OpTranspose %mat2v2float %47
+%48 = OpCompositeConstruct %v2float %float_1 %float_3
+%49 = OpCompositeConstruct %v2float %float_2 %float_4
+%50 = OpCompositeConstruct %mat2v2float %48 %49
+%52 = OpCompositeExtract %v2float %42 0
+%53 = OpCompositeExtract %v2float %50 0
+%54 = OpFOrdEqual %v2bool %52 %53
+%55 = OpAll %bool %54
+%56 = OpCompositeExtract %v2float %42 1
+%57 = OpCompositeExtract %v2float %50 1
+%58 = OpFOrdEqual %v2bool %56 %57
+%59 = OpAll %bool %58
+%60 = OpLogicalAnd %bool %55 %59
+OpSelectionMerge %62 None
+OpBranchConditional %60 %61 %62
+%61 = OpLabel
+%64 = OpLoad %mat2v3float %testMatrix2x3
+%63 = OpTranspose %mat3v2float %64
+%66 = OpCompositeConstruct %v2float %float_1 %float_4
+%67 = OpCompositeConstruct %v2float %float_2 %float_5
+%68 = OpCompositeConstruct %v2float %float_3 %float_6
+%69 = OpCompositeConstruct %mat3v2float %66 %67 %68
+%70 = OpCompositeExtract %v2float %63 0
+%71 = OpCompositeExtract %v2float %69 0
+%72 = OpFOrdEqual %v2bool %70 %71
+%73 = OpAll %bool %72
+%74 = OpCompositeExtract %v2float %63 1
+%75 = OpCompositeExtract %v2float %69 1
+%76 = OpFOrdEqual %v2bool %74 %75
+%77 = OpAll %bool %76
+%78 = OpLogicalAnd %bool %73 %77
+%79 = OpCompositeExtract %v2float %63 2
+%80 = OpCompositeExtract %v2float %69 2
+%81 = OpFOrdEqual %v2bool %79 %80
+%82 = OpAll %bool %81
+%83 = OpLogicalAnd %bool %78 %82
+OpBranch %62
+%62 = OpLabel
+%84 = OpPhi %bool %false %28 %83 %61
+OpSelectionMerge %86 None
+OpBranchConditional %84 %85 %86
+%85 = OpLabel
+%88 = OpAccessChain %_ptr_Uniform_mat3v3float %10 %int_1
+%91 = OpLoad %mat3v3float %88
+%87 = OpTranspose %mat3v3float %91
+%95 = OpCompositeConstruct %v3float %float_1 %float_4 %float_7
+%96 = OpCompositeConstruct %v3float %float_2 %float_5 %float_8
+%97 = OpCompositeConstruct %v3float %float_3 %float_6 %float_9
+%98 = OpCompositeConstruct %mat3v3float %95 %96 %97
+%100 = OpCompositeExtract %v3float %87 0
+%101 = OpCompositeExtract %v3float %98 0
+%102 = OpFOrdEqual %v3bool %100 %101
+%103 = OpAll %bool %102
+%104 = OpCompositeExtract %v3float %87 1
+%105 = OpCompositeExtract %v3float %98 1
+%106 = OpFOrdEqual %v3bool %104 %105
+%107 = OpAll %bool %106
+%108 = OpLogicalAnd %bool %103 %107
+%109 = OpCompositeExtract %v3float %87 2
+%110 = OpCompositeExtract %v3float %98 2
+%111 = OpFOrdEqual %v3bool %109 %110
+%112 = OpAll %bool %111
+%113 = OpLogicalAnd %bool %108 %112
+OpBranch %86
+%86 = OpLabel
+%114 = OpPhi %bool %false %62 %113 %85
+OpSelectionMerge %119 None
+OpBranchConditional %114 %117 %118
+%117 = OpLabel
+%120 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
+%123 = OpLoad %v4float %120
+OpStore %115 %123
+OpBranch %119
+%118 = OpLabel
+%124 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
+%126 = OpLoad %v4float %124
+OpStore %115 %126
+OpBranch %119
+%119 = OpLabel
+%127 = OpLoad %v4float %115
+OpReturnValue %127
 OpFunctionEnd
diff --git a/tests/sksl/intrinsics/Transpose.glsl b/tests/sksl/intrinsics/Transpose.glsl
index 9d09cb4..33db5f6 100644
--- a/tests/sksl/intrinsics/Transpose.glsl
+++ b/tests/sksl/intrinsics/Transpose.glsl
@@ -5,12 +5,6 @@
 uniform vec4 colorGreen;
 uniform vec4 colorRed;
 vec4 main() {
-    const mat2x3 testMatrix2x3 = mat2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
-    const mat2x4 testMatrix2x4 = mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
-    const mat3x2 testMatrix3x2 = mat3x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
-    const mat3x4 testMatrix3x4 = mat3x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
-    const mat4x2 testMatrix4x2 = mat4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
-    const mat4x3 testMatrix4x3 = mat4x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
-    const mat4 testMatrix4x4 = mat4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0);
-    return (((((((transpose(testMatrix2x2) == mat2(1.0, 3.0, 2.0, 4.0) && transpose(testMatrix2x3) == mat3x2(1.0, 4.0, 2.0, 5.0, 3.0, 6.0)) && transpose(testMatrix2x4) == mat4x2(1.0, 5.0, 2.0, 6.0, 3.0, 7.0, 4.0, 8.0)) && transpose(testMatrix3x2) == mat2x3(1.0, 3.0, 5.0, 2.0, 4.0, 6.0)) && transpose(testMatrix3x3) == mat3(1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0)) && transpose(testMatrix3x4) == mat4x3(1.0, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0)) && transpose(testMatrix4x2) == mat2x4(1.0, 3.0, 5.0, 7.0, 2.0, 4.0, 6.0, 8.0)) && transpose(testMatrix4x3) == mat3x4(1.0, 4.0, 7.0, 10.0, 2.0, 5.0, 8.0, 11.0, 3.0, 6.0, 9.0, 12.0)) && transpose(testMatrix4x4) == mat4(1.0, 5.0, 9.0, 13.0, 2.0, 6.0, 10.0, 14.0, 3.0, 7.0, 11.0, 15.0, 4.0, 8.0, 12.0, 16.0) ? colorGreen : colorRed;
+    mat2x3 testMatrix2x3 = mat2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
+    return (transpose(testMatrix2x2) == mat2(1.0, 3.0, 2.0, 4.0) && transpose(testMatrix2x3) == mat3x2(1.0, 4.0, 2.0, 5.0, 3.0, 6.0)) && transpose(testMatrix3x3) == mat3(1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0) ? colorGreen : colorRed;
 }
diff --git a/tests/sksl/intrinsics/Transpose.metal b/tests/sksl/intrinsics/Transpose.metal
index 3788d10..48e40a5 100644
--- a/tests/sksl/intrinsics/Transpose.metal
+++ b/tests/sksl/intrinsics/Transpose.metal
@@ -19,26 +19,8 @@
 thread bool operator==(const float3x2 left, const float3x2 right);
 thread bool operator!=(const float3x2 left, const float3x2 right);
 
-thread bool operator==(const float4x2 left, const float4x2 right);
-thread bool operator!=(const float4x2 left, const float4x2 right);
-
-thread bool operator==(const float2x3 left, const float2x3 right);
-thread bool operator!=(const float2x3 left, const float2x3 right);
-
 thread bool operator==(const float3x3 left, const float3x3 right);
 thread bool operator!=(const float3x3 left, const float3x3 right);
-
-thread bool operator==(const float4x3 left, const float4x3 right);
-thread bool operator!=(const float4x3 left, const float4x3 right);
-
-thread bool operator==(const float2x4 left, const float2x4 right);
-thread bool operator!=(const float2x4 left, const float2x4 right);
-
-thread bool operator==(const float3x4 left, const float3x4 right);
-thread bool operator!=(const float3x4 left, const float3x4 right);
-
-thread bool operator==(const float4x4 left, const float4x4 right);
-thread bool operator!=(const float4x4 left, const float4x4 right);
 thread bool operator==(const float2x2 left, const float2x2 right) {
     return all(left[0] == right[0]) &&
            all(left[1] == right[1]);
@@ -54,22 +36,6 @@
 thread bool operator!=(const float3x2 left, const float3x2 right) {
     return !(left == right);
 }
-thread bool operator==(const float4x2 left, const float4x2 right) {
-    return all(left[0] == right[0]) &&
-           all(left[1] == right[1]) &&
-           all(left[2] == right[2]) &&
-           all(left[3] == right[3]);
-}
-thread bool operator!=(const float4x2 left, const float4x2 right) {
-    return !(left == right);
-}
-thread bool operator==(const float2x3 left, const float2x3 right) {
-    return all(left[0] == right[0]) &&
-           all(left[1] == right[1]);
-}
-thread bool operator!=(const float2x3 left, const float2x3 right) {
-    return !(left == right);
-}
 thread bool operator==(const float3x3 left, const float3x3 right) {
     return all(left[0] == right[0]) &&
            all(left[1] == right[1]) &&
@@ -78,49 +44,10 @@
 thread bool operator!=(const float3x3 left, const float3x3 right) {
     return !(left == right);
 }
-thread bool operator==(const float4x3 left, const float4x3 right) {
-    return all(left[0] == right[0]) &&
-           all(left[1] == right[1]) &&
-           all(left[2] == right[2]) &&
-           all(left[3] == right[3]);
-}
-thread bool operator!=(const float4x3 left, const float4x3 right) {
-    return !(left == right);
-}
-thread bool operator==(const float2x4 left, const float2x4 right) {
-    return all(left[0] == right[0]) &&
-           all(left[1] == right[1]);
-}
-thread bool operator!=(const float2x4 left, const float2x4 right) {
-    return !(left == right);
-}
-thread bool operator==(const float3x4 left, const float3x4 right) {
-    return all(left[0] == right[0]) &&
-           all(left[1] == right[1]) &&
-           all(left[2] == right[2]);
-}
-thread bool operator!=(const float3x4 left, const float3x4 right) {
-    return !(left == right);
-}
-thread bool operator==(const float4x4 left, const float4x4 right) {
-    return all(left[0] == right[0]) &&
-           all(left[1] == right[1]) &&
-           all(left[2] == right[2]) &&
-           all(left[3] == right[3]);
-}
-thread bool operator!=(const float4x4 left, const float4x4 right) {
-    return !(left == right);
-}
 fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
     Outputs _out;
     (void)_out;
-    const float2x3 testMatrix2x3 = float2x3(float3(1.0, 2.0, 3.0), float3(4.0, 5.0, 6.0));
-    const float2x4 testMatrix2x4 = float2x4(float4(1.0, 2.0, 3.0, 4.0), float4(5.0, 6.0, 7.0, 8.0));
-    const float3x2 testMatrix3x2 = float3x2(float2(1.0, 2.0), float2(3.0, 4.0), float2(5.0, 6.0));
-    const float3x4 testMatrix3x4 = float3x4(float4(1.0, 2.0, 3.0, 4.0), float4(5.0, 6.0, 7.0, 8.0), float4(9.0, 10.0, 11.0, 12.0));
-    const float4x2 testMatrix4x2 = float4x2(float2(1.0, 2.0), float2(3.0, 4.0), float2(5.0, 6.0), float2(7.0, 8.0));
-    const float4x3 testMatrix4x3 = float4x3(float3(1.0, 2.0, 3.0), float3(4.0, 5.0, 6.0), float3(7.0, 8.0, 9.0), float3(10.0, 11.0, 12.0));
-    const float4x4 testMatrix4x4 = float4x4(float4(1.0, 2.0, 3.0, 4.0), float4(5.0, 6.0, 7.0, 8.0), float4(9.0, 10.0, 11.0, 12.0), float4(13.0, 14.0, 15.0, 16.0));
-    _out.sk_FragColor = (((((((transpose(_uniforms.testMatrix2x2) == float2x2(float2(1.0, 3.0), float2(2.0, 4.0)) && transpose(testMatrix2x3) == float3x2(float2(1.0, 4.0), float2(2.0, 5.0), float2(3.0, 6.0))) && transpose(testMatrix2x4) == float4x2(float2(1.0, 5.0), float2(2.0, 6.0), float2(3.0, 7.0), float2(4.0, 8.0))) && transpose(testMatrix3x2) == float2x3(float3(1.0, 3.0, 5.0), float3(2.0, 4.0, 6.0))) && transpose(_uniforms.testMatrix3x3) == float3x3(float3(1.0, 4.0, 7.0), float3(2.0, 5.0, 8.0), float3(3.0, 6.0, 9.0))) && transpose(testMatrix3x4) == float4x3(float3(1.0, 5.0, 9.0), float3(2.0, 6.0, 10.0), float3(3.0, 7.0, 11.0), float3(4.0, 8.0, 12.0))) && transpose(testMatrix4x2) == float2x4(float4(1.0, 3.0, 5.0, 7.0), float4(2.0, 4.0, 6.0, 8.0))) && transpose(testMatrix4x3) == float3x4(float4(1.0, 4.0, 7.0, 10.0), float4(2.0, 5.0, 8.0, 11.0), float4(3.0, 6.0, 9.0, 12.0))) && transpose(testMatrix4x4) == float4x4(float4(1.0, 5.0, 9.0, 13.0), float4(2.0, 6.0, 10.0, 14.0), float4(3.0, 7.0, 11.0, 15.0), float4(4.0, 8.0, 12.0, 16.0)) ? _uniforms.colorGreen : _uniforms.colorRed;
+    float2x3 testMatrix2x3 = float2x3(float3(1.0, 2.0, 3.0), float3(4.0, 5.0, 6.0));
+    _out.sk_FragColor = (transpose(_uniforms.testMatrix2x2) == float2x2(float2(1.0, 3.0), float2(2.0, 4.0)) && transpose(testMatrix2x3) == float3x2(float2(1.0, 4.0), float2(2.0, 5.0), float2(3.0, 6.0))) && transpose(_uniforms.testMatrix3x3) == float3x3(float3(1.0, 4.0, 7.0), float3(2.0, 5.0, 8.0), float3(3.0, 6.0, 9.0)) ? _uniforms.colorGreen : _uniforms.colorRed;
     return _out;
 }