Fix crash when inverse() is passed a constant variable.

Optimization for inverse() uses some custom logic which neglected to
look up the value of a constant variable before assuming it was a
FloatLiteral; our tests were not exercising this case.

Change-Id: Idc8f2cc24f6a8df7234062f5f15e8c39a08457e5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/440260
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/resources/sksl/intrinsics/Inverse.sksl b/resources/sksl/intrinsics/Inverse.sksl
index 1d926fa..6979442 100644
--- a/resources/sksl/intrinsics/Inverse.sksl
+++ b/resources/sksl/intrinsics/Inverse.sksl
@@ -1,11 +1,12 @@
 uniform half4 colorGreen, colorRed;
 
 half4 main(float2 xy) {
+    const half2x2 mat2x2 = half2x2(1, 2, 3, 4);
     half2x2 inv2x2 = half2x2(-2, 1, 1.5, -0.5);
     half3x3 inv3x3 = half3x3(-24, 18, 5, 20, -15, -4, -5, 4, 1);
     half4x4 inv4x4 = half4x4(-2, -0.5, 1, 0.5, 1, 0.5, 0, -0.5, -8, -1, 2, 2, 3, 0.5, -1, -0.5);
 
-    return (inverse(half2x2(1, 2, 3, 4)) == inv2x2 &&
+    return (inverse(mat2x2) == inv2x2 &&
             inverse(half3x3(1, 2, 3, 0, 1, 4, 5, 6, 0)) == inv3x3 &&
             inverse(half4x4(1, 0, 0, 1, 0, 2, 1, 2, 2, 1, 0, 1, 2, 0, 1, 4)) == inv4x4 &&
             inverse(half3x3(1, 2, 3, 4, 5, 6, 7, 8, 9)) != inv3x3)
diff --git a/src/sksl/ir/SkSLFunctionCall.cpp b/src/sksl/ir/SkSLFunctionCall.cpp
index 54c6740..18ac352 100644
--- a/src/sksl/ir/SkSLFunctionCall.cpp
+++ b/src/sksl/ir/SkSLFunctionCall.cpp
@@ -424,6 +424,13 @@
 static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& context,
                                                            IntrinsicKind intrinsic,
                                                            const ExpressionArray& arguments) {
+    // Helper function for accessing a matrix argument by column and row.
+    const Expression* matrix = nullptr;
+    auto M = [&](int c, int r) -> float {
+        int index = (matrix->type().rows() * c) + r;
+        return matrix->getConstantSubexpression(index)->as<FloatLiteral>().value();
+    };
+
     using namespace SkSL::dsl;
     switch (intrinsic) {
         // 8.1 : Angle and Trigonometry Functions
@@ -610,13 +617,8 @@
         case k_matrixCompMult_IntrinsicKind:
             return evaluate_pairwise_intrinsic(context, arguments,
                                                Intrinsics::evaluate_matrixCompMult);
-        // Not supported until GLSL 1.40. Poly-filled by SkSL:
         case k_inverse_IntrinsicKind: {
-            auto M = [&](int c, int r) -> float {
-                int index = (arguments[0]->type().rows() * c) + r;
-                return arguments[0]->getConstantSubexpression(index)->as<FloatLiteral>().value();
-            };
-            // Our matrix inverse is adapted from the logic in GLSLCodeGenerator::writeInverseHack.
+            matrix = ConstantFolder::GetConstantValueForVariable(*arguments[0]);
             switch (arguments[0]->type().slotCount()) {
                 case 4: {
                     float mat2[4] = {M(0, 0), M(0, 1),