Enable SPIR-V disassembly output from skslc.

We now have SPIR-V golden outputs for `blend` and `shared` tests.
This exposes a handful of SPIR-V limitations for us to address.

Change-Id: Ie5278889b8a61432403d06231b17765885bee0ac
Bug: skia:10694
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/337182
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/BUILD.gn b/BUILD.gn
index 6377dfb..e53b4f8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -575,6 +575,7 @@
     deps = [
       ":run_sksllex",
       "//third_party/spirv-tools:spvtools",
+      "//third_party/spirv-tools:spvtools_val",
     ]
   }
 
@@ -758,6 +759,15 @@
     lang = "--metal"
     settings = "--settings"
   }
+  compile_sksl("spirv_tests") {
+    sources = sksl_spirv_tests_sources
+    outputPatterns = [ [
+          "/golden/",
+          ".spirv",
+        ] ]
+    lang = "--spirv"
+    settings = "--settings"
+  }
 } else {
   group("compile_sksl_fp_tests") {
   }
@@ -767,6 +777,8 @@
   }
   group("compile_sksl_metal_tests") {
   }
+  group("compile_sksl_spirv_tests") {
+  }
 }
 
 optional("gpu") {
@@ -777,6 +789,7 @@
     ":compile_sksl_glsl_nosettings_tests",
     ":compile_sksl_glsl_tests",
     ":compile_sksl_metal_tests",
+    ":compile_sksl_spirv_tests",
     ":dehydrate_sksl",
     ":run_sksllex",
   ]
diff --git a/gn/compile_sksl_tests.py b/gn/compile_sksl_tests.py
index a87cf99..806c243 100755
--- a/gn/compile_sksl_tests.py
+++ b/gn/compile_sksl_tests.py
@@ -21,6 +21,9 @@
     except OSError:
         pass
 
+def extensionForSpirvAsm(ext):
+    return ext if (ext == 'frag' or ext == 'vert' or ext == 'geom') else 'frag'
+
 if settings != "--settings" and settings != "--nosettings":
     sys.exit("### Expected --settings or --nosettings, got " + settings)
 
@@ -29,7 +32,7 @@
 
 # Convert the list of command-line inputs into a worklist file sfor skslc.
 for input in inputs:
-    noExt, _ = os.path.splitext(input)
+    noExt, ext = os.path.splitext(input)
     head, tail = os.path.split(noExt)
     targetDir = os.path.join(head, "golden")
     if not os.path.isdir(targetDir):
@@ -56,8 +59,12 @@
         worklist.write(input + "\n")
         worklist.write(target + ".metal\n")
         worklist.write(settings + "\n\n")
+    elif lang == "--spirv":
+        worklist.write(input + "\n")
+        worklist.write(target + ".asm." + extensionForSpirvAsm(ext) + "\n")
+        worklist.write(settings + "\n\n")
     else:
-        sys.exit("### Expected one of: --fp --glsl --metal, got " + lang)
+        sys.exit("### Expected one of: --fp --glsl --metal --spirv, got " + lang)
 
 # Invoke skslc, passing in the worklist.
 worklist.close()
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index eee26d4..be938f1 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -375,3 +375,7 @@
 # generate a .metal output file.
 sksl_metal_tests_sources =
     sksl_metal_tests + sksl_blend_tests + sksl_shared_tests
+
+# Tests in sksl_spirv_tests_sources will be compiled with --settings on, and are expected to
+# generate a .asm.(frag|vert|geom) output file.
+sksl_spirv_tests_sources = sksl_blend_tests + sksl_shared_tests
diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp
index 39851f7..5c35b64 100644
--- a/src/sksl/SkSLMain.cpp
+++ b/src/sksl/SkSLMain.cpp
@@ -17,6 +17,8 @@
 #include "src/sksl/ir/SkSLEnum.h"
 #include "src/sksl/ir/SkSLUnresolvedFunction.h"
 
+#include "spirv-tools/libspirv.hpp"
+
 #include <fstream>
 #include <limits.h>
 #include <stdarg.h>
@@ -38,6 +40,7 @@
     kCompileError = 1,
     kInputError = 2,
     kOutputError = 3,
+    kConfigurationError = 4,
 };
 
 // Given the path to a file (e.g. src/gpu/effects/GrFooFragmentProcessor.fp) and the expected
@@ -310,6 +313,28 @@
                 [](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
                     return compiler.toSPIRV(program, out);
                 });
+    } else if (outputPath.endsWith(".asm.frag") || outputPath.endsWith(".asm.vert") ||
+               outputPath.endsWith(".asm.geom")) {
+        return compileProgram(
+                SkSL::Compiler::kNone_Flags,
+                [](SkSL::Compiler& compiler, SkSL::Program& program, SkSL::OutputStream& out) {
+                    // Compile program to SPIR-V assembly in a string-stream.
+                    SkSL::StringStream assembly;
+                    if (!compiler.toSPIRV(program, assembly)) {
+                        return false;
+                    }
+                    // Convert the string-stream to a SPIR-V disassembly.
+                    spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
+                    const SkSL::String& spirv(assembly.str());
+                    std::string disassembly;
+                    if (!tools.Disassemble((const uint32_t*)spirv.data(),
+                                           spirv.size() / 4, &disassembly)) {
+                        return false;
+                    }
+                    // Finally, write the disassembly to our output stream.
+                    out.write(disassembly.data(), disassembly.size());
+                    return true;
+                });
     } else if (outputPath.endsWith(".glsl")) {
         return compileProgram(
                 SkSL::Compiler::kNone_Flags,
@@ -364,8 +389,9 @@
             return ResultCode::kOutputError;
         }
     } else {
-        printf("expected output filename to end with '.spirv', '.glsl', '.cpp', '.h', or '.metal'");
-        return ResultCode::kInputError;  // the "output filename" is still an input argument
+        printf("expected output path to end with one of: .glsl, .metal, .spirv, .asm.frag, "
+               ".asm.vert, .asm.geom, .cpp, .h (got '%s')\n", outputPath.c_str());
+        return ResultCode::kConfigurationError;
     }
     return ResultCode::kSuccess;
 }
@@ -378,7 +404,7 @@
     if (!inputPath.endsWith(".worklist")) {
         printf("expected .worklist file, found: %s\n\n", worklistPath);
         show_usage();
-        return ResultCode::kInputError;
+        return ResultCode::kConfigurationError;
     }
 
     // The worklist contains one line per argument to pass to skslc. When a blank line is reached,
diff --git a/tests/sksl/blend/golden/BlendClear.asm.frag b/tests/sksl/blend/golden/BlendClear.asm.frag
new file mode 100644
index 0000000..2471f4e
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendClear.asm.frag
@@ -0,0 +1,36 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%float_0 = OpConstant %float 0
+%16 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %14
+%15 = OpLabel
+OpStore %sk_FragColor %16
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendColor.asm.frag b/tests/sksl/blend/golden/BlendColor.asm.frag
new file mode 100644
index 0000000..c450789
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendColor.asm.frag
@@ -0,0 +1,275 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_color "_0_blend_color"
+OpName %_1_alpha "_1_alpha"
+OpName %_2_sda "_2_sda"
+OpName %_3_dsa "_3_dsa"
+OpName %_4_blend_set_color_luminance "_4_blend_set_color_luminance"
+OpName %_5_15_blend_color_luminance "_5_15_blend_color_luminance"
+OpName %_6_lum "_6_lum"
+OpName %_7_16_blend_color_luminance "_7_16_blend_color_luminance"
+OpName %_8_result "_8_result"
+OpName %_9_minComp "_9_minComp"
+OpName %_10_maxComp "_10_maxComp"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %52 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %56 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %63 RelaxedPrecision
+OpDecorate %65 RelaxedPrecision
+OpDecorate %67 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
+OpDecorate %74 RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %84 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %91 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %95 RelaxedPrecision
+OpDecorate %97 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %106 RelaxedPrecision
+OpDecorate %110 RelaxedPrecision
+OpDecorate %111 RelaxedPrecision
+OpDecorate %118 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %129 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+OpDecorate %137 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %140 RelaxedPrecision
+OpDecorate %141 RelaxedPrecision
+OpDecorate %142 RelaxedPrecision
+OpDecorate %144 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %146 RelaxedPrecision
+OpDecorate %150 RelaxedPrecision
+OpDecorate %152 RelaxedPrecision
+OpDecorate %154 RelaxedPrecision
+OpDecorate %155 RelaxedPrecision
+OpDecorate %156 RelaxedPrecision
+OpDecorate %158 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function_float = OpTypePointer Function %float
+%v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+%float_0_300000012 = OpConstant %float 0.300000012
+%float_0_589999974 = OpConstant %float 0.589999974
+%float_0_109999999 = OpConstant %float 0.109999999
+%42 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%51 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%false = OpConstantFalse %bool
+%float_0 = OpConstant %float 0
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_color = OpVariable %_ptr_Function_v4float Function
+%_1_alpha = OpVariable %_ptr_Function_float Function
+%_2_sda = OpVariable %_ptr_Function_v3float Function
+%_3_dsa = OpVariable %_ptr_Function_v3float Function
+%_4_blend_set_color_luminance = OpVariable %_ptr_Function_v3float Function
+%_5_15_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_6_lum = OpVariable %_ptr_Function_float Function
+%_7_16_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_8_result = OpVariable %_ptr_Function_v3float Function
+%_9_minComp = OpVariable %_ptr_Function_float Function
+%_10_maxComp = OpVariable %_ptr_Function_float Function
+%114 = OpVariable %_ptr_Function_v3float Function
+%20 = OpLoad %v4float %dst
+%21 = OpCompositeExtract %float %20 3
+%22 = OpLoad %v4float %src
+%23 = OpCompositeExtract %float %22 3
+%24 = OpFMul %float %21 %23
+OpStore %_1_alpha %24
+%28 = OpLoad %v4float %src
+%29 = OpVectorShuffle %v3float %28 %28 0 1 2
+%30 = OpLoad %v4float %dst
+%31 = OpCompositeExtract %float %30 3
+%32 = OpVectorTimesScalar %v3float %29 %31
+OpStore %_2_sda %32
+%34 = OpLoad %v4float %dst
+%35 = OpVectorShuffle %v3float %34 %34 0 1 2
+%36 = OpLoad %v4float %src
+%37 = OpCompositeExtract %float %36 3
+%38 = OpVectorTimesScalar %v3float %35 %37
+OpStore %_3_dsa %38
+%46 = OpLoad %v3float %_3_dsa
+%41 = OpDot %float %42 %46
+OpStore %_5_15_blend_color_luminance %41
+%48 = OpLoad %float %_5_15_blend_color_luminance
+OpStore %_6_lum %48
+%52 = OpLoad %v3float %_2_sda
+%50 = OpDot %float %51 %52
+OpStore %_7_16_blend_color_luminance %50
+%54 = OpLoad %float %_6_lum
+%55 = OpLoad %float %_7_16_blend_color_luminance
+%56 = OpFSub %float %54 %55
+%57 = OpLoad %v3float %_2_sda
+%58 = OpCompositeConstruct %v3float %56 %56 %56
+%59 = OpFAdd %v3float %58 %57
+OpStore %_8_result %59
+%63 = OpLoad %v3float %_8_result
+%64 = OpCompositeExtract %float %63 0
+%65 = OpLoad %v3float %_8_result
+%66 = OpCompositeExtract %float %65 1
+%62 = OpExtInst %float %1 FMin %64 %66
+%67 = OpLoad %v3float %_8_result
+%68 = OpCompositeExtract %float %67 2
+%61 = OpExtInst %float %1 FMin %62 %68
+OpStore %_9_minComp %61
+%72 = OpLoad %v3float %_8_result
+%73 = OpCompositeExtract %float %72 0
+%74 = OpLoad %v3float %_8_result
+%75 = OpCompositeExtract %float %74 1
+%71 = OpExtInst %float %1 FMax %73 %75
+%76 = OpLoad %v3float %_8_result
+%77 = OpCompositeExtract %float %76 2
+%70 = OpExtInst %float %1 FMax %71 %77
+OpStore %_10_maxComp %70
+%79 = OpLoad %float %_9_minComp
+%81 = OpFOrdLessThan %bool %79 %float_0
+OpSelectionMerge %83 None
+OpBranchConditional %81 %82 %83
+%82 = OpLabel
+%84 = OpLoad %float %_6_lum
+%85 = OpLoad %float %_9_minComp
+%86 = OpFOrdNotEqual %bool %84 %85
+OpBranch %83
+%83 = OpLabel
+%87 = OpPhi %bool %false %15 %86 %82
+OpSelectionMerge %89 None
+OpBranchConditional %87 %88 %89
+%88 = OpLabel
+%90 = OpLoad %float %_6_lum
+%91 = OpLoad %v3float %_8_result
+%92 = OpLoad %float %_6_lum
+%93 = OpCompositeConstruct %v3float %92 %92 %92
+%94 = OpFSub %v3float %91 %93
+%95 = OpLoad %float %_6_lum
+%96 = OpVectorTimesScalar %v3float %94 %95
+%97 = OpLoad %float %_6_lum
+%98 = OpLoad %float %_9_minComp
+%99 = OpFSub %float %97 %98
+%101 = OpFDiv %float %float_1 %99
+%102 = OpVectorTimesScalar %v3float %96 %101
+%103 = OpCompositeConstruct %v3float %90 %90 %90
+%104 = OpFAdd %v3float %103 %102
+OpStore %_8_result %104
+OpBranch %89
+%89 = OpLabel
+%105 = OpLoad %float %_10_maxComp
+%106 = OpLoad %float %_1_alpha
+%107 = OpFOrdGreaterThan %bool %105 %106
+OpSelectionMerge %109 None
+OpBranchConditional %107 %108 %109
+%108 = OpLabel
+%110 = OpLoad %float %_10_maxComp
+%111 = OpLoad %float %_6_lum
+%112 = OpFOrdNotEqual %bool %110 %111
+OpBranch %109
+%109 = OpLabel
+%113 = OpPhi %bool %false %89 %112 %108
+OpSelectionMerge %117 None
+OpBranchConditional %113 %115 %116
+%115 = OpLabel
+%118 = OpLoad %float %_6_lum
+%119 = OpLoad %v3float %_8_result
+%120 = OpLoad %float %_6_lum
+%121 = OpCompositeConstruct %v3float %120 %120 %120
+%122 = OpFSub %v3float %119 %121
+%123 = OpLoad %float %_1_alpha
+%124 = OpLoad %float %_6_lum
+%125 = OpFSub %float %123 %124
+%126 = OpVectorTimesScalar %v3float %122 %125
+%127 = OpLoad %float %_10_maxComp
+%128 = OpLoad %float %_6_lum
+%129 = OpFSub %float %127 %128
+%130 = OpFDiv %float %float_1 %129
+%131 = OpVectorTimesScalar %v3float %126 %130
+%132 = OpCompositeConstruct %v3float %118 %118 %118
+%133 = OpFAdd %v3float %132 %131
+OpStore %114 %133
+OpBranch %117
+%116 = OpLabel
+%134 = OpLoad %v3float %_8_result
+OpStore %114 %134
+OpBranch %117
+%117 = OpLabel
+%135 = OpLoad %v3float %114
+OpStore %_4_blend_set_color_luminance %135
+%136 = OpLoad %v3float %_4_blend_set_color_luminance
+%137 = OpLoad %v4float %dst
+%138 = OpVectorShuffle %v3float %137 %137 0 1 2
+%139 = OpFAdd %v3float %136 %138
+%140 = OpLoad %v3float %_3_dsa
+%141 = OpFSub %v3float %139 %140
+%142 = OpLoad %v4float %src
+%143 = OpVectorShuffle %v3float %142 %142 0 1 2
+%144 = OpFAdd %v3float %141 %143
+%145 = OpLoad %v3float %_2_sda
+%146 = OpFSub %v3float %144 %145
+%147 = OpCompositeExtract %float %146 0
+%148 = OpCompositeExtract %float %146 1
+%149 = OpCompositeExtract %float %146 2
+%150 = OpLoad %v4float %src
+%151 = OpCompositeExtract %float %150 3
+%152 = OpLoad %v4float %dst
+%153 = OpCompositeExtract %float %152 3
+%154 = OpFAdd %float %151 %153
+%155 = OpLoad %float %_1_alpha
+%156 = OpFSub %float %154 %155
+%157 = OpCompositeConstruct %v4float %147 %148 %149 %156
+OpStore %_0_blend_color %157
+%158 = OpLoad %v4float %_0_blend_color
+OpStore %sk_FragColor %158
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendColorBurn.asm.frag b/tests/sksl/blend/golden/BlendColorBurn.asm.frag
new file mode 100644
index 0000000..7f09e81
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendColorBurn.asm.frag
@@ -0,0 +1,237 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %_color_burn_component "_color_burn_component"
+OpName %_6_guarded_divide "_6_guarded_divide"
+OpName %_7_n "_7_n"
+OpName %delta "delta"
+OpName %main "main"
+OpName %_0_blend_color_burn "_0_blend_color_burn"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %32 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %40 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %59 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %64 RelaxedPrecision
+OpDecorate %66 RelaxedPrecision
+OpDecorate %68 RelaxedPrecision
+OpDecorate %69 RelaxedPrecision
+OpDecorate %71 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
+OpDecorate %73 RelaxedPrecision
+OpDecorate %75 RelaxedPrecision
+OpDecorate %78 RelaxedPrecision
+OpDecorate %80 RelaxedPrecision
+OpDecorate %81 RelaxedPrecision
+OpDecorate %82 RelaxedPrecision
+OpDecorate %83 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %86 RelaxedPrecision
+OpDecorate %88 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %91 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %93 RelaxedPrecision
+OpDecorate %95 RelaxedPrecision
+OpDecorate %97 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %108 RelaxedPrecision
+OpDecorate %112 RelaxedPrecision
+OpDecorate %115 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %122 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %131 RelaxedPrecision
+OpDecorate %133 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%15 = OpTypeFunction %float %_ptr_Function_v2float %_ptr_Function_v2float
+%float_1 = OpConstant %float 1
+%float_0 = OpConstant %float 0
+%_ptr_Function_float = OpTypePointer Function %float
+%void = OpTypeVoid
+%101 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_color_burn_component = OpFunction %float None %15
+%17 = OpFunctionParameter %_ptr_Function_v2float
+%18 = OpFunctionParameter %_ptr_Function_v2float
+%19 = OpLabel
+%_6_guarded_divide = OpVariable %_ptr_Function_float Function
+%_7_n = OpVariable %_ptr_Function_float Function
+%delta = OpVariable %_ptr_Function_float Function
+%20 = OpLoad %v2float %18
+%21 = OpCompositeExtract %float %20 1
+%22 = OpLoad %v2float %18
+%23 = OpCompositeExtract %float %22 0
+%24 = OpFOrdEqual %bool %21 %23
+OpSelectionMerge %27 None
+OpBranchConditional %24 %25 %26
+%25 = OpLabel
+%28 = OpLoad %v2float %17
+%29 = OpCompositeExtract %float %28 1
+%30 = OpLoad %v2float %18
+%31 = OpCompositeExtract %float %30 1
+%32 = OpFMul %float %29 %31
+%33 = OpLoad %v2float %17
+%34 = OpCompositeExtract %float %33 0
+%36 = OpLoad %v2float %18
+%37 = OpCompositeExtract %float %36 1
+%38 = OpFSub %float %float_1 %37
+%39 = OpFMul %float %34 %38
+%40 = OpFAdd %float %32 %39
+%41 = OpLoad %v2float %18
+%42 = OpCompositeExtract %float %41 0
+%43 = OpLoad %v2float %17
+%44 = OpCompositeExtract %float %43 1
+%45 = OpFSub %float %float_1 %44
+%46 = OpFMul %float %42 %45
+%47 = OpFAdd %float %40 %46
+OpReturnValue %47
+%26 = OpLabel
+%48 = OpLoad %v2float %17
+%49 = OpCompositeExtract %float %48 0
+%51 = OpFOrdEqual %bool %49 %float_0
+OpSelectionMerge %54 None
+OpBranchConditional %51 %52 %53
+%52 = OpLabel
+%55 = OpLoad %v2float %18
+%56 = OpCompositeExtract %float %55 0
+%57 = OpLoad %v2float %17
+%58 = OpCompositeExtract %float %57 1
+%59 = OpFSub %float %float_1 %58
+%60 = OpFMul %float %56 %59
+OpReturnValue %60
+%53 = OpLabel
+%64 = OpLoad %v2float %18
+%65 = OpCompositeExtract %float %64 1
+%66 = OpLoad %v2float %18
+%67 = OpCompositeExtract %float %66 0
+%68 = OpFSub %float %65 %67
+%69 = OpLoad %v2float %17
+%70 = OpCompositeExtract %float %69 1
+%71 = OpFMul %float %68 %70
+OpStore %_7_n %71
+%72 = OpLoad %float %_7_n
+%73 = OpLoad %v2float %17
+%74 = OpCompositeExtract %float %73 0
+%75 = OpFDiv %float %72 %74
+OpStore %_6_guarded_divide %75
+%78 = OpLoad %v2float %18
+%79 = OpCompositeExtract %float %78 1
+%80 = OpLoad %float %_6_guarded_divide
+%81 = OpFSub %float %79 %80
+%77 = OpExtInst %float %1 FMax %float_0 %81
+OpStore %delta %77
+%82 = OpLoad %float %delta
+%83 = OpLoad %v2float %17
+%84 = OpCompositeExtract %float %83 1
+%85 = OpFMul %float %82 %84
+%86 = OpLoad %v2float %17
+%87 = OpCompositeExtract %float %86 0
+%88 = OpLoad %v2float %18
+%89 = OpCompositeExtract %float %88 1
+%90 = OpFSub %float %float_1 %89
+%91 = OpFMul %float %87 %90
+%92 = OpFAdd %float %85 %91
+%93 = OpLoad %v2float %18
+%94 = OpCompositeExtract %float %93 0
+%95 = OpLoad %v2float %17
+%96 = OpCompositeExtract %float %95 1
+%97 = OpFSub %float %float_1 %96
+%98 = OpFMul %float %94 %97
+%99 = OpFAdd %float %92 %98
+OpReturnValue %99
+%54 = OpLabel
+OpBranch %27
+%27 = OpLabel
+OpUnreachable
+OpFunctionEnd
+%main = OpFunction %void None %101
+%102 = OpLabel
+%_0_blend_color_burn = OpVariable %_ptr_Function_v4float Function
+%107 = OpVariable %_ptr_Function_v2float Function
+%110 = OpVariable %_ptr_Function_v2float Function
+%114 = OpVariable %_ptr_Function_v2float Function
+%117 = OpVariable %_ptr_Function_v2float Function
+%121 = OpVariable %_ptr_Function_v2float Function
+%124 = OpVariable %_ptr_Function_v2float Function
+%105 = OpLoad %v4float %src
+%106 = OpVectorShuffle %v2float %105 %105 0 3
+OpStore %107 %106
+%108 = OpLoad %v4float %dst
+%109 = OpVectorShuffle %v2float %108 %108 0 3
+OpStore %110 %109
+%111 = OpFunctionCall %float %_color_burn_component %107 %110
+%112 = OpLoad %v4float %src
+%113 = OpVectorShuffle %v2float %112 %112 1 3
+OpStore %114 %113
+%115 = OpLoad %v4float %dst
+%116 = OpVectorShuffle %v2float %115 %115 1 3
+OpStore %117 %116
+%118 = OpFunctionCall %float %_color_burn_component %114 %117
+%119 = OpLoad %v4float %src
+%120 = OpVectorShuffle %v2float %119 %119 2 3
+OpStore %121 %120
+%122 = OpLoad %v4float %dst
+%123 = OpVectorShuffle %v2float %122 %122 2 3
+OpStore %124 %123
+%125 = OpFunctionCall %float %_color_burn_component %121 %124
+%126 = OpLoad %v4float %src
+%127 = OpCompositeExtract %float %126 3
+%128 = OpLoad %v4float %src
+%129 = OpCompositeExtract %float %128 3
+%130 = OpFSub %float %float_1 %129
+%131 = OpLoad %v4float %dst
+%132 = OpCompositeExtract %float %131 3
+%133 = OpFMul %float %130 %132
+%134 = OpFAdd %float %127 %133
+%135 = OpCompositeConstruct %v4float %111 %118 %125 %134
+OpStore %_0_blend_color_burn %135
+%136 = OpLoad %v4float %_0_blend_color_burn
+OpStore %sk_FragColor %136
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendColorDodge.asm.frag b/tests/sksl/blend/golden/BlendColorDodge.asm.frag
new file mode 100644
index 0000000..39281f2
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendColorDodge.asm.frag
@@ -0,0 +1,234 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %_color_dodge_component "_color_dodge_component"
+OpName %delta "delta"
+OpName %_4_guarded_divide "_4_guarded_divide"
+OpName %_5_n "_5_n"
+OpName %main "main"
+OpName %_0_blend_color_dodge "_0_blend_color_dodge"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %27 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %32 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %40 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %50 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %53 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %56 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %58 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %62 RelaxedPrecision
+OpDecorate %63 RelaxedPrecision
+OpDecorate %64 RelaxedPrecision
+OpDecorate %67 RelaxedPrecision
+OpDecorate %69 RelaxedPrecision
+OpDecorate %71 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
+OpDecorate %73 RelaxedPrecision
+OpDecorate %74 RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %78 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %80 RelaxedPrecision
+OpDecorate %82 RelaxedPrecision
+OpDecorate %83 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %87 RelaxedPrecision
+OpDecorate %88 RelaxedPrecision
+OpDecorate %89 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %94 RelaxedPrecision
+OpDecorate %95 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %102 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %109 RelaxedPrecision
+OpDecorate %112 RelaxedPrecision
+OpDecorate %116 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %131 RelaxedPrecision
+OpDecorate %133 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%15 = OpTypeFunction %float %_ptr_Function_v2float %_ptr_Function_v2float
+%float_0 = OpConstant %float 0
+%float_1 = OpConstant %float 1
+%_ptr_Function_float = OpTypePointer Function %float
+%void = OpTypeVoid
+%98 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_color_dodge_component = OpFunction %float None %15
+%17 = OpFunctionParameter %_ptr_Function_v2float
+%18 = OpFunctionParameter %_ptr_Function_v2float
+%19 = OpLabel
+%delta = OpVariable %_ptr_Function_float Function
+%_4_guarded_divide = OpVariable %_ptr_Function_float Function
+%_5_n = OpVariable %_ptr_Function_float Function
+%20 = OpLoad %v2float %18
+%21 = OpCompositeExtract %float %20 0
+%23 = OpFOrdEqual %bool %21 %float_0
+OpSelectionMerge %26 None
+OpBranchConditional %23 %24 %25
+%24 = OpLabel
+%27 = OpLoad %v2float %17
+%28 = OpCompositeExtract %float %27 0
+%30 = OpLoad %v2float %18
+%31 = OpCompositeExtract %float %30 1
+%32 = OpFSub %float %float_1 %31
+%33 = OpFMul %float %28 %32
+OpReturnValue %33
+%25 = OpLabel
+%36 = OpLoad %v2float %17
+%37 = OpCompositeExtract %float %36 1
+%38 = OpLoad %v2float %17
+%39 = OpCompositeExtract %float %38 0
+%40 = OpFSub %float %37 %39
+OpStore %delta %40
+%41 = OpLoad %float %delta
+%42 = OpFOrdEqual %bool %41 %float_0
+OpSelectionMerge %45 None
+OpBranchConditional %42 %43 %44
+%43 = OpLabel
+%46 = OpLoad %v2float %17
+%47 = OpCompositeExtract %float %46 1
+%48 = OpLoad %v2float %18
+%49 = OpCompositeExtract %float %48 1
+%50 = OpFMul %float %47 %49
+%51 = OpLoad %v2float %17
+%52 = OpCompositeExtract %float %51 0
+%53 = OpLoad %v2float %18
+%54 = OpCompositeExtract %float %53 1
+%55 = OpFSub %float %float_1 %54
+%56 = OpFMul %float %52 %55
+%57 = OpFAdd %float %50 %56
+%58 = OpLoad %v2float %18
+%59 = OpCompositeExtract %float %58 0
+%60 = OpLoad %v2float %17
+%61 = OpCompositeExtract %float %60 1
+%62 = OpFSub %float %float_1 %61
+%63 = OpFMul %float %59 %62
+%64 = OpFAdd %float %57 %63
+OpReturnValue %64
+%44 = OpLabel
+%67 = OpLoad %v2float %18
+%68 = OpCompositeExtract %float %67 0
+%69 = OpLoad %v2float %17
+%70 = OpCompositeExtract %float %69 1
+%71 = OpFMul %float %68 %70
+OpStore %_5_n %71
+%72 = OpLoad %float %_5_n
+%73 = OpLoad %float %delta
+%74 = OpFDiv %float %72 %73
+OpStore %_4_guarded_divide %74
+%76 = OpLoad %v2float %18
+%77 = OpCompositeExtract %float %76 1
+%78 = OpLoad %float %_4_guarded_divide
+%75 = OpExtInst %float %1 FMin %77 %78
+OpStore %delta %75
+%79 = OpLoad %float %delta
+%80 = OpLoad %v2float %17
+%81 = OpCompositeExtract %float %80 1
+%82 = OpFMul %float %79 %81
+%83 = OpLoad %v2float %17
+%84 = OpCompositeExtract %float %83 0
+%85 = OpLoad %v2float %18
+%86 = OpCompositeExtract %float %85 1
+%87 = OpFSub %float %float_1 %86
+%88 = OpFMul %float %84 %87
+%89 = OpFAdd %float %82 %88
+%90 = OpLoad %v2float %18
+%91 = OpCompositeExtract %float %90 0
+%92 = OpLoad %v2float %17
+%93 = OpCompositeExtract %float %92 1
+%94 = OpFSub %float %float_1 %93
+%95 = OpFMul %float %91 %94
+%96 = OpFAdd %float %89 %95
+OpReturnValue %96
+%45 = OpLabel
+OpBranch %26
+%26 = OpLabel
+OpUnreachable
+OpFunctionEnd
+%main = OpFunction %void None %98
+%99 = OpLabel
+%_0_blend_color_dodge = OpVariable %_ptr_Function_v4float Function
+%104 = OpVariable %_ptr_Function_v2float Function
+%107 = OpVariable %_ptr_Function_v2float Function
+%111 = OpVariable %_ptr_Function_v2float Function
+%114 = OpVariable %_ptr_Function_v2float Function
+%118 = OpVariable %_ptr_Function_v2float Function
+%121 = OpVariable %_ptr_Function_v2float Function
+%102 = OpLoad %v4float %src
+%103 = OpVectorShuffle %v2float %102 %102 0 3
+OpStore %104 %103
+%105 = OpLoad %v4float %dst
+%106 = OpVectorShuffle %v2float %105 %105 0 3
+OpStore %107 %106
+%108 = OpFunctionCall %float %_color_dodge_component %104 %107
+%109 = OpLoad %v4float %src
+%110 = OpVectorShuffle %v2float %109 %109 1 3
+OpStore %111 %110
+%112 = OpLoad %v4float %dst
+%113 = OpVectorShuffle %v2float %112 %112 1 3
+OpStore %114 %113
+%115 = OpFunctionCall %float %_color_dodge_component %111 %114
+%116 = OpLoad %v4float %src
+%117 = OpVectorShuffle %v2float %116 %116 2 3
+OpStore %118 %117
+%119 = OpLoad %v4float %dst
+%120 = OpVectorShuffle %v2float %119 %119 2 3
+OpStore %121 %120
+%122 = OpFunctionCall %float %_color_dodge_component %118 %121
+%123 = OpLoad %v4float %src
+%124 = OpCompositeExtract %float %123 3
+%125 = OpLoad %v4float %src
+%126 = OpCompositeExtract %float %125 3
+%127 = OpFSub %float %float_1 %126
+%128 = OpLoad %v4float %dst
+%129 = OpCompositeExtract %float %128 3
+%130 = OpFMul %float %127 %129
+%131 = OpFAdd %float %124 %130
+%132 = OpCompositeConstruct %v4float %108 %115 %122 %131
+OpStore %_0_blend_color_dodge %132
+%133 = OpLoad %v4float %_0_blend_color_dodge
+OpStore %sk_FragColor %133
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDarken.asm.frag b/tests/sksl/blend/golden/BlendDarken.asm.frag
new file mode 100644
index 0000000..6985dcd
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDarken.asm.frag
@@ -0,0 +1,86 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_darken "_0_blend_darken"
+OpName %_1_2_blend_src_over "_1_2_blend_src_over"
+OpName %_2_result "_2_result"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_darken = OpVariable %_ptr_Function_v4float Function
+%_1_2_blend_src_over = OpVariable %_ptr_Function_v4float Function
+%_2_result = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %src
+%21 = OpLoad %v4float %src
+%22 = OpCompositeExtract %float %21 3
+%23 = OpFSub %float %float_1 %22
+%24 = OpLoad %v4float %dst
+%25 = OpVectorTimesScalar %v4float %24 %23
+%26 = OpFAdd %v4float %19 %25
+OpStore %_1_2_blend_src_over %26
+%28 = OpLoad %v4float %_1_2_blend_src_over
+OpStore %_2_result %28
+%30 = OpLoad %v4float %_2_result
+%31 = OpVectorShuffle %v3float %30 %30 0 1 2
+%33 = OpLoad %v4float %dst
+%34 = OpCompositeExtract %float %33 3
+%35 = OpFSub %float %float_1 %34
+%36 = OpLoad %v4float %src
+%37 = OpVectorShuffle %v3float %36 %36 0 1 2
+%38 = OpVectorTimesScalar %v3float %37 %35
+%39 = OpLoad %v4float %dst
+%40 = OpVectorShuffle %v3float %39 %39 0 1 2
+%41 = OpFAdd %v3float %38 %40
+%29 = OpExtInst %v3float %1 FMin %31 %41
+%42 = OpLoad %v4float %_2_result
+%43 = OpVectorShuffle %v4float %42 %29 4 5 6 3
+OpStore %_2_result %43
+%44 = OpLoad %v4float %_2_result
+OpStore %_0_blend_darken %44
+%45 = OpLoad %v4float %_0_blend_darken
+OpStore %sk_FragColor %45
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDifference.asm.frag b/tests/sksl/blend/golden/BlendDifference.asm.frag
new file mode 100644
index 0000000..f161f1f
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDifference.asm.frag
@@ -0,0 +1,88 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_difference "_0_blend_difference"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %31 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %37 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+OpDecorate %50 RelaxedPrecision
+OpDecorate %52 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%v3float = OpTypeVector %float 3
+%float_2 = OpConstant %float 2
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_difference = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %src
+%19 = OpVectorShuffle %v3float %18 %18 0 1 2
+%21 = OpLoad %v4float %dst
+%22 = OpVectorShuffle %v3float %21 %21 0 1 2
+%23 = OpFAdd %v3float %19 %22
+%26 = OpLoad %v4float %src
+%27 = OpVectorShuffle %v3float %26 %26 0 1 2
+%28 = OpLoad %v4float %dst
+%29 = OpCompositeExtract %float %28 3
+%30 = OpVectorTimesScalar %v3float %27 %29
+%31 = OpLoad %v4float %dst
+%32 = OpVectorShuffle %v3float %31 %31 0 1 2
+%33 = OpLoad %v4float %src
+%34 = OpCompositeExtract %float %33 3
+%35 = OpVectorTimesScalar %v3float %32 %34
+%25 = OpExtInst %v3float %1 FMin %30 %35
+%36 = OpVectorTimesScalar %v3float %25 %float_2
+%37 = OpFSub %v3float %23 %36
+%38 = OpCompositeExtract %float %37 0
+%39 = OpCompositeExtract %float %37 1
+%40 = OpCompositeExtract %float %37 2
+%41 = OpLoad %v4float %src
+%42 = OpCompositeExtract %float %41 3
+%44 = OpLoad %v4float %src
+%45 = OpCompositeExtract %float %44 3
+%46 = OpFSub %float %float_1 %45
+%47 = OpLoad %v4float %dst
+%48 = OpCompositeExtract %float %47 3
+%49 = OpFMul %float %46 %48
+%50 = OpFAdd %float %42 %49
+%51 = OpCompositeConstruct %v4float %38 %39 %40 %50
+OpStore %_0_blend_difference %51
+%52 = OpLoad %v4float %_0_blend_difference
+OpStore %sk_FragColor %52
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDst.asm.frag b/tests/sksl/blend/golden/BlendDst.asm.frag
new file mode 100644
index 0000000..76e72eb
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDst.asm.frag
@@ -0,0 +1,42 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_dst "_0_blend_dst"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_dst = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %dst
+OpStore %_0_blend_dst %18
+%19 = OpLoad %v4float %_0_blend_dst
+OpStore %sk_FragColor %19
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDstAtop.asm.frag b/tests/sksl/blend/golden/BlendDstAtop.asm.frag
new file mode 100644
index 0000000..fa36e6c
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDstAtop.asm.frag
@@ -0,0 +1,57 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_src_atop "_0_blend_src_atop"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_src_atop = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %dst
+%19 = OpCompositeExtract %float %18 3
+%20 = OpLoad %v4float %src
+%21 = OpVectorTimesScalar %v4float %20 %19
+%23 = OpLoad %v4float %src
+%24 = OpCompositeExtract %float %23 3
+%25 = OpFSub %float %float_1 %24
+%26 = OpLoad %v4float %dst
+%27 = OpVectorTimesScalar %v4float %26 %25
+%28 = OpFAdd %v4float %21 %27
+OpStore %_0_blend_src_atop %28
+%29 = OpLoad %v4float %_0_blend_src_atop
+OpStore %sk_FragColor %29
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDstIn.asm.frag b/tests/sksl/blend/golden/BlendDstIn.asm.frag
new file mode 100644
index 0000000..7ebe3e9
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDstIn.asm.frag
@@ -0,0 +1,51 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_dst_in "_0_blend_dst_in"
+OpName %_1_0_blend_src_in "_1_0_blend_src_in"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_dst_in = OpVariable %_ptr_Function_v4float Function
+%_1_0_blend_src_in = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %dst
+%20 = OpLoad %v4float %src
+%21 = OpCompositeExtract %float %20 3
+%22 = OpVectorTimesScalar %v4float %19 %21
+OpStore %_1_0_blend_src_in %22
+%23 = OpLoad %v4float %_1_0_blend_src_in
+OpStore %_0_blend_dst_in %23
+%24 = OpLoad %v4float %_0_blend_dst_in
+OpStore %sk_FragColor %24
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDstOut.asm.frag b/tests/sksl/blend/golden/BlendDstOut.asm.frag
new file mode 100644
index 0000000..e2d58e3
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDstOut.asm.frag
@@ -0,0 +1,49 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_dst_out "_0_blend_dst_out"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_dst_out = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %src
+%20 = OpCompositeExtract %float %19 3
+%21 = OpFSub %float %float_1 %20
+%22 = OpLoad %v4float %dst
+%23 = OpVectorTimesScalar %v4float %22 %21
+OpStore %_0_blend_dst_out %23
+%24 = OpLoad %v4float %_0_blend_dst_out
+OpStore %sk_FragColor %24
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendDstOver.asm.frag b/tests/sksl/blend/golden/BlendDstOver.asm.frag
new file mode 100644
index 0000000..cc29751
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendDstOver.asm.frag
@@ -0,0 +1,53 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_dst_over "_0_blend_dst_over"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_dst_over = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %dst
+%20 = OpCompositeExtract %float %19 3
+%21 = OpFSub %float %float_1 %20
+%22 = OpLoad %v4float %src
+%23 = OpVectorTimesScalar %v4float %22 %21
+%24 = OpLoad %v4float %dst
+%25 = OpFAdd %v4float %23 %24
+OpStore %_0_blend_dst_over %25
+%26 = OpLoad %v4float %_0_blend_dst_over
+OpStore %sk_FragColor %26
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendExclusion.asm.frag b/tests/sksl/blend/golden/BlendExclusion.asm.frag
new file mode 100644
index 0000000..ef0a4a6
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendExclusion.asm.frag
@@ -0,0 +1,81 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_exclusion "_0_blend_exclusion"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %31 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %40 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%v3float = OpTypeVector %float 3
+%float_2 = OpConstant %float 2
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_exclusion = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %dst
+%19 = OpVectorShuffle %v3float %18 %18 0 1 2
+%21 = OpLoad %v4float %src
+%22 = OpVectorShuffle %v3float %21 %21 0 1 2
+%23 = OpFAdd %v3float %19 %22
+%25 = OpLoad %v4float %dst
+%26 = OpVectorShuffle %v3float %25 %25 0 1 2
+%27 = OpVectorTimesScalar %v3float %26 %float_2
+%28 = OpLoad %v4float %src
+%29 = OpVectorShuffle %v3float %28 %28 0 1 2
+%30 = OpFMul %v3float %27 %29
+%31 = OpFSub %v3float %23 %30
+%32 = OpCompositeExtract %float %31 0
+%33 = OpCompositeExtract %float %31 1
+%34 = OpCompositeExtract %float %31 2
+%35 = OpLoad %v4float %src
+%36 = OpCompositeExtract %float %35 3
+%38 = OpLoad %v4float %src
+%39 = OpCompositeExtract %float %38 3
+%40 = OpFSub %float %float_1 %39
+%41 = OpLoad %v4float %dst
+%42 = OpCompositeExtract %float %41 3
+%43 = OpFMul %float %40 %42
+%44 = OpFAdd %float %36 %43
+%45 = OpCompositeConstruct %v4float %32 %33 %34 %44
+OpStore %_0_blend_exclusion %45
+%46 = OpLoad %v4float %_0_blend_exclusion
+OpStore %sk_FragColor %46
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendHardLight.asm.frag b/tests/sksl/blend/golden/BlendHardLight.asm.frag
new file mode 100644
index 0000000..c427d52
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendHardLight.asm.frag
@@ -0,0 +1,298 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_hard_light "_0_blend_hard_light"
+OpName %_1_8_blend_overlay "_1_8_blend_overlay"
+OpName %_2_9_1_blend_overlay_component "_2_9_1_blend_overlay_component"
+OpName %_3_76_blend_overlay_component "_3_76_blend_overlay_component"
+OpName %_4_80_blend_overlay_component "_4_80_blend_overlay_component"
+OpName %_5_10_result "_5_10_result"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %32 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %37 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %40 RelaxedPrecision
+OpDecorate %42 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %53 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %56 RelaxedPrecision
+OpDecorate %58 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %61 RelaxedPrecision
+OpDecorate %68 RelaxedPrecision
+OpDecorate %70 RelaxedPrecision
+OpDecorate %71 RelaxedPrecision
+OpDecorate %73 RelaxedPrecision
+OpDecorate %74 RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %78 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %81 RelaxedPrecision
+OpDecorate %83 RelaxedPrecision
+OpDecorate %84 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %87 RelaxedPrecision
+OpDecorate %89 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %91 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %94 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %97 RelaxedPrecision
+OpDecorate %104 RelaxedPrecision
+OpDecorate %106 RelaxedPrecision
+OpDecorate %107 RelaxedPrecision
+OpDecorate %109 RelaxedPrecision
+OpDecorate %110 RelaxedPrecision
+OpDecorate %112 RelaxedPrecision
+OpDecorate %114 RelaxedPrecision
+OpDecorate %115 RelaxedPrecision
+OpDecorate %117 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %121 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %131 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %133 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+OpDecorate %138 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %141 RelaxedPrecision
+OpDecorate %142 RelaxedPrecision
+OpDecorate %144 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %147 RelaxedPrecision
+OpDecorate %149 RelaxedPrecision
+OpDecorate %151 RelaxedPrecision
+OpDecorate %153 RelaxedPrecision
+OpDecorate %155 RelaxedPrecision
+OpDecorate %157 RelaxedPrecision
+OpDecorate %159 RelaxedPrecision
+OpDecorate %160 RelaxedPrecision
+OpDecorate %162 RelaxedPrecision
+OpDecorate %163 RelaxedPrecision
+OpDecorate %164 RelaxedPrecision
+OpDecorate %165 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function_float = OpTypePointer Function %float
+%float_2 = OpConstant %float 2
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_hard_light = OpVariable %_ptr_Function_v4float Function
+%_1_8_blend_overlay = OpVariable %_ptr_Function_v4float Function
+%_2_9_1_blend_overlay_component = OpVariable %_ptr_Function_float Function
+%28 = OpVariable %_ptr_Function_float Function
+%_3_76_blend_overlay_component = OpVariable %_ptr_Function_float Function
+%64 = OpVariable %_ptr_Function_float Function
+%_4_80_blend_overlay_component = OpVariable %_ptr_Function_float Function
+%100 = OpVariable %_ptr_Function_float Function
+%_5_10_result = OpVariable %_ptr_Function_v4float Function
+%22 = OpLoad %v4float %src
+%23 = OpCompositeExtract %float %22 0
+%24 = OpFMul %float %float_2 %23
+%25 = OpLoad %v4float %src
+%26 = OpCompositeExtract %float %25 3
+%27 = OpFOrdLessThanEqual %bool %24 %26
+OpSelectionMerge %31 None
+OpBranchConditional %27 %29 %30
+%29 = OpLabel
+%32 = OpLoad %v4float %dst
+%33 = OpCompositeExtract %float %32 0
+%34 = OpFMul %float %float_2 %33
+%35 = OpLoad %v4float %src
+%36 = OpCompositeExtract %float %35 0
+%37 = OpFMul %float %34 %36
+OpStore %28 %37
+OpBranch %31
+%30 = OpLabel
+%38 = OpLoad %v4float %dst
+%39 = OpCompositeExtract %float %38 3
+%40 = OpLoad %v4float %src
+%41 = OpCompositeExtract %float %40 3
+%42 = OpFMul %float %39 %41
+%43 = OpLoad %v4float %src
+%44 = OpCompositeExtract %float %43 3
+%45 = OpLoad %v4float %src
+%46 = OpCompositeExtract %float %45 0
+%47 = OpFSub %float %44 %46
+%48 = OpFMul %float %float_2 %47
+%49 = OpLoad %v4float %dst
+%50 = OpCompositeExtract %float %49 3
+%51 = OpLoad %v4float %dst
+%52 = OpCompositeExtract %float %51 0
+%53 = OpFSub %float %50 %52
+%54 = OpFMul %float %48 %53
+%55 = OpFSub %float %42 %54
+OpStore %28 %55
+OpBranch %31
+%31 = OpLabel
+%56 = OpLoad %float %28
+OpStore %_2_9_1_blend_overlay_component %56
+%58 = OpLoad %v4float %src
+%59 = OpCompositeExtract %float %58 1
+%60 = OpFMul %float %float_2 %59
+%61 = OpLoad %v4float %src
+%62 = OpCompositeExtract %float %61 3
+%63 = OpFOrdLessThanEqual %bool %60 %62
+OpSelectionMerge %67 None
+OpBranchConditional %63 %65 %66
+%65 = OpLabel
+%68 = OpLoad %v4float %dst
+%69 = OpCompositeExtract %float %68 1
+%70 = OpFMul %float %float_2 %69
+%71 = OpLoad %v4float %src
+%72 = OpCompositeExtract %float %71 1
+%73 = OpFMul %float %70 %72
+OpStore %64 %73
+OpBranch %67
+%66 = OpLabel
+%74 = OpLoad %v4float %dst
+%75 = OpCompositeExtract %float %74 3
+%76 = OpLoad %v4float %src
+%77 = OpCompositeExtract %float %76 3
+%78 = OpFMul %float %75 %77
+%79 = OpLoad %v4float %src
+%80 = OpCompositeExtract %float %79 3
+%81 = OpLoad %v4float %src
+%82 = OpCompositeExtract %float %81 1
+%83 = OpFSub %float %80 %82
+%84 = OpFMul %float %float_2 %83
+%85 = OpLoad %v4float %dst
+%86 = OpCompositeExtract %float %85 3
+%87 = OpLoad %v4float %dst
+%88 = OpCompositeExtract %float %87 1
+%89 = OpFSub %float %86 %88
+%90 = OpFMul %float %84 %89
+%91 = OpFSub %float %78 %90
+OpStore %64 %91
+OpBranch %67
+%67 = OpLabel
+%92 = OpLoad %float %64
+OpStore %_3_76_blend_overlay_component %92
+%94 = OpLoad %v4float %src
+%95 = OpCompositeExtract %float %94 2
+%96 = OpFMul %float %float_2 %95
+%97 = OpLoad %v4float %src
+%98 = OpCompositeExtract %float %97 3
+%99 = OpFOrdLessThanEqual %bool %96 %98
+OpSelectionMerge %103 None
+OpBranchConditional %99 %101 %102
+%101 = OpLabel
+%104 = OpLoad %v4float %dst
+%105 = OpCompositeExtract %float %104 2
+%106 = OpFMul %float %float_2 %105
+%107 = OpLoad %v4float %src
+%108 = OpCompositeExtract %float %107 2
+%109 = OpFMul %float %106 %108
+OpStore %100 %109
+OpBranch %103
+%102 = OpLabel
+%110 = OpLoad %v4float %dst
+%111 = OpCompositeExtract %float %110 3
+%112 = OpLoad %v4float %src
+%113 = OpCompositeExtract %float %112 3
+%114 = OpFMul %float %111 %113
+%115 = OpLoad %v4float %src
+%116 = OpCompositeExtract %float %115 3
+%117 = OpLoad %v4float %src
+%118 = OpCompositeExtract %float %117 2
+%119 = OpFSub %float %116 %118
+%120 = OpFMul %float %float_2 %119
+%121 = OpLoad %v4float %dst
+%122 = OpCompositeExtract %float %121 3
+%123 = OpLoad %v4float %dst
+%124 = OpCompositeExtract %float %123 2
+%125 = OpFSub %float %122 %124
+%126 = OpFMul %float %120 %125
+%127 = OpFSub %float %114 %126
+OpStore %100 %127
+OpBranch %103
+%103 = OpLabel
+%128 = OpLoad %float %100
+OpStore %_4_80_blend_overlay_component %128
+%130 = OpLoad %float %_2_9_1_blend_overlay_component
+%131 = OpLoad %float %_3_76_blend_overlay_component
+%132 = OpLoad %float %_4_80_blend_overlay_component
+%133 = OpLoad %v4float %dst
+%134 = OpCompositeExtract %float %133 3
+%136 = OpLoad %v4float %dst
+%137 = OpCompositeExtract %float %136 3
+%138 = OpFSub %float %float_1 %137
+%139 = OpLoad %v4float %src
+%140 = OpCompositeExtract %float %139 3
+%141 = OpFMul %float %138 %140
+%142 = OpFAdd %float %134 %141
+%143 = OpCompositeConstruct %v4float %130 %131 %132 %142
+OpStore %_5_10_result %143
+%144 = OpLoad %v4float %_5_10_result
+%145 = OpVectorShuffle %v3float %144 %144 0 1 2
+%147 = OpLoad %v4float %src
+%148 = OpVectorShuffle %v3float %147 %147 0 1 2
+%149 = OpLoad %v4float %dst
+%150 = OpCompositeExtract %float %149 3
+%151 = OpFSub %float %float_1 %150
+%152 = OpVectorTimesScalar %v3float %148 %151
+%153 = OpLoad %v4float %dst
+%154 = OpVectorShuffle %v3float %153 %153 0 1 2
+%155 = OpLoad %v4float %src
+%156 = OpCompositeExtract %float %155 3
+%157 = OpFSub %float %float_1 %156
+%158 = OpVectorTimesScalar %v3float %154 %157
+%159 = OpFAdd %v3float %152 %158
+%160 = OpFAdd %v3float %145 %159
+%161 = OpLoad %v4float %_5_10_result
+%162 = OpVectorShuffle %v4float %161 %160 4 5 6 3
+OpStore %_5_10_result %162
+%163 = OpLoad %v4float %_5_10_result
+OpStore %_1_8_blend_overlay %163
+%164 = OpLoad %v4float %_1_8_blend_overlay
+OpStore %_0_blend_hard_light %164
+%165 = OpLoad %v4float %_0_blend_hard_light
+OpStore %sk_FragColor %165
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendHue.asm.frag b/tests/sksl/blend/golden/BlendHue.asm.frag
new file mode 100644
index 0000000..e105270
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendHue.asm.frag
@@ -0,0 +1,690 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_hue "_0_blend_hue"
+OpName %_1_alpha "_1_alpha"
+OpName %_2_sda "_2_sda"
+OpName %_3_dsa "_3_dsa"
+OpName %_4_blend_set_color_saturation "_4_blend_set_color_saturation"
+OpName %_5_17_blend_color_saturation "_5_17_blend_color_saturation"
+OpName %_6_sat "_6_sat"
+OpName %_7_18_blend_set_color_saturation_helper "_7_18_blend_set_color_saturation_helper"
+OpName %_8_19_blend_set_color_saturation_helper "_8_19_blend_set_color_saturation_helper"
+OpName %_9_20_blend_set_color_saturation_helper "_9_20_blend_set_color_saturation_helper"
+OpName %_10_21_blend_set_color_saturation_helper "_10_21_blend_set_color_saturation_helper"
+OpName %_11_22_blend_set_color_saturation_helper "_11_22_blend_set_color_saturation_helper"
+OpName %_12_23_blend_set_color_saturation_helper "_12_23_blend_set_color_saturation_helper"
+OpName %_13_blend_set_color_luminance "_13_blend_set_color_luminance"
+OpName %_14_15_blend_color_luminance "_14_15_blend_color_luminance"
+OpName %_15_lum "_15_lum"
+OpName %_16_16_blend_color_luminance "_16_16_blend_color_luminance"
+OpName %_17_result "_17_result"
+OpName %_18_minComp "_18_minComp"
+OpName %_19_maxComp "_19_maxComp"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %53 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %59 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %62 RelaxedPrecision
+OpDecorate %68 RelaxedPrecision
+OpDecorate %70 RelaxedPrecision
+OpDecorate %77 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %87 RelaxedPrecision
+OpDecorate %88 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %93 RelaxedPrecision
+OpDecorate %94 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %100 RelaxedPrecision
+OpDecorate %103 RelaxedPrecision
+OpDecorate %104 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %107 RelaxedPrecision
+OpDecorate %114 RelaxedPrecision
+OpDecorate %116 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %129 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %140 RelaxedPrecision
+OpDecorate %143 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %152 RelaxedPrecision
+OpDecorate %153 RelaxedPrecision
+OpDecorate %155 RelaxedPrecision
+OpDecorate %157 RelaxedPrecision
+OpDecorate %158 RelaxedPrecision
+OpDecorate %159 RelaxedPrecision
+OpDecorate %161 RelaxedPrecision
+OpDecorate %163 RelaxedPrecision
+OpDecorate %164 RelaxedPrecision
+OpDecorate %165 RelaxedPrecision
+OpDecorate %168 RelaxedPrecision
+OpDecorate %169 RelaxedPrecision
+OpDecorate %171 RelaxedPrecision
+OpDecorate %173 RelaxedPrecision
+OpDecorate %180 RelaxedPrecision
+OpDecorate %182 RelaxedPrecision
+OpDecorate %189 RelaxedPrecision
+OpDecorate %190 RelaxedPrecision
+OpDecorate %192 RelaxedPrecision
+OpDecorate %194 RelaxedPrecision
+OpDecorate %195 RelaxedPrecision
+OpDecorate %196 RelaxedPrecision
+OpDecorate %198 RelaxedPrecision
+OpDecorate %200 RelaxedPrecision
+OpDecorate %201 RelaxedPrecision
+OpDecorate %202 RelaxedPrecision
+OpDecorate %205 RelaxedPrecision
+OpDecorate %206 RelaxedPrecision
+OpDecorate %208 RelaxedPrecision
+OpDecorate %210 RelaxedPrecision
+OpDecorate %217 RelaxedPrecision
+OpDecorate %219 RelaxedPrecision
+OpDecorate %226 RelaxedPrecision
+OpDecorate %227 RelaxedPrecision
+OpDecorate %229 RelaxedPrecision
+OpDecorate %231 RelaxedPrecision
+OpDecorate %232 RelaxedPrecision
+OpDecorate %233 RelaxedPrecision
+OpDecorate %235 RelaxedPrecision
+OpDecorate %237 RelaxedPrecision
+OpDecorate %238 RelaxedPrecision
+OpDecorate %239 RelaxedPrecision
+OpDecorate %242 RelaxedPrecision
+OpDecorate %243 RelaxedPrecision
+OpDecorate %246 RelaxedPrecision
+OpDecorate %248 RelaxedPrecision
+OpDecorate %255 RelaxedPrecision
+OpDecorate %256 RelaxedPrecision
+OpDecorate %258 RelaxedPrecision
+OpDecorate %260 RelaxedPrecision
+OpDecorate %261 RelaxedPrecision
+OpDecorate %262 RelaxedPrecision
+OpDecorate %264 RelaxedPrecision
+OpDecorate %266 RelaxedPrecision
+OpDecorate %267 RelaxedPrecision
+OpDecorate %268 RelaxedPrecision
+OpDecorate %271 RelaxedPrecision
+OpDecorate %272 RelaxedPrecision
+OpDecorate %281 RelaxedPrecision
+OpDecorate %283 RelaxedPrecision
+OpDecorate %287 RelaxedPrecision
+OpDecorate %289 RelaxedPrecision
+OpDecorate %290 RelaxedPrecision
+OpDecorate %291 RelaxedPrecision
+OpDecorate %292 RelaxedPrecision
+OpDecorate %298 RelaxedPrecision
+OpDecorate %300 RelaxedPrecision
+OpDecorate %302 RelaxedPrecision
+OpDecorate %307 RelaxedPrecision
+OpDecorate %309 RelaxedPrecision
+OpDecorate %311 RelaxedPrecision
+OpDecorate %314 RelaxedPrecision
+OpDecorate %318 RelaxedPrecision
+OpDecorate %319 RelaxedPrecision
+OpDecorate %324 RelaxedPrecision
+OpDecorate %325 RelaxedPrecision
+OpDecorate %326 RelaxedPrecision
+OpDecorate %329 RelaxedPrecision
+OpDecorate %331 RelaxedPrecision
+OpDecorate %332 RelaxedPrecision
+OpDecorate %333 RelaxedPrecision
+OpDecorate %339 RelaxedPrecision
+OpDecorate %340 RelaxedPrecision
+OpDecorate %344 RelaxedPrecision
+OpDecorate %345 RelaxedPrecision
+OpDecorate %352 RelaxedPrecision
+OpDecorate %353 RelaxedPrecision
+OpDecorate %354 RelaxedPrecision
+OpDecorate %357 RelaxedPrecision
+OpDecorate %358 RelaxedPrecision
+OpDecorate %359 RelaxedPrecision
+OpDecorate %361 RelaxedPrecision
+OpDecorate %362 RelaxedPrecision
+OpDecorate %363 RelaxedPrecision
+OpDecorate %368 RelaxedPrecision
+OpDecorate %369 RelaxedPrecision
+OpDecorate %370 RelaxedPrecision
+OpDecorate %371 RelaxedPrecision
+OpDecorate %373 RelaxedPrecision
+OpDecorate %374 RelaxedPrecision
+OpDecorate %375 RelaxedPrecision
+OpDecorate %376 RelaxedPrecision
+OpDecorate %378 RelaxedPrecision
+OpDecorate %379 RelaxedPrecision
+OpDecorate %380 RelaxedPrecision
+OpDecorate %384 RelaxedPrecision
+OpDecorate %386 RelaxedPrecision
+OpDecorate %388 RelaxedPrecision
+OpDecorate %389 RelaxedPrecision
+OpDecorate %390 RelaxedPrecision
+OpDecorate %392 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function_float = OpTypePointer Function %float
+%v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+%float_0 = OpConstant %float 0
+%102 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%138 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%167 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%204 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%241 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%270 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%float_0_300000012 = OpConstant %float 0.300000012
+%float_0_589999974 = OpConstant %float 0.589999974
+%float_0_109999999 = OpConstant %float 0.109999999
+%277 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%286 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%false = OpConstantFalse %bool
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_hue = OpVariable %_ptr_Function_v4float Function
+%_1_alpha = OpVariable %_ptr_Function_float Function
+%_2_sda = OpVariable %_ptr_Function_v3float Function
+%_3_dsa = OpVariable %_ptr_Function_v3float Function
+%_4_blend_set_color_saturation = OpVariable %_ptr_Function_v3float Function
+%_5_17_blend_color_saturation = OpVariable %_ptr_Function_float Function
+%_6_sat = OpVariable %_ptr_Function_float Function
+%_7_18_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%82 = OpVariable %_ptr_Function_v3float Function
+%_8_19_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%119 = OpVariable %_ptr_Function_v3float Function
+%_9_20_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%148 = OpVariable %_ptr_Function_v3float Function
+%_10_21_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%185 = OpVariable %_ptr_Function_v3float Function
+%_11_22_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%222 = OpVariable %_ptr_Function_v3float Function
+%_12_23_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%251 = OpVariable %_ptr_Function_v3float Function
+%_13_blend_set_color_luminance = OpVariable %_ptr_Function_v3float Function
+%_14_15_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_15_lum = OpVariable %_ptr_Function_float Function
+%_16_16_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_17_result = OpVariable %_ptr_Function_v3float Function
+%_18_minComp = OpVariable %_ptr_Function_float Function
+%_19_maxComp = OpVariable %_ptr_Function_float Function
+%348 = OpVariable %_ptr_Function_v3float Function
+%20 = OpLoad %v4float %dst
+%21 = OpCompositeExtract %float %20 3
+%22 = OpLoad %v4float %src
+%23 = OpCompositeExtract %float %22 3
+%24 = OpFMul %float %21 %23
+OpStore %_1_alpha %24
+%28 = OpLoad %v4float %src
+%29 = OpVectorShuffle %v3float %28 %28 0 1 2
+%30 = OpLoad %v4float %dst
+%31 = OpCompositeExtract %float %30 3
+%32 = OpVectorTimesScalar %v3float %29 %31
+OpStore %_2_sda %32
+%34 = OpLoad %v4float %dst
+%35 = OpVectorShuffle %v3float %34 %34 0 1 2
+%36 = OpLoad %v4float %src
+%37 = OpCompositeExtract %float %36 3
+%38 = OpVectorTimesScalar %v3float %35 %37
+OpStore %_3_dsa %38
+%43 = OpLoad %v3float %_3_dsa
+%44 = OpCompositeExtract %float %43 0
+%45 = OpLoad %v3float %_3_dsa
+%46 = OpCompositeExtract %float %45 1
+%42 = OpExtInst %float %1 FMax %44 %46
+%47 = OpLoad %v3float %_3_dsa
+%48 = OpCompositeExtract %float %47 2
+%41 = OpExtInst %float %1 FMax %42 %48
+%51 = OpLoad %v3float %_3_dsa
+%52 = OpCompositeExtract %float %51 0
+%53 = OpLoad %v3float %_3_dsa
+%54 = OpCompositeExtract %float %53 1
+%50 = OpExtInst %float %1 FMin %52 %54
+%55 = OpLoad %v3float %_3_dsa
+%56 = OpCompositeExtract %float %55 2
+%49 = OpExtInst %float %1 FMin %50 %56
+%57 = OpFSub %float %41 %49
+OpStore %_5_17_blend_color_saturation %57
+%59 = OpLoad %float %_5_17_blend_color_saturation
+OpStore %_6_sat %59
+%60 = OpLoad %v3float %_2_sda
+%61 = OpCompositeExtract %float %60 0
+%62 = OpLoad %v3float %_2_sda
+%63 = OpCompositeExtract %float %62 1
+%64 = OpFOrdLessThanEqual %bool %61 %63
+OpSelectionMerge %67 None
+OpBranchConditional %64 %65 %66
+%65 = OpLabel
+%68 = OpLoad %v3float %_2_sda
+%69 = OpCompositeExtract %float %68 1
+%70 = OpLoad %v3float %_2_sda
+%71 = OpCompositeExtract %float %70 2
+%72 = OpFOrdLessThanEqual %bool %69 %71
+OpSelectionMerge %75 None
+OpBranchConditional %72 %73 %74
+%73 = OpLabel
+%77 = OpLoad %v3float %_2_sda
+%78 = OpCompositeExtract %float %77 0
+%79 = OpLoad %v3float %_2_sda
+%80 = OpCompositeExtract %float %79 2
+%81 = OpFOrdLessThan %bool %78 %80
+OpSelectionMerge %85 None
+OpBranchConditional %81 %83 %84
+%83 = OpLabel
+%87 = OpLoad %float %_6_sat
+%88 = OpLoad %v3float %_2_sda
+%89 = OpCompositeExtract %float %88 1
+%90 = OpLoad %v3float %_2_sda
+%91 = OpCompositeExtract %float %90 0
+%92 = OpFSub %float %89 %91
+%93 = OpFMul %float %87 %92
+%94 = OpLoad %v3float %_2_sda
+%95 = OpCompositeExtract %float %94 2
+%96 = OpLoad %v3float %_2_sda
+%97 = OpCompositeExtract %float %96 0
+%98 = OpFSub %float %95 %97
+%99 = OpFDiv %float %93 %98
+%100 = OpLoad %float %_6_sat
+%101 = OpCompositeConstruct %v3float %float_0 %99 %100
+OpStore %82 %101
+OpBranch %85
+%84 = OpLabel
+OpStore %82 %102
+OpBranch %85
+%85 = OpLabel
+%103 = OpLoad %v3float %82
+OpStore %_7_18_blend_set_color_saturation_helper %103
+%104 = OpLoad %v3float %_7_18_blend_set_color_saturation_helper
+OpStore %_4_blend_set_color_saturation %104
+OpBranch %75
+%74 = OpLabel
+%105 = OpLoad %v3float %_2_sda
+%106 = OpCompositeExtract %float %105 0
+%107 = OpLoad %v3float %_2_sda
+%108 = OpCompositeExtract %float %107 2
+%109 = OpFOrdLessThanEqual %bool %106 %108
+OpSelectionMerge %112 None
+OpBranchConditional %109 %110 %111
+%110 = OpLabel
+%114 = OpLoad %v3float %_2_sda
+%115 = OpCompositeExtract %float %114 0
+%116 = OpLoad %v3float %_2_sda
+%117 = OpCompositeExtract %float %116 1
+%118 = OpFOrdLessThan %bool %115 %117
+OpSelectionMerge %122 None
+OpBranchConditional %118 %120 %121
+%120 = OpLabel
+%123 = OpLoad %float %_6_sat
+%124 = OpLoad %v3float %_2_sda
+%125 = OpCompositeExtract %float %124 2
+%126 = OpLoad %v3float %_2_sda
+%127 = OpCompositeExtract %float %126 0
+%128 = OpFSub %float %125 %127
+%129 = OpFMul %float %123 %128
+%130 = OpLoad %v3float %_2_sda
+%131 = OpCompositeExtract %float %130 1
+%132 = OpLoad %v3float %_2_sda
+%133 = OpCompositeExtract %float %132 0
+%134 = OpFSub %float %131 %133
+%135 = OpFDiv %float %129 %134
+%136 = OpLoad %float %_6_sat
+%137 = OpCompositeConstruct %v3float %float_0 %135 %136
+OpStore %119 %137
+OpBranch %122
+%121 = OpLabel
+OpStore %119 %138
+OpBranch %122
+%122 = OpLabel
+%139 = OpLoad %v3float %119
+OpStore %_8_19_blend_set_color_saturation_helper %139
+%140 = OpLoad %v3float %_8_19_blend_set_color_saturation_helper
+%141 = OpVectorShuffle %v3float %140 %140 0 2 1
+OpStore %_4_blend_set_color_saturation %141
+OpBranch %112
+%111 = OpLabel
+%143 = OpLoad %v3float %_2_sda
+%144 = OpCompositeExtract %float %143 2
+%145 = OpLoad %v3float %_2_sda
+%146 = OpCompositeExtract %float %145 1
+%147 = OpFOrdLessThan %bool %144 %146
+OpSelectionMerge %151 None
+OpBranchConditional %147 %149 %150
+%149 = OpLabel
+%152 = OpLoad %float %_6_sat
+%153 = OpLoad %v3float %_2_sda
+%154 = OpCompositeExtract %float %153 0
+%155 = OpLoad %v3float %_2_sda
+%156 = OpCompositeExtract %float %155 2
+%157 = OpFSub %float %154 %156
+%158 = OpFMul %float %152 %157
+%159 = OpLoad %v3float %_2_sda
+%160 = OpCompositeExtract %float %159 1
+%161 = OpLoad %v3float %_2_sda
+%162 = OpCompositeExtract %float %161 2
+%163 = OpFSub %float %160 %162
+%164 = OpFDiv %float %158 %163
+%165 = OpLoad %float %_6_sat
+%166 = OpCompositeConstruct %v3float %float_0 %164 %165
+OpStore %148 %166
+OpBranch %151
+%150 = OpLabel
+OpStore %148 %167
+OpBranch %151
+%151 = OpLabel
+%168 = OpLoad %v3float %148
+OpStore %_9_20_blend_set_color_saturation_helper %168
+%169 = OpLoad %v3float %_9_20_blend_set_color_saturation_helper
+%170 = OpVectorShuffle %v3float %169 %169 1 2 0
+OpStore %_4_blend_set_color_saturation %170
+OpBranch %112
+%112 = OpLabel
+OpBranch %75
+%75 = OpLabel
+OpBranch %67
+%66 = OpLabel
+%171 = OpLoad %v3float %_2_sda
+%172 = OpCompositeExtract %float %171 0
+%173 = OpLoad %v3float %_2_sda
+%174 = OpCompositeExtract %float %173 2
+%175 = OpFOrdLessThanEqual %bool %172 %174
+OpSelectionMerge %178 None
+OpBranchConditional %175 %176 %177
+%176 = OpLabel
+%180 = OpLoad %v3float %_2_sda
+%181 = OpCompositeExtract %float %180 1
+%182 = OpLoad %v3float %_2_sda
+%183 = OpCompositeExtract %float %182 2
+%184 = OpFOrdLessThan %bool %181 %183
+OpSelectionMerge %188 None
+OpBranchConditional %184 %186 %187
+%186 = OpLabel
+%189 = OpLoad %float %_6_sat
+%190 = OpLoad %v3float %_2_sda
+%191 = OpCompositeExtract %float %190 0
+%192 = OpLoad %v3float %_2_sda
+%193 = OpCompositeExtract %float %192 1
+%194 = OpFSub %float %191 %193
+%195 = OpFMul %float %189 %194
+%196 = OpLoad %v3float %_2_sda
+%197 = OpCompositeExtract %float %196 2
+%198 = OpLoad %v3float %_2_sda
+%199 = OpCompositeExtract %float %198 1
+%200 = OpFSub %float %197 %199
+%201 = OpFDiv %float %195 %200
+%202 = OpLoad %float %_6_sat
+%203 = OpCompositeConstruct %v3float %float_0 %201 %202
+OpStore %185 %203
+OpBranch %188
+%187 = OpLabel
+OpStore %185 %204
+OpBranch %188
+%188 = OpLabel
+%205 = OpLoad %v3float %185
+OpStore %_10_21_blend_set_color_saturation_helper %205
+%206 = OpLoad %v3float %_10_21_blend_set_color_saturation_helper
+%207 = OpVectorShuffle %v3float %206 %206 1 0 2
+OpStore %_4_blend_set_color_saturation %207
+OpBranch %178
+%177 = OpLabel
+%208 = OpLoad %v3float %_2_sda
+%209 = OpCompositeExtract %float %208 1
+%210 = OpLoad %v3float %_2_sda
+%211 = OpCompositeExtract %float %210 2
+%212 = OpFOrdLessThanEqual %bool %209 %211
+OpSelectionMerge %215 None
+OpBranchConditional %212 %213 %214
+%213 = OpLabel
+%217 = OpLoad %v3float %_2_sda
+%218 = OpCompositeExtract %float %217 1
+%219 = OpLoad %v3float %_2_sda
+%220 = OpCompositeExtract %float %219 0
+%221 = OpFOrdLessThan %bool %218 %220
+OpSelectionMerge %225 None
+OpBranchConditional %221 %223 %224
+%223 = OpLabel
+%226 = OpLoad %float %_6_sat
+%227 = OpLoad %v3float %_2_sda
+%228 = OpCompositeExtract %float %227 2
+%229 = OpLoad %v3float %_2_sda
+%230 = OpCompositeExtract %float %229 1
+%231 = OpFSub %float %228 %230
+%232 = OpFMul %float %226 %231
+%233 = OpLoad %v3float %_2_sda
+%234 = OpCompositeExtract %float %233 0
+%235 = OpLoad %v3float %_2_sda
+%236 = OpCompositeExtract %float %235 1
+%237 = OpFSub %float %234 %236
+%238 = OpFDiv %float %232 %237
+%239 = OpLoad %float %_6_sat
+%240 = OpCompositeConstruct %v3float %float_0 %238 %239
+OpStore %222 %240
+OpBranch %225
+%224 = OpLabel
+OpStore %222 %241
+OpBranch %225
+%225 = OpLabel
+%242 = OpLoad %v3float %222
+OpStore %_11_22_blend_set_color_saturation_helper %242
+%243 = OpLoad %v3float %_11_22_blend_set_color_saturation_helper
+%244 = OpVectorShuffle %v3float %243 %243 2 0 1
+OpStore %_4_blend_set_color_saturation %244
+OpBranch %215
+%214 = OpLabel
+%246 = OpLoad %v3float %_2_sda
+%247 = OpCompositeExtract %float %246 2
+%248 = OpLoad %v3float %_2_sda
+%249 = OpCompositeExtract %float %248 0
+%250 = OpFOrdLessThan %bool %247 %249
+OpSelectionMerge %254 None
+OpBranchConditional %250 %252 %253
+%252 = OpLabel
+%255 = OpLoad %float %_6_sat
+%256 = OpLoad %v3float %_2_sda
+%257 = OpCompositeExtract %float %256 1
+%258 = OpLoad %v3float %_2_sda
+%259 = OpCompositeExtract %float %258 2
+%260 = OpFSub %float %257 %259
+%261 = OpFMul %float %255 %260
+%262 = OpLoad %v3float %_2_sda
+%263 = OpCompositeExtract %float %262 0
+%264 = OpLoad %v3float %_2_sda
+%265 = OpCompositeExtract %float %264 2
+%266 = OpFSub %float %263 %265
+%267 = OpFDiv %float %261 %266
+%268 = OpLoad %float %_6_sat
+%269 = OpCompositeConstruct %v3float %float_0 %267 %268
+OpStore %251 %269
+OpBranch %254
+%253 = OpLabel
+OpStore %251 %270
+OpBranch %254
+%254 = OpLabel
+%271 = OpLoad %v3float %251
+OpStore %_12_23_blend_set_color_saturation_helper %271
+%272 = OpLoad %v3float %_12_23_blend_set_color_saturation_helper
+%273 = OpVectorShuffle %v3float %272 %272 2 1 0
+OpStore %_4_blend_set_color_saturation %273
+OpBranch %215
+%215 = OpLabel
+OpBranch %178
+%178 = OpLabel
+OpBranch %67
+%67 = OpLabel
+%281 = OpLoad %v3float %_3_dsa
+%276 = OpDot %float %277 %281
+OpStore %_14_15_blend_color_luminance %276
+%283 = OpLoad %float %_14_15_blend_color_luminance
+OpStore %_15_lum %283
+%287 = OpLoad %v3float %_4_blend_set_color_saturation
+%285 = OpDot %float %286 %287
+OpStore %_16_16_blend_color_luminance %285
+%289 = OpLoad %float %_15_lum
+%290 = OpLoad %float %_16_16_blend_color_luminance
+%291 = OpFSub %float %289 %290
+%292 = OpLoad %v3float %_4_blend_set_color_saturation
+%293 = OpCompositeConstruct %v3float %291 %291 %291
+%294 = OpFAdd %v3float %293 %292
+OpStore %_17_result %294
+%298 = OpLoad %v3float %_17_result
+%299 = OpCompositeExtract %float %298 0
+%300 = OpLoad %v3float %_17_result
+%301 = OpCompositeExtract %float %300 1
+%297 = OpExtInst %float %1 FMin %299 %301
+%302 = OpLoad %v3float %_17_result
+%303 = OpCompositeExtract %float %302 2
+%296 = OpExtInst %float %1 FMin %297 %303
+OpStore %_18_minComp %296
+%307 = OpLoad %v3float %_17_result
+%308 = OpCompositeExtract %float %307 0
+%309 = OpLoad %v3float %_17_result
+%310 = OpCompositeExtract %float %309 1
+%306 = OpExtInst %float %1 FMax %308 %310
+%311 = OpLoad %v3float %_17_result
+%312 = OpCompositeExtract %float %311 2
+%305 = OpExtInst %float %1 FMax %306 %312
+OpStore %_19_maxComp %305
+%314 = OpLoad %float %_18_minComp
+%315 = OpFOrdLessThan %bool %314 %float_0
+OpSelectionMerge %317 None
+OpBranchConditional %315 %316 %317
+%316 = OpLabel
+%318 = OpLoad %float %_15_lum
+%319 = OpLoad %float %_18_minComp
+%320 = OpFOrdNotEqual %bool %318 %319
+OpBranch %317
+%317 = OpLabel
+%321 = OpPhi %bool %false %67 %320 %316
+OpSelectionMerge %323 None
+OpBranchConditional %321 %322 %323
+%322 = OpLabel
+%324 = OpLoad %float %_15_lum
+%325 = OpLoad %v3float %_17_result
+%326 = OpLoad %float %_15_lum
+%327 = OpCompositeConstruct %v3float %326 %326 %326
+%328 = OpFSub %v3float %325 %327
+%329 = OpLoad %float %_15_lum
+%330 = OpVectorTimesScalar %v3float %328 %329
+%331 = OpLoad %float %_15_lum
+%332 = OpLoad %float %_18_minComp
+%333 = OpFSub %float %331 %332
+%335 = OpFDiv %float %float_1 %333
+%336 = OpVectorTimesScalar %v3float %330 %335
+%337 = OpCompositeConstruct %v3float %324 %324 %324
+%338 = OpFAdd %v3float %337 %336
+OpStore %_17_result %338
+OpBranch %323
+%323 = OpLabel
+%339 = OpLoad %float %_19_maxComp
+%340 = OpLoad %float %_1_alpha
+%341 = OpFOrdGreaterThan %bool %339 %340
+OpSelectionMerge %343 None
+OpBranchConditional %341 %342 %343
+%342 = OpLabel
+%344 = OpLoad %float %_19_maxComp
+%345 = OpLoad %float %_15_lum
+%346 = OpFOrdNotEqual %bool %344 %345
+OpBranch %343
+%343 = OpLabel
+%347 = OpPhi %bool %false %323 %346 %342
+OpSelectionMerge %351 None
+OpBranchConditional %347 %349 %350
+%349 = OpLabel
+%352 = OpLoad %float %_15_lum
+%353 = OpLoad %v3float %_17_result
+%354 = OpLoad %float %_15_lum
+%355 = OpCompositeConstruct %v3float %354 %354 %354
+%356 = OpFSub %v3float %353 %355
+%357 = OpLoad %float %_1_alpha
+%358 = OpLoad %float %_15_lum
+%359 = OpFSub %float %357 %358
+%360 = OpVectorTimesScalar %v3float %356 %359
+%361 = OpLoad %float %_19_maxComp
+%362 = OpLoad %float %_15_lum
+%363 = OpFSub %float %361 %362
+%364 = OpFDiv %float %float_1 %363
+%365 = OpVectorTimesScalar %v3float %360 %364
+%366 = OpCompositeConstruct %v3float %352 %352 %352
+%367 = OpFAdd %v3float %366 %365
+OpStore %348 %367
+OpBranch %351
+%350 = OpLabel
+%368 = OpLoad %v3float %_17_result
+OpStore %348 %368
+OpBranch %351
+%351 = OpLabel
+%369 = OpLoad %v3float %348
+OpStore %_13_blend_set_color_luminance %369
+%370 = OpLoad %v3float %_13_blend_set_color_luminance
+%371 = OpLoad %v4float %dst
+%372 = OpVectorShuffle %v3float %371 %371 0 1 2
+%373 = OpFAdd %v3float %370 %372
+%374 = OpLoad %v3float %_3_dsa
+%375 = OpFSub %v3float %373 %374
+%376 = OpLoad %v4float %src
+%377 = OpVectorShuffle %v3float %376 %376 0 1 2
+%378 = OpFAdd %v3float %375 %377
+%379 = OpLoad %v3float %_2_sda
+%380 = OpFSub %v3float %378 %379
+%381 = OpCompositeExtract %float %380 0
+%382 = OpCompositeExtract %float %380 1
+%383 = OpCompositeExtract %float %380 2
+%384 = OpLoad %v4float %src
+%385 = OpCompositeExtract %float %384 3
+%386 = OpLoad %v4float %dst
+%387 = OpCompositeExtract %float %386 3
+%388 = OpFAdd %float %385 %387
+%389 = OpLoad %float %_1_alpha
+%390 = OpFSub %float %388 %389
+%391 = OpCompositeConstruct %v4float %381 %382 %383 %390
+OpStore %_0_blend_hue %391
+%392 = OpLoad %v4float %_0_blend_hue
+OpStore %sk_FragColor %392
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendLighten.asm.frag b/tests/sksl/blend/golden/BlendLighten.asm.frag
new file mode 100644
index 0000000..b7136c9
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendLighten.asm.frag
@@ -0,0 +1,86 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_lighten "_0_blend_lighten"
+OpName %_1_3_blend_src_over "_1_3_blend_src_over"
+OpName %_2_result "_2_result"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_lighten = OpVariable %_ptr_Function_v4float Function
+%_1_3_blend_src_over = OpVariable %_ptr_Function_v4float Function
+%_2_result = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %src
+%21 = OpLoad %v4float %src
+%22 = OpCompositeExtract %float %21 3
+%23 = OpFSub %float %float_1 %22
+%24 = OpLoad %v4float %dst
+%25 = OpVectorTimesScalar %v4float %24 %23
+%26 = OpFAdd %v4float %19 %25
+OpStore %_1_3_blend_src_over %26
+%28 = OpLoad %v4float %_1_3_blend_src_over
+OpStore %_2_result %28
+%30 = OpLoad %v4float %_2_result
+%31 = OpVectorShuffle %v3float %30 %30 0 1 2
+%33 = OpLoad %v4float %dst
+%34 = OpCompositeExtract %float %33 3
+%35 = OpFSub %float %float_1 %34
+%36 = OpLoad %v4float %src
+%37 = OpVectorShuffle %v3float %36 %36 0 1 2
+%38 = OpVectorTimesScalar %v3float %37 %35
+%39 = OpLoad %v4float %dst
+%40 = OpVectorShuffle %v3float %39 %39 0 1 2
+%41 = OpFAdd %v3float %38 %40
+%29 = OpExtInst %v3float %1 FMax %31 %41
+%42 = OpLoad %v4float %_2_result
+%43 = OpVectorShuffle %v4float %42 %29 4 5 6 3
+OpStore %_2_result %43
+%44 = OpLoad %v4float %_2_result
+OpStore %_0_blend_lighten %44
+%45 = OpLoad %v4float %_0_blend_lighten
+OpStore %sk_FragColor %45
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendLuminosity.asm.frag b/tests/sksl/blend/golden/BlendLuminosity.asm.frag
new file mode 100644
index 0000000..401b1df
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendLuminosity.asm.frag
@@ -0,0 +1,275 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_luminosity "_0_blend_luminosity"
+OpName %_1_alpha "_1_alpha"
+OpName %_2_sda "_2_sda"
+OpName %_3_dsa "_3_dsa"
+OpName %_4_blend_set_color_luminance "_4_blend_set_color_luminance"
+OpName %_5_15_blend_color_luminance "_5_15_blend_color_luminance"
+OpName %_6_lum "_6_lum"
+OpName %_7_16_blend_color_luminance "_7_16_blend_color_luminance"
+OpName %_8_result "_8_result"
+OpName %_9_minComp "_9_minComp"
+OpName %_10_maxComp "_10_maxComp"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %52 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %56 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %63 RelaxedPrecision
+OpDecorate %65 RelaxedPrecision
+OpDecorate %67 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
+OpDecorate %74 RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %84 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %91 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %95 RelaxedPrecision
+OpDecorate %97 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %106 RelaxedPrecision
+OpDecorate %110 RelaxedPrecision
+OpDecorate %111 RelaxedPrecision
+OpDecorate %118 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %129 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+OpDecorate %137 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %140 RelaxedPrecision
+OpDecorate %141 RelaxedPrecision
+OpDecorate %142 RelaxedPrecision
+OpDecorate %144 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %146 RelaxedPrecision
+OpDecorate %150 RelaxedPrecision
+OpDecorate %152 RelaxedPrecision
+OpDecorate %154 RelaxedPrecision
+OpDecorate %155 RelaxedPrecision
+OpDecorate %156 RelaxedPrecision
+OpDecorate %158 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function_float = OpTypePointer Function %float
+%v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+%float_0_300000012 = OpConstant %float 0.300000012
+%float_0_589999974 = OpConstant %float 0.589999974
+%float_0_109999999 = OpConstant %float 0.109999999
+%42 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%51 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%false = OpConstantFalse %bool
+%float_0 = OpConstant %float 0
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_luminosity = OpVariable %_ptr_Function_v4float Function
+%_1_alpha = OpVariable %_ptr_Function_float Function
+%_2_sda = OpVariable %_ptr_Function_v3float Function
+%_3_dsa = OpVariable %_ptr_Function_v3float Function
+%_4_blend_set_color_luminance = OpVariable %_ptr_Function_v3float Function
+%_5_15_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_6_lum = OpVariable %_ptr_Function_float Function
+%_7_16_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_8_result = OpVariable %_ptr_Function_v3float Function
+%_9_minComp = OpVariable %_ptr_Function_float Function
+%_10_maxComp = OpVariable %_ptr_Function_float Function
+%114 = OpVariable %_ptr_Function_v3float Function
+%20 = OpLoad %v4float %dst
+%21 = OpCompositeExtract %float %20 3
+%22 = OpLoad %v4float %src
+%23 = OpCompositeExtract %float %22 3
+%24 = OpFMul %float %21 %23
+OpStore %_1_alpha %24
+%28 = OpLoad %v4float %src
+%29 = OpVectorShuffle %v3float %28 %28 0 1 2
+%30 = OpLoad %v4float %dst
+%31 = OpCompositeExtract %float %30 3
+%32 = OpVectorTimesScalar %v3float %29 %31
+OpStore %_2_sda %32
+%34 = OpLoad %v4float %dst
+%35 = OpVectorShuffle %v3float %34 %34 0 1 2
+%36 = OpLoad %v4float %src
+%37 = OpCompositeExtract %float %36 3
+%38 = OpVectorTimesScalar %v3float %35 %37
+OpStore %_3_dsa %38
+%46 = OpLoad %v3float %_2_sda
+%41 = OpDot %float %42 %46
+OpStore %_5_15_blend_color_luminance %41
+%48 = OpLoad %float %_5_15_blend_color_luminance
+OpStore %_6_lum %48
+%52 = OpLoad %v3float %_3_dsa
+%50 = OpDot %float %51 %52
+OpStore %_7_16_blend_color_luminance %50
+%54 = OpLoad %float %_6_lum
+%55 = OpLoad %float %_7_16_blend_color_luminance
+%56 = OpFSub %float %54 %55
+%57 = OpLoad %v3float %_3_dsa
+%58 = OpCompositeConstruct %v3float %56 %56 %56
+%59 = OpFAdd %v3float %58 %57
+OpStore %_8_result %59
+%63 = OpLoad %v3float %_8_result
+%64 = OpCompositeExtract %float %63 0
+%65 = OpLoad %v3float %_8_result
+%66 = OpCompositeExtract %float %65 1
+%62 = OpExtInst %float %1 FMin %64 %66
+%67 = OpLoad %v3float %_8_result
+%68 = OpCompositeExtract %float %67 2
+%61 = OpExtInst %float %1 FMin %62 %68
+OpStore %_9_minComp %61
+%72 = OpLoad %v3float %_8_result
+%73 = OpCompositeExtract %float %72 0
+%74 = OpLoad %v3float %_8_result
+%75 = OpCompositeExtract %float %74 1
+%71 = OpExtInst %float %1 FMax %73 %75
+%76 = OpLoad %v3float %_8_result
+%77 = OpCompositeExtract %float %76 2
+%70 = OpExtInst %float %1 FMax %71 %77
+OpStore %_10_maxComp %70
+%79 = OpLoad %float %_9_minComp
+%81 = OpFOrdLessThan %bool %79 %float_0
+OpSelectionMerge %83 None
+OpBranchConditional %81 %82 %83
+%82 = OpLabel
+%84 = OpLoad %float %_6_lum
+%85 = OpLoad %float %_9_minComp
+%86 = OpFOrdNotEqual %bool %84 %85
+OpBranch %83
+%83 = OpLabel
+%87 = OpPhi %bool %false %15 %86 %82
+OpSelectionMerge %89 None
+OpBranchConditional %87 %88 %89
+%88 = OpLabel
+%90 = OpLoad %float %_6_lum
+%91 = OpLoad %v3float %_8_result
+%92 = OpLoad %float %_6_lum
+%93 = OpCompositeConstruct %v3float %92 %92 %92
+%94 = OpFSub %v3float %91 %93
+%95 = OpLoad %float %_6_lum
+%96 = OpVectorTimesScalar %v3float %94 %95
+%97 = OpLoad %float %_6_lum
+%98 = OpLoad %float %_9_minComp
+%99 = OpFSub %float %97 %98
+%101 = OpFDiv %float %float_1 %99
+%102 = OpVectorTimesScalar %v3float %96 %101
+%103 = OpCompositeConstruct %v3float %90 %90 %90
+%104 = OpFAdd %v3float %103 %102
+OpStore %_8_result %104
+OpBranch %89
+%89 = OpLabel
+%105 = OpLoad %float %_10_maxComp
+%106 = OpLoad %float %_1_alpha
+%107 = OpFOrdGreaterThan %bool %105 %106
+OpSelectionMerge %109 None
+OpBranchConditional %107 %108 %109
+%108 = OpLabel
+%110 = OpLoad %float %_10_maxComp
+%111 = OpLoad %float %_6_lum
+%112 = OpFOrdNotEqual %bool %110 %111
+OpBranch %109
+%109 = OpLabel
+%113 = OpPhi %bool %false %89 %112 %108
+OpSelectionMerge %117 None
+OpBranchConditional %113 %115 %116
+%115 = OpLabel
+%118 = OpLoad %float %_6_lum
+%119 = OpLoad %v3float %_8_result
+%120 = OpLoad %float %_6_lum
+%121 = OpCompositeConstruct %v3float %120 %120 %120
+%122 = OpFSub %v3float %119 %121
+%123 = OpLoad %float %_1_alpha
+%124 = OpLoad %float %_6_lum
+%125 = OpFSub %float %123 %124
+%126 = OpVectorTimesScalar %v3float %122 %125
+%127 = OpLoad %float %_10_maxComp
+%128 = OpLoad %float %_6_lum
+%129 = OpFSub %float %127 %128
+%130 = OpFDiv %float %float_1 %129
+%131 = OpVectorTimesScalar %v3float %126 %130
+%132 = OpCompositeConstruct %v3float %118 %118 %118
+%133 = OpFAdd %v3float %132 %131
+OpStore %114 %133
+OpBranch %117
+%116 = OpLabel
+%134 = OpLoad %v3float %_8_result
+OpStore %114 %134
+OpBranch %117
+%117 = OpLabel
+%135 = OpLoad %v3float %114
+OpStore %_4_blend_set_color_luminance %135
+%136 = OpLoad %v3float %_4_blend_set_color_luminance
+%137 = OpLoad %v4float %dst
+%138 = OpVectorShuffle %v3float %137 %137 0 1 2
+%139 = OpFAdd %v3float %136 %138
+%140 = OpLoad %v3float %_3_dsa
+%141 = OpFSub %v3float %139 %140
+%142 = OpLoad %v4float %src
+%143 = OpVectorShuffle %v3float %142 %142 0 1 2
+%144 = OpFAdd %v3float %141 %143
+%145 = OpLoad %v3float %_2_sda
+%146 = OpFSub %v3float %144 %145
+%147 = OpCompositeExtract %float %146 0
+%148 = OpCompositeExtract %float %146 1
+%149 = OpCompositeExtract %float %146 2
+%150 = OpLoad %v4float %src
+%151 = OpCompositeExtract %float %150 3
+%152 = OpLoad %v4float %dst
+%153 = OpCompositeExtract %float %152 3
+%154 = OpFAdd %float %151 %153
+%155 = OpLoad %float %_1_alpha
+%156 = OpFSub %float %154 %155
+%157 = OpCompositeConstruct %v4float %147 %148 %149 %156
+OpStore %_0_blend_luminosity %157
+%158 = OpLoad %v4float %_0_blend_luminosity
+OpStore %sk_FragColor %158
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendModulate.asm.frag b/tests/sksl/blend/golden/BlendModulate.asm.frag
new file mode 100644
index 0000000..3d4930b
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendModulate.asm.frag
@@ -0,0 +1,46 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_modulate "_0_blend_modulate"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_modulate = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %src
+%19 = OpLoad %v4float %dst
+%20 = OpFMul %v4float %18 %19
+OpStore %_0_blend_modulate %20
+%21 = OpLoad %v4float %_0_blend_modulate
+OpStore %sk_FragColor %21
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendMultiply.asm.frag b/tests/sksl/blend/golden/BlendMultiply.asm.frag
new file mode 100644
index 0000000..f4c0800
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendMultiply.asm.frag
@@ -0,0 +1,91 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_multiply "_0_blend_multiply"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+OpDecorate %32 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %37 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %42 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+OpDecorate %50 RelaxedPrecision
+OpDecorate %52 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_multiply = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %src
+%20 = OpCompositeExtract %float %19 3
+%21 = OpFSub %float %float_1 %20
+%22 = OpLoad %v4float %dst
+%23 = OpVectorShuffle %v3float %22 %22 0 1 2
+%25 = OpVectorTimesScalar %v3float %23 %21
+%26 = OpLoad %v4float %dst
+%27 = OpCompositeExtract %float %26 3
+%28 = OpFSub %float %float_1 %27
+%29 = OpLoad %v4float %src
+%30 = OpVectorShuffle %v3float %29 %29 0 1 2
+%31 = OpVectorTimesScalar %v3float %30 %28
+%32 = OpFAdd %v3float %25 %31
+%33 = OpLoad %v4float %src
+%34 = OpVectorShuffle %v3float %33 %33 0 1 2
+%35 = OpLoad %v4float %dst
+%36 = OpVectorShuffle %v3float %35 %35 0 1 2
+%37 = OpFMul %v3float %34 %36
+%38 = OpFAdd %v3float %32 %37
+%39 = OpCompositeExtract %float %38 0
+%40 = OpCompositeExtract %float %38 1
+%41 = OpCompositeExtract %float %38 2
+%42 = OpLoad %v4float %src
+%43 = OpCompositeExtract %float %42 3
+%44 = OpLoad %v4float %src
+%45 = OpCompositeExtract %float %44 3
+%46 = OpFSub %float %float_1 %45
+%47 = OpLoad %v4float %dst
+%48 = OpCompositeExtract %float %47 3
+%49 = OpFMul %float %46 %48
+%50 = OpFAdd %float %43 %49
+%51 = OpCompositeConstruct %v4float %39 %40 %41 %50
+OpStore %_0_blend_multiply %51
+%52 = OpLoad %v4float %_0_blend_multiply
+OpStore %sk_FragColor %52
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendOverlay.asm.frag b/tests/sksl/blend/golden/BlendOverlay.asm.frag
new file mode 100644
index 0000000..e8df9f7
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendOverlay.asm.frag
@@ -0,0 +1,293 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_overlay "_0_blend_overlay"
+OpName %_1_1_blend_overlay_component "_1_1_blend_overlay_component"
+OpName %_2_75_blend_overlay_component "_2_75_blend_overlay_component"
+OpName %_3_79_blend_overlay_component "_3_79_blend_overlay_component"
+OpName %_4_result "_4_result"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %31 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %37 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %42 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %50 RelaxedPrecision
+OpDecorate %52 RelaxedPrecision
+OpDecorate %53 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %59 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %67 RelaxedPrecision
+OpDecorate %69 RelaxedPrecision
+OpDecorate %70 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
+OpDecorate %73 RelaxedPrecision
+OpDecorate %75 RelaxedPrecision
+OpDecorate %77 RelaxedPrecision
+OpDecorate %78 RelaxedPrecision
+OpDecorate %80 RelaxedPrecision
+OpDecorate %82 RelaxedPrecision
+OpDecorate %83 RelaxedPrecision
+OpDecorate %84 RelaxedPrecision
+OpDecorate %86 RelaxedPrecision
+OpDecorate %88 RelaxedPrecision
+OpDecorate %89 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %91 RelaxedPrecision
+OpDecorate %93 RelaxedPrecision
+OpDecorate %95 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %103 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %106 RelaxedPrecision
+OpDecorate %108 RelaxedPrecision
+OpDecorate %109 RelaxedPrecision
+OpDecorate %111 RelaxedPrecision
+OpDecorate %113 RelaxedPrecision
+OpDecorate %114 RelaxedPrecision
+OpDecorate %116 RelaxedPrecision
+OpDecorate %118 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %122 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %129 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %131 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %137 RelaxedPrecision
+OpDecorate %138 RelaxedPrecision
+OpDecorate %140 RelaxedPrecision
+OpDecorate %141 RelaxedPrecision
+OpDecorate %143 RelaxedPrecision
+OpDecorate %144 RelaxedPrecision
+OpDecorate %146 RelaxedPrecision
+OpDecorate %148 RelaxedPrecision
+OpDecorate %150 RelaxedPrecision
+OpDecorate %152 RelaxedPrecision
+OpDecorate %154 RelaxedPrecision
+OpDecorate %156 RelaxedPrecision
+OpDecorate %158 RelaxedPrecision
+OpDecorate %159 RelaxedPrecision
+OpDecorate %161 RelaxedPrecision
+OpDecorate %162 RelaxedPrecision
+OpDecorate %163 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function_float = OpTypePointer Function %float
+%float_2 = OpConstant %float 2
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_overlay = OpVariable %_ptr_Function_v4float Function
+%_1_1_blend_overlay_component = OpVariable %_ptr_Function_float Function
+%27 = OpVariable %_ptr_Function_float Function
+%_2_75_blend_overlay_component = OpVariable %_ptr_Function_float Function
+%63 = OpVariable %_ptr_Function_float Function
+%_3_79_blend_overlay_component = OpVariable %_ptr_Function_float Function
+%99 = OpVariable %_ptr_Function_float Function
+%_4_result = OpVariable %_ptr_Function_v4float Function
+%21 = OpLoad %v4float %dst
+%22 = OpCompositeExtract %float %21 0
+%23 = OpFMul %float %float_2 %22
+%24 = OpLoad %v4float %dst
+%25 = OpCompositeExtract %float %24 3
+%26 = OpFOrdLessThanEqual %bool %23 %25
+OpSelectionMerge %30 None
+OpBranchConditional %26 %28 %29
+%28 = OpLabel
+%31 = OpLoad %v4float %src
+%32 = OpCompositeExtract %float %31 0
+%33 = OpFMul %float %float_2 %32
+%34 = OpLoad %v4float %dst
+%35 = OpCompositeExtract %float %34 0
+%36 = OpFMul %float %33 %35
+OpStore %27 %36
+OpBranch %30
+%29 = OpLabel
+%37 = OpLoad %v4float %src
+%38 = OpCompositeExtract %float %37 3
+%39 = OpLoad %v4float %dst
+%40 = OpCompositeExtract %float %39 3
+%41 = OpFMul %float %38 %40
+%42 = OpLoad %v4float %dst
+%43 = OpCompositeExtract %float %42 3
+%44 = OpLoad %v4float %dst
+%45 = OpCompositeExtract %float %44 0
+%46 = OpFSub %float %43 %45
+%47 = OpFMul %float %float_2 %46
+%48 = OpLoad %v4float %src
+%49 = OpCompositeExtract %float %48 3
+%50 = OpLoad %v4float %src
+%51 = OpCompositeExtract %float %50 0
+%52 = OpFSub %float %49 %51
+%53 = OpFMul %float %47 %52
+%54 = OpFSub %float %41 %53
+OpStore %27 %54
+OpBranch %30
+%30 = OpLabel
+%55 = OpLoad %float %27
+OpStore %_1_1_blend_overlay_component %55
+%57 = OpLoad %v4float %dst
+%58 = OpCompositeExtract %float %57 1
+%59 = OpFMul %float %float_2 %58
+%60 = OpLoad %v4float %dst
+%61 = OpCompositeExtract %float %60 3
+%62 = OpFOrdLessThanEqual %bool %59 %61
+OpSelectionMerge %66 None
+OpBranchConditional %62 %64 %65
+%64 = OpLabel
+%67 = OpLoad %v4float %src
+%68 = OpCompositeExtract %float %67 1
+%69 = OpFMul %float %float_2 %68
+%70 = OpLoad %v4float %dst
+%71 = OpCompositeExtract %float %70 1
+%72 = OpFMul %float %69 %71
+OpStore %63 %72
+OpBranch %66
+%65 = OpLabel
+%73 = OpLoad %v4float %src
+%74 = OpCompositeExtract %float %73 3
+%75 = OpLoad %v4float %dst
+%76 = OpCompositeExtract %float %75 3
+%77 = OpFMul %float %74 %76
+%78 = OpLoad %v4float %dst
+%79 = OpCompositeExtract %float %78 3
+%80 = OpLoad %v4float %dst
+%81 = OpCompositeExtract %float %80 1
+%82 = OpFSub %float %79 %81
+%83 = OpFMul %float %float_2 %82
+%84 = OpLoad %v4float %src
+%85 = OpCompositeExtract %float %84 3
+%86 = OpLoad %v4float %src
+%87 = OpCompositeExtract %float %86 1
+%88 = OpFSub %float %85 %87
+%89 = OpFMul %float %83 %88
+%90 = OpFSub %float %77 %89
+OpStore %63 %90
+OpBranch %66
+%66 = OpLabel
+%91 = OpLoad %float %63
+OpStore %_2_75_blend_overlay_component %91
+%93 = OpLoad %v4float %dst
+%94 = OpCompositeExtract %float %93 2
+%95 = OpFMul %float %float_2 %94
+%96 = OpLoad %v4float %dst
+%97 = OpCompositeExtract %float %96 3
+%98 = OpFOrdLessThanEqual %bool %95 %97
+OpSelectionMerge %102 None
+OpBranchConditional %98 %100 %101
+%100 = OpLabel
+%103 = OpLoad %v4float %src
+%104 = OpCompositeExtract %float %103 2
+%105 = OpFMul %float %float_2 %104
+%106 = OpLoad %v4float %dst
+%107 = OpCompositeExtract %float %106 2
+%108 = OpFMul %float %105 %107
+OpStore %99 %108
+OpBranch %102
+%101 = OpLabel
+%109 = OpLoad %v4float %src
+%110 = OpCompositeExtract %float %109 3
+%111 = OpLoad %v4float %dst
+%112 = OpCompositeExtract %float %111 3
+%113 = OpFMul %float %110 %112
+%114 = OpLoad %v4float %dst
+%115 = OpCompositeExtract %float %114 3
+%116 = OpLoad %v4float %dst
+%117 = OpCompositeExtract %float %116 2
+%118 = OpFSub %float %115 %117
+%119 = OpFMul %float %float_2 %118
+%120 = OpLoad %v4float %src
+%121 = OpCompositeExtract %float %120 3
+%122 = OpLoad %v4float %src
+%123 = OpCompositeExtract %float %122 2
+%124 = OpFSub %float %121 %123
+%125 = OpFMul %float %119 %124
+%126 = OpFSub %float %113 %125
+OpStore %99 %126
+OpBranch %102
+%102 = OpLabel
+%127 = OpLoad %float %99
+OpStore %_3_79_blend_overlay_component %127
+%129 = OpLoad %float %_1_1_blend_overlay_component
+%130 = OpLoad %float %_2_75_blend_overlay_component
+%131 = OpLoad %float %_3_79_blend_overlay_component
+%132 = OpLoad %v4float %src
+%133 = OpCompositeExtract %float %132 3
+%135 = OpLoad %v4float %src
+%136 = OpCompositeExtract %float %135 3
+%137 = OpFSub %float %float_1 %136
+%138 = OpLoad %v4float %dst
+%139 = OpCompositeExtract %float %138 3
+%140 = OpFMul %float %137 %139
+%141 = OpFAdd %float %133 %140
+%142 = OpCompositeConstruct %v4float %129 %130 %131 %141
+OpStore %_4_result %142
+%143 = OpLoad %v4float %_4_result
+%144 = OpVectorShuffle %v3float %143 %143 0 1 2
+%146 = OpLoad %v4float %dst
+%147 = OpVectorShuffle %v3float %146 %146 0 1 2
+%148 = OpLoad %v4float %src
+%149 = OpCompositeExtract %float %148 3
+%150 = OpFSub %float %float_1 %149
+%151 = OpVectorTimesScalar %v3float %147 %150
+%152 = OpLoad %v4float %src
+%153 = OpVectorShuffle %v3float %152 %152 0 1 2
+%154 = OpLoad %v4float %dst
+%155 = OpCompositeExtract %float %154 3
+%156 = OpFSub %float %float_1 %155
+%157 = OpVectorTimesScalar %v3float %153 %156
+%158 = OpFAdd %v3float %151 %157
+%159 = OpFAdd %v3float %144 %158
+%160 = OpLoad %v4float %_4_result
+%161 = OpVectorShuffle %v4float %160 %159 4 5 6 3
+OpStore %_4_result %161
+%162 = OpLoad %v4float %_4_result
+OpStore %_0_blend_overlay %162
+%163 = OpLoad %v4float %_0_blend_overlay
+OpStore %sk_FragColor %163
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendPlus.asm.frag b/tests/sksl/blend/golden/BlendPlus.asm.frag
new file mode 100644
index 0000000..db71cb6
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendPlus.asm.frag
@@ -0,0 +1,50 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_plus "_0_blend_plus"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_plus = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %src
+%20 = OpLoad %v4float %dst
+%21 = OpFAdd %v4float %19 %20
+%23 = OpCompositeConstruct %v4float %float_1 %float_1 %float_1 %float_1
+%18 = OpExtInst %v4float %1 FMin %21 %23
+OpStore %_0_blend_plus %18
+%24 = OpLoad %v4float %_0_blend_plus
+OpStore %sk_FragColor %24
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSaturation.asm.frag b/tests/sksl/blend/golden/BlendSaturation.asm.frag
new file mode 100644
index 0000000..5035096
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSaturation.asm.frag
@@ -0,0 +1,690 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_saturation "_0_blend_saturation"
+OpName %_1_alpha "_1_alpha"
+OpName %_2_sda "_2_sda"
+OpName %_3_dsa "_3_dsa"
+OpName %_4_blend_set_color_saturation "_4_blend_set_color_saturation"
+OpName %_5_17_blend_color_saturation "_5_17_blend_color_saturation"
+OpName %_6_sat "_6_sat"
+OpName %_7_18_blend_set_color_saturation_helper "_7_18_blend_set_color_saturation_helper"
+OpName %_8_19_blend_set_color_saturation_helper "_8_19_blend_set_color_saturation_helper"
+OpName %_9_20_blend_set_color_saturation_helper "_9_20_blend_set_color_saturation_helper"
+OpName %_10_21_blend_set_color_saturation_helper "_10_21_blend_set_color_saturation_helper"
+OpName %_11_22_blend_set_color_saturation_helper "_11_22_blend_set_color_saturation_helper"
+OpName %_12_23_blend_set_color_saturation_helper "_12_23_blend_set_color_saturation_helper"
+OpName %_13_blend_set_color_luminance "_13_blend_set_color_luminance"
+OpName %_14_15_blend_color_luminance "_14_15_blend_color_luminance"
+OpName %_15_lum "_15_lum"
+OpName %_16_16_blend_color_luminance "_16_16_blend_color_luminance"
+OpName %_17_result "_17_result"
+OpName %_18_minComp "_18_minComp"
+OpName %_19_maxComp "_19_maxComp"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %36 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %53 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %59 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %62 RelaxedPrecision
+OpDecorate %68 RelaxedPrecision
+OpDecorate %70 RelaxedPrecision
+OpDecorate %77 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %87 RelaxedPrecision
+OpDecorate %88 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %93 RelaxedPrecision
+OpDecorate %94 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %100 RelaxedPrecision
+OpDecorate %103 RelaxedPrecision
+OpDecorate %104 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %107 RelaxedPrecision
+OpDecorate %114 RelaxedPrecision
+OpDecorate %116 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %129 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %140 RelaxedPrecision
+OpDecorate %143 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %152 RelaxedPrecision
+OpDecorate %153 RelaxedPrecision
+OpDecorate %155 RelaxedPrecision
+OpDecorate %157 RelaxedPrecision
+OpDecorate %158 RelaxedPrecision
+OpDecorate %159 RelaxedPrecision
+OpDecorate %161 RelaxedPrecision
+OpDecorate %163 RelaxedPrecision
+OpDecorate %164 RelaxedPrecision
+OpDecorate %165 RelaxedPrecision
+OpDecorate %168 RelaxedPrecision
+OpDecorate %169 RelaxedPrecision
+OpDecorate %171 RelaxedPrecision
+OpDecorate %173 RelaxedPrecision
+OpDecorate %180 RelaxedPrecision
+OpDecorate %182 RelaxedPrecision
+OpDecorate %189 RelaxedPrecision
+OpDecorate %190 RelaxedPrecision
+OpDecorate %192 RelaxedPrecision
+OpDecorate %194 RelaxedPrecision
+OpDecorate %195 RelaxedPrecision
+OpDecorate %196 RelaxedPrecision
+OpDecorate %198 RelaxedPrecision
+OpDecorate %200 RelaxedPrecision
+OpDecorate %201 RelaxedPrecision
+OpDecorate %202 RelaxedPrecision
+OpDecorate %205 RelaxedPrecision
+OpDecorate %206 RelaxedPrecision
+OpDecorate %208 RelaxedPrecision
+OpDecorate %210 RelaxedPrecision
+OpDecorate %217 RelaxedPrecision
+OpDecorate %219 RelaxedPrecision
+OpDecorate %226 RelaxedPrecision
+OpDecorate %227 RelaxedPrecision
+OpDecorate %229 RelaxedPrecision
+OpDecorate %231 RelaxedPrecision
+OpDecorate %232 RelaxedPrecision
+OpDecorate %233 RelaxedPrecision
+OpDecorate %235 RelaxedPrecision
+OpDecorate %237 RelaxedPrecision
+OpDecorate %238 RelaxedPrecision
+OpDecorate %239 RelaxedPrecision
+OpDecorate %242 RelaxedPrecision
+OpDecorate %243 RelaxedPrecision
+OpDecorate %246 RelaxedPrecision
+OpDecorate %248 RelaxedPrecision
+OpDecorate %255 RelaxedPrecision
+OpDecorate %256 RelaxedPrecision
+OpDecorate %258 RelaxedPrecision
+OpDecorate %260 RelaxedPrecision
+OpDecorate %261 RelaxedPrecision
+OpDecorate %262 RelaxedPrecision
+OpDecorate %264 RelaxedPrecision
+OpDecorate %266 RelaxedPrecision
+OpDecorate %267 RelaxedPrecision
+OpDecorate %268 RelaxedPrecision
+OpDecorate %271 RelaxedPrecision
+OpDecorate %272 RelaxedPrecision
+OpDecorate %281 RelaxedPrecision
+OpDecorate %283 RelaxedPrecision
+OpDecorate %287 RelaxedPrecision
+OpDecorate %289 RelaxedPrecision
+OpDecorate %290 RelaxedPrecision
+OpDecorate %291 RelaxedPrecision
+OpDecorate %292 RelaxedPrecision
+OpDecorate %298 RelaxedPrecision
+OpDecorate %300 RelaxedPrecision
+OpDecorate %302 RelaxedPrecision
+OpDecorate %307 RelaxedPrecision
+OpDecorate %309 RelaxedPrecision
+OpDecorate %311 RelaxedPrecision
+OpDecorate %314 RelaxedPrecision
+OpDecorate %318 RelaxedPrecision
+OpDecorate %319 RelaxedPrecision
+OpDecorate %324 RelaxedPrecision
+OpDecorate %325 RelaxedPrecision
+OpDecorate %326 RelaxedPrecision
+OpDecorate %329 RelaxedPrecision
+OpDecorate %331 RelaxedPrecision
+OpDecorate %332 RelaxedPrecision
+OpDecorate %333 RelaxedPrecision
+OpDecorate %339 RelaxedPrecision
+OpDecorate %340 RelaxedPrecision
+OpDecorate %344 RelaxedPrecision
+OpDecorate %345 RelaxedPrecision
+OpDecorate %352 RelaxedPrecision
+OpDecorate %353 RelaxedPrecision
+OpDecorate %354 RelaxedPrecision
+OpDecorate %357 RelaxedPrecision
+OpDecorate %358 RelaxedPrecision
+OpDecorate %359 RelaxedPrecision
+OpDecorate %361 RelaxedPrecision
+OpDecorate %362 RelaxedPrecision
+OpDecorate %363 RelaxedPrecision
+OpDecorate %368 RelaxedPrecision
+OpDecorate %369 RelaxedPrecision
+OpDecorate %370 RelaxedPrecision
+OpDecorate %371 RelaxedPrecision
+OpDecorate %373 RelaxedPrecision
+OpDecorate %374 RelaxedPrecision
+OpDecorate %375 RelaxedPrecision
+OpDecorate %376 RelaxedPrecision
+OpDecorate %378 RelaxedPrecision
+OpDecorate %379 RelaxedPrecision
+OpDecorate %380 RelaxedPrecision
+OpDecorate %384 RelaxedPrecision
+OpDecorate %386 RelaxedPrecision
+OpDecorate %388 RelaxedPrecision
+OpDecorate %389 RelaxedPrecision
+OpDecorate %390 RelaxedPrecision
+OpDecorate %392 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%_ptr_Function_float = OpTypePointer Function %float
+%v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+%float_0 = OpConstant %float 0
+%102 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%138 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%167 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%204 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%241 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%270 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%float_0_300000012 = OpConstant %float 0.300000012
+%float_0_589999974 = OpConstant %float 0.589999974
+%float_0_109999999 = OpConstant %float 0.109999999
+%277 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%286 = OpConstantComposite %v3float %float_0_300000012 %float_0_589999974 %float_0_109999999
+%false = OpConstantFalse %bool
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_saturation = OpVariable %_ptr_Function_v4float Function
+%_1_alpha = OpVariable %_ptr_Function_float Function
+%_2_sda = OpVariable %_ptr_Function_v3float Function
+%_3_dsa = OpVariable %_ptr_Function_v3float Function
+%_4_blend_set_color_saturation = OpVariable %_ptr_Function_v3float Function
+%_5_17_blend_color_saturation = OpVariable %_ptr_Function_float Function
+%_6_sat = OpVariable %_ptr_Function_float Function
+%_7_18_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%82 = OpVariable %_ptr_Function_v3float Function
+%_8_19_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%119 = OpVariable %_ptr_Function_v3float Function
+%_9_20_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%148 = OpVariable %_ptr_Function_v3float Function
+%_10_21_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%185 = OpVariable %_ptr_Function_v3float Function
+%_11_22_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%222 = OpVariable %_ptr_Function_v3float Function
+%_12_23_blend_set_color_saturation_helper = OpVariable %_ptr_Function_v3float Function
+%251 = OpVariable %_ptr_Function_v3float Function
+%_13_blend_set_color_luminance = OpVariable %_ptr_Function_v3float Function
+%_14_15_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_15_lum = OpVariable %_ptr_Function_float Function
+%_16_16_blend_color_luminance = OpVariable %_ptr_Function_float Function
+%_17_result = OpVariable %_ptr_Function_v3float Function
+%_18_minComp = OpVariable %_ptr_Function_float Function
+%_19_maxComp = OpVariable %_ptr_Function_float Function
+%348 = OpVariable %_ptr_Function_v3float Function
+%20 = OpLoad %v4float %dst
+%21 = OpCompositeExtract %float %20 3
+%22 = OpLoad %v4float %src
+%23 = OpCompositeExtract %float %22 3
+%24 = OpFMul %float %21 %23
+OpStore %_1_alpha %24
+%28 = OpLoad %v4float %src
+%29 = OpVectorShuffle %v3float %28 %28 0 1 2
+%30 = OpLoad %v4float %dst
+%31 = OpCompositeExtract %float %30 3
+%32 = OpVectorTimesScalar %v3float %29 %31
+OpStore %_2_sda %32
+%34 = OpLoad %v4float %dst
+%35 = OpVectorShuffle %v3float %34 %34 0 1 2
+%36 = OpLoad %v4float %src
+%37 = OpCompositeExtract %float %36 3
+%38 = OpVectorTimesScalar %v3float %35 %37
+OpStore %_3_dsa %38
+%43 = OpLoad %v3float %_2_sda
+%44 = OpCompositeExtract %float %43 0
+%45 = OpLoad %v3float %_2_sda
+%46 = OpCompositeExtract %float %45 1
+%42 = OpExtInst %float %1 FMax %44 %46
+%47 = OpLoad %v3float %_2_sda
+%48 = OpCompositeExtract %float %47 2
+%41 = OpExtInst %float %1 FMax %42 %48
+%51 = OpLoad %v3float %_2_sda
+%52 = OpCompositeExtract %float %51 0
+%53 = OpLoad %v3float %_2_sda
+%54 = OpCompositeExtract %float %53 1
+%50 = OpExtInst %float %1 FMin %52 %54
+%55 = OpLoad %v3float %_2_sda
+%56 = OpCompositeExtract %float %55 2
+%49 = OpExtInst %float %1 FMin %50 %56
+%57 = OpFSub %float %41 %49
+OpStore %_5_17_blend_color_saturation %57
+%59 = OpLoad %float %_5_17_blend_color_saturation
+OpStore %_6_sat %59
+%60 = OpLoad %v3float %_3_dsa
+%61 = OpCompositeExtract %float %60 0
+%62 = OpLoad %v3float %_3_dsa
+%63 = OpCompositeExtract %float %62 1
+%64 = OpFOrdLessThanEqual %bool %61 %63
+OpSelectionMerge %67 None
+OpBranchConditional %64 %65 %66
+%65 = OpLabel
+%68 = OpLoad %v3float %_3_dsa
+%69 = OpCompositeExtract %float %68 1
+%70 = OpLoad %v3float %_3_dsa
+%71 = OpCompositeExtract %float %70 2
+%72 = OpFOrdLessThanEqual %bool %69 %71
+OpSelectionMerge %75 None
+OpBranchConditional %72 %73 %74
+%73 = OpLabel
+%77 = OpLoad %v3float %_3_dsa
+%78 = OpCompositeExtract %float %77 0
+%79 = OpLoad %v3float %_3_dsa
+%80 = OpCompositeExtract %float %79 2
+%81 = OpFOrdLessThan %bool %78 %80
+OpSelectionMerge %85 None
+OpBranchConditional %81 %83 %84
+%83 = OpLabel
+%87 = OpLoad %float %_6_sat
+%88 = OpLoad %v3float %_3_dsa
+%89 = OpCompositeExtract %float %88 1
+%90 = OpLoad %v3float %_3_dsa
+%91 = OpCompositeExtract %float %90 0
+%92 = OpFSub %float %89 %91
+%93 = OpFMul %float %87 %92
+%94 = OpLoad %v3float %_3_dsa
+%95 = OpCompositeExtract %float %94 2
+%96 = OpLoad %v3float %_3_dsa
+%97 = OpCompositeExtract %float %96 0
+%98 = OpFSub %float %95 %97
+%99 = OpFDiv %float %93 %98
+%100 = OpLoad %float %_6_sat
+%101 = OpCompositeConstruct %v3float %float_0 %99 %100
+OpStore %82 %101
+OpBranch %85
+%84 = OpLabel
+OpStore %82 %102
+OpBranch %85
+%85 = OpLabel
+%103 = OpLoad %v3float %82
+OpStore %_7_18_blend_set_color_saturation_helper %103
+%104 = OpLoad %v3float %_7_18_blend_set_color_saturation_helper
+OpStore %_4_blend_set_color_saturation %104
+OpBranch %75
+%74 = OpLabel
+%105 = OpLoad %v3float %_3_dsa
+%106 = OpCompositeExtract %float %105 0
+%107 = OpLoad %v3float %_3_dsa
+%108 = OpCompositeExtract %float %107 2
+%109 = OpFOrdLessThanEqual %bool %106 %108
+OpSelectionMerge %112 None
+OpBranchConditional %109 %110 %111
+%110 = OpLabel
+%114 = OpLoad %v3float %_3_dsa
+%115 = OpCompositeExtract %float %114 0
+%116 = OpLoad %v3float %_3_dsa
+%117 = OpCompositeExtract %float %116 1
+%118 = OpFOrdLessThan %bool %115 %117
+OpSelectionMerge %122 None
+OpBranchConditional %118 %120 %121
+%120 = OpLabel
+%123 = OpLoad %float %_6_sat
+%124 = OpLoad %v3float %_3_dsa
+%125 = OpCompositeExtract %float %124 2
+%126 = OpLoad %v3float %_3_dsa
+%127 = OpCompositeExtract %float %126 0
+%128 = OpFSub %float %125 %127
+%129 = OpFMul %float %123 %128
+%130 = OpLoad %v3float %_3_dsa
+%131 = OpCompositeExtract %float %130 1
+%132 = OpLoad %v3float %_3_dsa
+%133 = OpCompositeExtract %float %132 0
+%134 = OpFSub %float %131 %133
+%135 = OpFDiv %float %129 %134
+%136 = OpLoad %float %_6_sat
+%137 = OpCompositeConstruct %v3float %float_0 %135 %136
+OpStore %119 %137
+OpBranch %122
+%121 = OpLabel
+OpStore %119 %138
+OpBranch %122
+%122 = OpLabel
+%139 = OpLoad %v3float %119
+OpStore %_8_19_blend_set_color_saturation_helper %139
+%140 = OpLoad %v3float %_8_19_blend_set_color_saturation_helper
+%141 = OpVectorShuffle %v3float %140 %140 0 2 1
+OpStore %_4_blend_set_color_saturation %141
+OpBranch %112
+%111 = OpLabel
+%143 = OpLoad %v3float %_3_dsa
+%144 = OpCompositeExtract %float %143 2
+%145 = OpLoad %v3float %_3_dsa
+%146 = OpCompositeExtract %float %145 1
+%147 = OpFOrdLessThan %bool %144 %146
+OpSelectionMerge %151 None
+OpBranchConditional %147 %149 %150
+%149 = OpLabel
+%152 = OpLoad %float %_6_sat
+%153 = OpLoad %v3float %_3_dsa
+%154 = OpCompositeExtract %float %153 0
+%155 = OpLoad %v3float %_3_dsa
+%156 = OpCompositeExtract %float %155 2
+%157 = OpFSub %float %154 %156
+%158 = OpFMul %float %152 %157
+%159 = OpLoad %v3float %_3_dsa
+%160 = OpCompositeExtract %float %159 1
+%161 = OpLoad %v3float %_3_dsa
+%162 = OpCompositeExtract %float %161 2
+%163 = OpFSub %float %160 %162
+%164 = OpFDiv %float %158 %163
+%165 = OpLoad %float %_6_sat
+%166 = OpCompositeConstruct %v3float %float_0 %164 %165
+OpStore %148 %166
+OpBranch %151
+%150 = OpLabel
+OpStore %148 %167
+OpBranch %151
+%151 = OpLabel
+%168 = OpLoad %v3float %148
+OpStore %_9_20_blend_set_color_saturation_helper %168
+%169 = OpLoad %v3float %_9_20_blend_set_color_saturation_helper
+%170 = OpVectorShuffle %v3float %169 %169 1 2 0
+OpStore %_4_blend_set_color_saturation %170
+OpBranch %112
+%112 = OpLabel
+OpBranch %75
+%75 = OpLabel
+OpBranch %67
+%66 = OpLabel
+%171 = OpLoad %v3float %_3_dsa
+%172 = OpCompositeExtract %float %171 0
+%173 = OpLoad %v3float %_3_dsa
+%174 = OpCompositeExtract %float %173 2
+%175 = OpFOrdLessThanEqual %bool %172 %174
+OpSelectionMerge %178 None
+OpBranchConditional %175 %176 %177
+%176 = OpLabel
+%180 = OpLoad %v3float %_3_dsa
+%181 = OpCompositeExtract %float %180 1
+%182 = OpLoad %v3float %_3_dsa
+%183 = OpCompositeExtract %float %182 2
+%184 = OpFOrdLessThan %bool %181 %183
+OpSelectionMerge %188 None
+OpBranchConditional %184 %186 %187
+%186 = OpLabel
+%189 = OpLoad %float %_6_sat
+%190 = OpLoad %v3float %_3_dsa
+%191 = OpCompositeExtract %float %190 0
+%192 = OpLoad %v3float %_3_dsa
+%193 = OpCompositeExtract %float %192 1
+%194 = OpFSub %float %191 %193
+%195 = OpFMul %float %189 %194
+%196 = OpLoad %v3float %_3_dsa
+%197 = OpCompositeExtract %float %196 2
+%198 = OpLoad %v3float %_3_dsa
+%199 = OpCompositeExtract %float %198 1
+%200 = OpFSub %float %197 %199
+%201 = OpFDiv %float %195 %200
+%202 = OpLoad %float %_6_sat
+%203 = OpCompositeConstruct %v3float %float_0 %201 %202
+OpStore %185 %203
+OpBranch %188
+%187 = OpLabel
+OpStore %185 %204
+OpBranch %188
+%188 = OpLabel
+%205 = OpLoad %v3float %185
+OpStore %_10_21_blend_set_color_saturation_helper %205
+%206 = OpLoad %v3float %_10_21_blend_set_color_saturation_helper
+%207 = OpVectorShuffle %v3float %206 %206 1 0 2
+OpStore %_4_blend_set_color_saturation %207
+OpBranch %178
+%177 = OpLabel
+%208 = OpLoad %v3float %_3_dsa
+%209 = OpCompositeExtract %float %208 1
+%210 = OpLoad %v3float %_3_dsa
+%211 = OpCompositeExtract %float %210 2
+%212 = OpFOrdLessThanEqual %bool %209 %211
+OpSelectionMerge %215 None
+OpBranchConditional %212 %213 %214
+%213 = OpLabel
+%217 = OpLoad %v3float %_3_dsa
+%218 = OpCompositeExtract %float %217 1
+%219 = OpLoad %v3float %_3_dsa
+%220 = OpCompositeExtract %float %219 0
+%221 = OpFOrdLessThan %bool %218 %220
+OpSelectionMerge %225 None
+OpBranchConditional %221 %223 %224
+%223 = OpLabel
+%226 = OpLoad %float %_6_sat
+%227 = OpLoad %v3float %_3_dsa
+%228 = OpCompositeExtract %float %227 2
+%229 = OpLoad %v3float %_3_dsa
+%230 = OpCompositeExtract %float %229 1
+%231 = OpFSub %float %228 %230
+%232 = OpFMul %float %226 %231
+%233 = OpLoad %v3float %_3_dsa
+%234 = OpCompositeExtract %float %233 0
+%235 = OpLoad %v3float %_3_dsa
+%236 = OpCompositeExtract %float %235 1
+%237 = OpFSub %float %234 %236
+%238 = OpFDiv %float %232 %237
+%239 = OpLoad %float %_6_sat
+%240 = OpCompositeConstruct %v3float %float_0 %238 %239
+OpStore %222 %240
+OpBranch %225
+%224 = OpLabel
+OpStore %222 %241
+OpBranch %225
+%225 = OpLabel
+%242 = OpLoad %v3float %222
+OpStore %_11_22_blend_set_color_saturation_helper %242
+%243 = OpLoad %v3float %_11_22_blend_set_color_saturation_helper
+%244 = OpVectorShuffle %v3float %243 %243 2 0 1
+OpStore %_4_blend_set_color_saturation %244
+OpBranch %215
+%214 = OpLabel
+%246 = OpLoad %v3float %_3_dsa
+%247 = OpCompositeExtract %float %246 2
+%248 = OpLoad %v3float %_3_dsa
+%249 = OpCompositeExtract %float %248 0
+%250 = OpFOrdLessThan %bool %247 %249
+OpSelectionMerge %254 None
+OpBranchConditional %250 %252 %253
+%252 = OpLabel
+%255 = OpLoad %float %_6_sat
+%256 = OpLoad %v3float %_3_dsa
+%257 = OpCompositeExtract %float %256 1
+%258 = OpLoad %v3float %_3_dsa
+%259 = OpCompositeExtract %float %258 2
+%260 = OpFSub %float %257 %259
+%261 = OpFMul %float %255 %260
+%262 = OpLoad %v3float %_3_dsa
+%263 = OpCompositeExtract %float %262 0
+%264 = OpLoad %v3float %_3_dsa
+%265 = OpCompositeExtract %float %264 2
+%266 = OpFSub %float %263 %265
+%267 = OpFDiv %float %261 %266
+%268 = OpLoad %float %_6_sat
+%269 = OpCompositeConstruct %v3float %float_0 %267 %268
+OpStore %251 %269
+OpBranch %254
+%253 = OpLabel
+OpStore %251 %270
+OpBranch %254
+%254 = OpLabel
+%271 = OpLoad %v3float %251
+OpStore %_12_23_blend_set_color_saturation_helper %271
+%272 = OpLoad %v3float %_12_23_blend_set_color_saturation_helper
+%273 = OpVectorShuffle %v3float %272 %272 2 1 0
+OpStore %_4_blend_set_color_saturation %273
+OpBranch %215
+%215 = OpLabel
+OpBranch %178
+%178 = OpLabel
+OpBranch %67
+%67 = OpLabel
+%281 = OpLoad %v3float %_3_dsa
+%276 = OpDot %float %277 %281
+OpStore %_14_15_blend_color_luminance %276
+%283 = OpLoad %float %_14_15_blend_color_luminance
+OpStore %_15_lum %283
+%287 = OpLoad %v3float %_4_blend_set_color_saturation
+%285 = OpDot %float %286 %287
+OpStore %_16_16_blend_color_luminance %285
+%289 = OpLoad %float %_15_lum
+%290 = OpLoad %float %_16_16_blend_color_luminance
+%291 = OpFSub %float %289 %290
+%292 = OpLoad %v3float %_4_blend_set_color_saturation
+%293 = OpCompositeConstruct %v3float %291 %291 %291
+%294 = OpFAdd %v3float %293 %292
+OpStore %_17_result %294
+%298 = OpLoad %v3float %_17_result
+%299 = OpCompositeExtract %float %298 0
+%300 = OpLoad %v3float %_17_result
+%301 = OpCompositeExtract %float %300 1
+%297 = OpExtInst %float %1 FMin %299 %301
+%302 = OpLoad %v3float %_17_result
+%303 = OpCompositeExtract %float %302 2
+%296 = OpExtInst %float %1 FMin %297 %303
+OpStore %_18_minComp %296
+%307 = OpLoad %v3float %_17_result
+%308 = OpCompositeExtract %float %307 0
+%309 = OpLoad %v3float %_17_result
+%310 = OpCompositeExtract %float %309 1
+%306 = OpExtInst %float %1 FMax %308 %310
+%311 = OpLoad %v3float %_17_result
+%312 = OpCompositeExtract %float %311 2
+%305 = OpExtInst %float %1 FMax %306 %312
+OpStore %_19_maxComp %305
+%314 = OpLoad %float %_18_minComp
+%315 = OpFOrdLessThan %bool %314 %float_0
+OpSelectionMerge %317 None
+OpBranchConditional %315 %316 %317
+%316 = OpLabel
+%318 = OpLoad %float %_15_lum
+%319 = OpLoad %float %_18_minComp
+%320 = OpFOrdNotEqual %bool %318 %319
+OpBranch %317
+%317 = OpLabel
+%321 = OpPhi %bool %false %67 %320 %316
+OpSelectionMerge %323 None
+OpBranchConditional %321 %322 %323
+%322 = OpLabel
+%324 = OpLoad %float %_15_lum
+%325 = OpLoad %v3float %_17_result
+%326 = OpLoad %float %_15_lum
+%327 = OpCompositeConstruct %v3float %326 %326 %326
+%328 = OpFSub %v3float %325 %327
+%329 = OpLoad %float %_15_lum
+%330 = OpVectorTimesScalar %v3float %328 %329
+%331 = OpLoad %float %_15_lum
+%332 = OpLoad %float %_18_minComp
+%333 = OpFSub %float %331 %332
+%335 = OpFDiv %float %float_1 %333
+%336 = OpVectorTimesScalar %v3float %330 %335
+%337 = OpCompositeConstruct %v3float %324 %324 %324
+%338 = OpFAdd %v3float %337 %336
+OpStore %_17_result %338
+OpBranch %323
+%323 = OpLabel
+%339 = OpLoad %float %_19_maxComp
+%340 = OpLoad %float %_1_alpha
+%341 = OpFOrdGreaterThan %bool %339 %340
+OpSelectionMerge %343 None
+OpBranchConditional %341 %342 %343
+%342 = OpLabel
+%344 = OpLoad %float %_19_maxComp
+%345 = OpLoad %float %_15_lum
+%346 = OpFOrdNotEqual %bool %344 %345
+OpBranch %343
+%343 = OpLabel
+%347 = OpPhi %bool %false %323 %346 %342
+OpSelectionMerge %351 None
+OpBranchConditional %347 %349 %350
+%349 = OpLabel
+%352 = OpLoad %float %_15_lum
+%353 = OpLoad %v3float %_17_result
+%354 = OpLoad %float %_15_lum
+%355 = OpCompositeConstruct %v3float %354 %354 %354
+%356 = OpFSub %v3float %353 %355
+%357 = OpLoad %float %_1_alpha
+%358 = OpLoad %float %_15_lum
+%359 = OpFSub %float %357 %358
+%360 = OpVectorTimesScalar %v3float %356 %359
+%361 = OpLoad %float %_19_maxComp
+%362 = OpLoad %float %_15_lum
+%363 = OpFSub %float %361 %362
+%364 = OpFDiv %float %float_1 %363
+%365 = OpVectorTimesScalar %v3float %360 %364
+%366 = OpCompositeConstruct %v3float %352 %352 %352
+%367 = OpFAdd %v3float %366 %365
+OpStore %348 %367
+OpBranch %351
+%350 = OpLabel
+%368 = OpLoad %v3float %_17_result
+OpStore %348 %368
+OpBranch %351
+%351 = OpLabel
+%369 = OpLoad %v3float %348
+OpStore %_13_blend_set_color_luminance %369
+%370 = OpLoad %v3float %_13_blend_set_color_luminance
+%371 = OpLoad %v4float %dst
+%372 = OpVectorShuffle %v3float %371 %371 0 1 2
+%373 = OpFAdd %v3float %370 %372
+%374 = OpLoad %v3float %_3_dsa
+%375 = OpFSub %v3float %373 %374
+%376 = OpLoad %v4float %src
+%377 = OpVectorShuffle %v3float %376 %376 0 1 2
+%378 = OpFAdd %v3float %375 %377
+%379 = OpLoad %v3float %_2_sda
+%380 = OpFSub %v3float %378 %379
+%381 = OpCompositeExtract %float %380 0
+%382 = OpCompositeExtract %float %380 1
+%383 = OpCompositeExtract %float %380 2
+%384 = OpLoad %v4float %src
+%385 = OpCompositeExtract %float %384 3
+%386 = OpLoad %v4float %dst
+%387 = OpCompositeExtract %float %386 3
+%388 = OpFAdd %float %385 %387
+%389 = OpLoad %float %_1_alpha
+%390 = OpFSub %float %388 %389
+%391 = OpCompositeConstruct %v4float %381 %382 %383 %390
+OpStore %_0_blend_saturation %391
+%392 = OpLoad %v4float %_0_blend_saturation
+OpStore %sk_FragColor %392
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendScreen.asm.frag b/tests/sksl/blend/golden/BlendScreen.asm.frag
new file mode 100644
index 0000000..37186b5
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendScreen.asm.frag
@@ -0,0 +1,53 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_screen "_0_blend_screen"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_screen = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %src
+%20 = OpLoad %v4float %src
+%21 = OpCompositeConstruct %v4float %float_1 %float_1 %float_1 %float_1
+%22 = OpFSub %v4float %21 %20
+%23 = OpLoad %v4float %dst
+%24 = OpFMul %v4float %22 %23
+%25 = OpFAdd %v4float %18 %24
+OpStore %_0_blend_screen %25
+%26 = OpLoad %v4float %_0_blend_screen
+OpStore %sk_FragColor %26
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSoftLight.asm.frag b/tests/sksl/blend/golden/BlendSoftLight.asm.frag
new file mode 100644
index 0000000..e9c1974
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSoftLight.asm.frag
@@ -0,0 +1,415 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %_soft_light_component "_soft_light_component"
+OpName %_11_guarded_divide "_11_guarded_divide"
+OpName %_12_n "_12_n"
+OpName %DSqd "DSqd"
+OpName %DCub "DCub"
+OpName %DaSqd "DaSqd"
+OpName %DaCub "DaCub"
+OpName %_13_guarded_divide "_13_guarded_divide"
+OpName %_14_n "_14_n"
+OpName %main "main"
+OpName %_0_blend_soft_light "_0_blend_soft_light"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %37 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %40 RelaxedPrecision
+OpDecorate %42 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %53 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %56 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %58 RelaxedPrecision
+OpDecorate %61 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %63 RelaxedPrecision
+OpDecorate %65 RelaxedPrecision
+OpDecorate %66 RelaxedPrecision
+OpDecorate %67 RelaxedPrecision
+OpDecorate %68 RelaxedPrecision
+OpDecorate %69 RelaxedPrecision
+OpDecorate %71 RelaxedPrecision
+OpDecorate %73 RelaxedPrecision
+OpDecorate %74 RelaxedPrecision
+OpDecorate %81 RelaxedPrecision
+OpDecorate %83 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %87 RelaxedPrecision
+OpDecorate %88 RelaxedPrecision
+OpDecorate %90 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %94 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %101 RelaxedPrecision
+OpDecorate %104 RelaxedPrecision
+OpDecorate %105 RelaxedPrecision
+OpDecorate %107 RelaxedPrecision
+OpDecorate %110 RelaxedPrecision
+OpDecorate %112 RelaxedPrecision
+OpDecorate %114 RelaxedPrecision
+OpDecorate %116 RelaxedPrecision
+OpDecorate %117 RelaxedPrecision
+OpDecorate %118 RelaxedPrecision
+OpDecorate %119 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %121 RelaxedPrecision
+OpDecorate %123 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %133 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %137 RelaxedPrecision
+OpDecorate %138 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %141 RelaxedPrecision
+OpDecorate %143 RelaxedPrecision
+OpDecorate %144 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %146 RelaxedPrecision
+OpDecorate %147 RelaxedPrecision
+OpDecorate %148 RelaxedPrecision
+OpDecorate %150 RelaxedPrecision
+OpDecorate %151 RelaxedPrecision
+OpDecorate %152 RelaxedPrecision
+OpDecorate %153 RelaxedPrecision
+OpDecorate %154 RelaxedPrecision
+OpDecorate %155 RelaxedPrecision
+OpDecorate %156 RelaxedPrecision
+OpDecorate %158 RelaxedPrecision
+OpDecorate %160 RelaxedPrecision
+OpDecorate %162 RelaxedPrecision
+OpDecorate %163 RelaxedPrecision
+OpDecorate %164 RelaxedPrecision
+OpDecorate %165 RelaxedPrecision
+OpDecorate %166 RelaxedPrecision
+OpDecorate %168 RelaxedPrecision
+OpDecorate %170 RelaxedPrecision
+OpDecorate %172 RelaxedPrecision
+OpDecorate %174 RelaxedPrecision
+OpDecorate %175 RelaxedPrecision
+OpDecorate %177 RelaxedPrecision
+OpDecorate %179 RelaxedPrecision
+OpDecorate %180 RelaxedPrecision
+OpDecorate %181 RelaxedPrecision
+OpDecorate %182 RelaxedPrecision
+OpDecorate %183 RelaxedPrecision
+OpDecorate %185 RelaxedPrecision
+OpDecorate %187 RelaxedPrecision
+OpDecorate %188 RelaxedPrecision
+OpDecorate %194 RelaxedPrecision
+OpDecorate %202 RelaxedPrecision
+OpDecorate %203 RelaxedPrecision
+OpDecorate %206 RelaxedPrecision
+OpDecorate %210 RelaxedPrecision
+OpDecorate %213 RelaxedPrecision
+OpDecorate %217 RelaxedPrecision
+OpDecorate %220 RelaxedPrecision
+OpDecorate %224 RelaxedPrecision
+OpDecorate %226 RelaxedPrecision
+OpDecorate %228 RelaxedPrecision
+OpDecorate %229 RelaxedPrecision
+OpDecorate %231 RelaxedPrecision
+OpDecorate %232 RelaxedPrecision
+OpDecorate %234 RelaxedPrecision
+OpDecorate %235 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%15 = OpTypeFunction %float %_ptr_Function_v2float %_ptr_Function_v2float
+%float_2 = OpConstant %float 2
+%_ptr_Function_float = OpTypePointer Function %float
+%float_1 = OpConstant %float 1
+%float_4 = OpConstant %float 4
+%float_3 = OpConstant %float 3
+%float_6 = OpConstant %float 6
+%float_12 = OpConstant %float 12
+%float_16 = OpConstant %float 16
+%void = OpTypeVoid
+%190 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_0 = OpConstant %float 0
+%_soft_light_component = OpFunction %float None %15
+%17 = OpFunctionParameter %_ptr_Function_v2float
+%18 = OpFunctionParameter %_ptr_Function_v2float
+%19 = OpLabel
+%_11_guarded_divide = OpVariable %_ptr_Function_float Function
+%_12_n = OpVariable %_ptr_Function_float Function
+%DSqd = OpVariable %_ptr_Function_float Function
+%DCub = OpVariable %_ptr_Function_float Function
+%DaSqd = OpVariable %_ptr_Function_float Function
+%DaCub = OpVariable %_ptr_Function_float Function
+%_13_guarded_divide = OpVariable %_ptr_Function_float Function
+%_14_n = OpVariable %_ptr_Function_float Function
+%21 = OpLoad %v2float %17
+%22 = OpCompositeExtract %float %21 0
+%23 = OpFMul %float %float_2 %22
+%24 = OpLoad %v2float %17
+%25 = OpCompositeExtract %float %24 1
+%26 = OpFOrdLessThanEqual %bool %23 %25
+OpSelectionMerge %29 None
+OpBranchConditional %26 %27 %28
+%27 = OpLabel
+%33 = OpLoad %v2float %18
+%34 = OpCompositeExtract %float %33 0
+%35 = OpLoad %v2float %18
+%36 = OpCompositeExtract %float %35 0
+%37 = OpFMul %float %34 %36
+%38 = OpLoad %v2float %17
+%39 = OpCompositeExtract %float %38 1
+%40 = OpLoad %v2float %17
+%41 = OpCompositeExtract %float %40 0
+%42 = OpFMul %float %float_2 %41
+%43 = OpFSub %float %39 %42
+%44 = OpFMul %float %37 %43
+OpStore %_12_n %44
+%45 = OpLoad %float %_12_n
+%46 = OpLoad %v2float %18
+%47 = OpCompositeExtract %float %46 1
+%48 = OpFDiv %float %45 %47
+OpStore %_11_guarded_divide %48
+%49 = OpLoad %float %_11_guarded_divide
+%51 = OpLoad %v2float %18
+%52 = OpCompositeExtract %float %51 1
+%53 = OpFSub %float %float_1 %52
+%54 = OpLoad %v2float %17
+%55 = OpCompositeExtract %float %54 0
+%56 = OpFMul %float %53 %55
+%57 = OpFAdd %float %49 %56
+%58 = OpLoad %v2float %18
+%59 = OpCompositeExtract %float %58 0
+%61 = OpLoad %v2float %17
+%62 = OpCompositeExtract %float %61 1
+%60 = OpFNegate %float %62
+%63 = OpLoad %v2float %17
+%64 = OpCompositeExtract %float %63 0
+%65 = OpFMul %float %float_2 %64
+%66 = OpFAdd %float %60 %65
+%67 = OpFAdd %float %66 %float_1
+%68 = OpFMul %float %59 %67
+%69 = OpFAdd %float %57 %68
+OpReturnValue %69
+%28 = OpLabel
+%71 = OpLoad %v2float %18
+%72 = OpCompositeExtract %float %71 0
+%73 = OpFMul %float %float_4 %72
+%74 = OpLoad %v2float %18
+%75 = OpCompositeExtract %float %74 1
+%76 = OpFOrdLessThanEqual %bool %73 %75
+OpSelectionMerge %79 None
+OpBranchConditional %76 %77 %78
+%77 = OpLabel
+%81 = OpLoad %v2float %18
+%82 = OpCompositeExtract %float %81 0
+%83 = OpLoad %v2float %18
+%84 = OpCompositeExtract %float %83 0
+%85 = OpFMul %float %82 %84
+OpStore %DSqd %85
+%87 = OpLoad %float %DSqd
+%88 = OpLoad %v2float %18
+%89 = OpCompositeExtract %float %88 0
+%90 = OpFMul %float %87 %89
+OpStore %DCub %90
+%92 = OpLoad %v2float %18
+%93 = OpCompositeExtract %float %92 1
+%94 = OpLoad %v2float %18
+%95 = OpCompositeExtract %float %94 1
+%96 = OpFMul %float %93 %95
+OpStore %DaSqd %96
+%98 = OpLoad %float %DaSqd
+%99 = OpLoad %v2float %18
+%100 = OpCompositeExtract %float %99 1
+%101 = OpFMul %float %98 %100
+OpStore %DaCub %101
+%104 = OpLoad %float %DaSqd
+%105 = OpLoad %v2float %17
+%106 = OpCompositeExtract %float %105 0
+%107 = OpLoad %v2float %18
+%108 = OpCompositeExtract %float %107 0
+%110 = OpLoad %v2float %17
+%111 = OpCompositeExtract %float %110 1
+%112 = OpFMul %float %float_3 %111
+%114 = OpLoad %v2float %17
+%115 = OpCompositeExtract %float %114 0
+%116 = OpFMul %float %float_6 %115
+%117 = OpFSub %float %112 %116
+%118 = OpFSub %float %117 %float_1
+%119 = OpFMul %float %108 %118
+%120 = OpFSub %float %106 %119
+%121 = OpFMul %float %104 %120
+%123 = OpLoad %v2float %18
+%124 = OpCompositeExtract %float %123 1
+%125 = OpFMul %float %float_12 %124
+%126 = OpLoad %float %DSqd
+%127 = OpFMul %float %125 %126
+%128 = OpLoad %v2float %17
+%129 = OpCompositeExtract %float %128 1
+%130 = OpLoad %v2float %17
+%131 = OpCompositeExtract %float %130 0
+%132 = OpFMul %float %float_2 %131
+%133 = OpFSub %float %129 %132
+%134 = OpFMul %float %127 %133
+%135 = OpFAdd %float %121 %134
+%137 = OpLoad %float %DCub
+%138 = OpFMul %float %float_16 %137
+%139 = OpLoad %v2float %17
+%140 = OpCompositeExtract %float %139 1
+%141 = OpLoad %v2float %17
+%142 = OpCompositeExtract %float %141 0
+%143 = OpFMul %float %float_2 %142
+%144 = OpFSub %float %140 %143
+%145 = OpFMul %float %138 %144
+%146 = OpFSub %float %135 %145
+%147 = OpLoad %float %DaCub
+%148 = OpLoad %v2float %17
+%149 = OpCompositeExtract %float %148 0
+%150 = OpFMul %float %147 %149
+%151 = OpFSub %float %146 %150
+OpStore %_14_n %151
+%152 = OpLoad %float %_14_n
+%153 = OpLoad %float %DaSqd
+%154 = OpFDiv %float %152 %153
+OpStore %_13_guarded_divide %154
+%155 = OpLoad %float %_13_guarded_divide
+OpReturnValue %155
+%78 = OpLabel
+%156 = OpLoad %v2float %18
+%157 = OpCompositeExtract %float %156 0
+%158 = OpLoad %v2float %17
+%159 = OpCompositeExtract %float %158 1
+%160 = OpLoad %v2float %17
+%161 = OpCompositeExtract %float %160 0
+%162 = OpFMul %float %float_2 %161
+%163 = OpFSub %float %159 %162
+%164 = OpFAdd %float %163 %float_1
+%165 = OpFMul %float %157 %164
+%166 = OpLoad %v2float %17
+%167 = OpCompositeExtract %float %166 0
+%168 = OpFAdd %float %165 %167
+%170 = OpLoad %v2float %18
+%171 = OpCompositeExtract %float %170 1
+%172 = OpLoad %v2float %18
+%173 = OpCompositeExtract %float %172 0
+%174 = OpFMul %float %171 %173
+%169 = OpExtInst %float %1 Sqrt %174
+%175 = OpLoad %v2float %17
+%176 = OpCompositeExtract %float %175 1
+%177 = OpLoad %v2float %17
+%178 = OpCompositeExtract %float %177 0
+%179 = OpFMul %float %float_2 %178
+%180 = OpFSub %float %176 %179
+%181 = OpFMul %float %169 %180
+%182 = OpFSub %float %168 %181
+%183 = OpLoad %v2float %18
+%184 = OpCompositeExtract %float %183 1
+%185 = OpLoad %v2float %17
+%186 = OpCompositeExtract %float %185 0
+%187 = OpFMul %float %184 %186
+%188 = OpFSub %float %182 %187
+OpReturnValue %188
+%79 = OpLabel
+OpBranch %29
+%29 = OpLabel
+OpUnreachable
+OpFunctionEnd
+%main = OpFunction %void None %190
+%191 = OpLabel
+%_0_blend_soft_light = OpVariable %_ptr_Function_v4float Function
+%198 = OpVariable %_ptr_Function_v4float Function
+%205 = OpVariable %_ptr_Function_v2float Function
+%208 = OpVariable %_ptr_Function_v2float Function
+%212 = OpVariable %_ptr_Function_v2float Function
+%215 = OpVariable %_ptr_Function_v2float Function
+%219 = OpVariable %_ptr_Function_v2float Function
+%222 = OpVariable %_ptr_Function_v2float Function
+%194 = OpLoad %v4float %dst
+%195 = OpCompositeExtract %float %194 3
+%197 = OpFOrdEqual %bool %195 %float_0
+OpSelectionMerge %201 None
+OpBranchConditional %197 %199 %200
+%199 = OpLabel
+%202 = OpLoad %v4float %src
+OpStore %198 %202
+OpBranch %201
+%200 = OpLabel
+%203 = OpLoad %v4float %src
+%204 = OpVectorShuffle %v2float %203 %203 0 3
+OpStore %205 %204
+%206 = OpLoad %v4float %dst
+%207 = OpVectorShuffle %v2float %206 %206 0 3
+OpStore %208 %207
+%209 = OpFunctionCall %float %_soft_light_component %205 %208
+%210 = OpLoad %v4float %src
+%211 = OpVectorShuffle %v2float %210 %210 1 3
+OpStore %212 %211
+%213 = OpLoad %v4float %dst
+%214 = OpVectorShuffle %v2float %213 %213 1 3
+OpStore %215 %214
+%216 = OpFunctionCall %float %_soft_light_component %212 %215
+%217 = OpLoad %v4float %src
+%218 = OpVectorShuffle %v2float %217 %217 2 3
+OpStore %219 %218
+%220 = OpLoad %v4float %dst
+%221 = OpVectorShuffle %v2float %220 %220 2 3
+OpStore %222 %221
+%223 = OpFunctionCall %float %_soft_light_component %219 %222
+%224 = OpLoad %v4float %src
+%225 = OpCompositeExtract %float %224 3
+%226 = OpLoad %v4float %src
+%227 = OpCompositeExtract %float %226 3
+%228 = OpFSub %float %float_1 %227
+%229 = OpLoad %v4float %dst
+%230 = OpCompositeExtract %float %229 3
+%231 = OpFMul %float %228 %230
+%232 = OpFAdd %float %225 %231
+%233 = OpCompositeConstruct %v4float %209 %216 %223 %232
+OpStore %198 %233
+OpBranch %201
+%201 = OpLabel
+%234 = OpLoad %v4float %198
+OpStore %_0_blend_soft_light %234
+%235 = OpLoad %v4float %_0_blend_soft_light
+OpStore %sk_FragColor %235
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSrc.asm.frag b/tests/sksl/blend/golden/BlendSrc.asm.frag
new file mode 100644
index 0000000..8f8ee09
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSrc.asm.frag
@@ -0,0 +1,42 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_src "_0_blend_src"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_src = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %src
+OpStore %_0_blend_src %18
+%19 = OpLoad %v4float %_0_blend_src
+OpStore %sk_FragColor %19
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSrcAtop.asm.frag b/tests/sksl/blend/golden/BlendSrcAtop.asm.frag
new file mode 100644
index 0000000..fa36e6c
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSrcAtop.asm.frag
@@ -0,0 +1,57 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_src_atop "_0_blend_src_atop"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_src_atop = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %dst
+%19 = OpCompositeExtract %float %18 3
+%20 = OpLoad %v4float %src
+%21 = OpVectorTimesScalar %v4float %20 %19
+%23 = OpLoad %v4float %src
+%24 = OpCompositeExtract %float %23 3
+%25 = OpFSub %float %float_1 %24
+%26 = OpLoad %v4float %dst
+%27 = OpVectorTimesScalar %v4float %26 %25
+%28 = OpFAdd %v4float %21 %27
+OpStore %_0_blend_src_atop %28
+%29 = OpLoad %v4float %_0_blend_src_atop
+OpStore %sk_FragColor %29
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSrcIn.asm.frag b/tests/sksl/blend/golden/BlendSrcIn.asm.frag
new file mode 100644
index 0000000..f32a271
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSrcIn.asm.frag
@@ -0,0 +1,46 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_src_in "_0_blend_src_in"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_src_in = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %src
+%19 = OpLoad %v4float %dst
+%20 = OpCompositeExtract %float %19 3
+%21 = OpVectorTimesScalar %v4float %18 %20
+OpStore %_0_blend_src_in %21
+%22 = OpLoad %v4float %_0_blend_src_in
+OpStore %sk_FragColor %22
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSrcOut.asm.frag b/tests/sksl/blend/golden/BlendSrcOut.asm.frag
new file mode 100644
index 0000000..7fabe2a
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSrcOut.asm.frag
@@ -0,0 +1,49 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_src_out "_0_blend_src_out"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_src_out = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %dst
+%20 = OpCompositeExtract %float %19 3
+%21 = OpFSub %float %float_1 %20
+%22 = OpLoad %v4float %src
+%23 = OpVectorTimesScalar %v4float %22 %21
+OpStore %_0_blend_src_out %23
+%24 = OpLoad %v4float %_0_blend_src_out
+OpStore %sk_FragColor %24
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendSrcOver.asm.frag b/tests/sksl/blend/golden/BlendSrcOver.asm.frag
new file mode 100644
index 0000000..e613758
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendSrcOver.asm.frag
@@ -0,0 +1,53 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_src_over "_0_blend_src_over"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %18 RelaxedPrecision
+OpDecorate %20 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %23 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_src_over = OpVariable %_ptr_Function_v4float Function
+%18 = OpLoad %v4float %src
+%20 = OpLoad %v4float %src
+%21 = OpCompositeExtract %float %20 3
+%22 = OpFSub %float %float_1 %21
+%23 = OpLoad %v4float %dst
+%24 = OpVectorTimesScalar %v4float %23 %22
+%25 = OpFAdd %v4float %18 %24
+OpStore %_0_blend_src_over %25
+%26 = OpLoad %v4float %_0_blend_src_over
+OpStore %sk_FragColor %26
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/blend/golden/BlendXor.asm.frag b/tests/sksl/blend/golden/BlendXor.asm.frag
new file mode 100644
index 0000000..47da591
--- /dev/null
+++ b/tests/sksl/blend/golden/BlendXor.asm.frag
@@ -0,0 +1,59 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %src %dst
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %src "src"
+OpName %dst "dst"
+OpName %main "main"
+OpName %_0_blend_xor "_0_blend_xor"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %src RelaxedPrecision
+OpDecorate %dst RelaxedPrecision
+OpDecorate %19 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+OpDecorate %27 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+OpDecorate %30 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%src = OpVariable %_ptr_Input_v4float Input
+%dst = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %14
+%15 = OpLabel
+%_0_blend_xor = OpVariable %_ptr_Function_v4float Function
+%19 = OpLoad %v4float %dst
+%20 = OpCompositeExtract %float %19 3
+%21 = OpFSub %float %float_1 %20
+%22 = OpLoad %v4float %src
+%23 = OpVectorTimesScalar %v4float %22 %21
+%24 = OpLoad %v4float %src
+%25 = OpCompositeExtract %float %24 3
+%26 = OpFSub %float %float_1 %25
+%27 = OpLoad %v4float %dst
+%28 = OpVectorTimesScalar %v4float %27 %26
+%29 = OpFAdd %v4float %23 %28
+OpStore %_0_blend_xor %29
+%30 = OpLoad %v4float %_0_blend_xor
+OpStore %sk_FragColor %30
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ArrayConstructors.asm.frag b/tests/sksl/shared/golden/ArrayConstructors.asm.frag
new file mode 100644
index 0000000..ab6f12c
--- /dev/null
+++ b/tests/sksl/shared/golden/ArrayConstructors.asm.frag
@@ -0,0 +1,6 @@
+### Compilation failed:
+
+error: 1: runtime-sized arrays are not supported in SPIR-V
+error: 1: runtime-sized arrays are not supported in SPIR-V
+error: 1: runtime-sized arrays are not supported in SPIR-V
+3 errors
diff --git a/tests/sksl/shared/golden/ArrayIndexTypes.asm.frag b/tests/sksl/shared/golden/ArrayIndexTypes.asm.frag
new file mode 100644
index 0000000..49dd761
--- /dev/null
+++ b/tests/sksl/shared/golden/ArrayIndexTypes.asm.frag
@@ -0,0 +1,63 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %_arr_float_int_4 ArrayStride 16
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%int_4 = OpConstant %int 4
+%_arr_float_int_4 = OpTypeArray %float %int_4
+%_ptr_Function__arr_float_int_4 = OpTypePointer Function %_arr_float_int_4
+%float_1 = OpConstant %float 1
+%float_2 = OpConstant %float 2
+%float_3 = OpConstant %float 3
+%float_4 = OpConstant %float 4
+%int_0 = OpConstant %int 0
+%_ptr_Function_float = OpTypePointer Function %float
+%int_1 = OpConstant %int 1
+%int_2 = OpConstant %int 2
+%uint = OpTypeInt 32 0
+%uint_3 = OpConstant %uint 3
+%main = OpFunction %void None %11
+%12 = OpLabel
+%13 = OpVariable %_ptr_Function__arr_float_int_4 Function
+%27 = OpVariable %_ptr_Function__arr_float_int_4 Function
+%32 = OpVariable %_ptr_Function__arr_float_int_4 Function
+%37 = OpVariable %_ptr_Function__arr_float_int_4 Function
+%22 = OpCompositeConstruct %_arr_float_int_4 %float_1 %float_2 %float_3 %float_4
+OpStore %13 %22
+%24 = OpAccessChain %_ptr_Function_float %13 %int_0
+%26 = OpLoad %float %24
+%28 = OpCompositeConstruct %_arr_float_int_4 %float_1 %float_2 %float_3 %float_4
+OpStore %27 %28
+%30 = OpAccessChain %_ptr_Function_float %27 %int_1
+%31 = OpLoad %float %30
+%33 = OpCompositeConstruct %_arr_float_int_4 %float_1 %float_2 %float_3 %float_4
+OpStore %32 %33
+%35 = OpAccessChain %_ptr_Function_float %32 %int_2
+%36 = OpLoad %float %35
+%38 = OpCompositeConstruct %_arr_float_int_4 %float_1 %float_2 %float_3 %float_4
+OpStore %37 %38
+%41 = OpAccessChain %_ptr_Function_float %37 %uint_3
+%42 = OpLoad %float %41
+%43 = OpCompositeConstruct %v4float %26 %31 %36 %42
+OpStore %sk_FragColor %43
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ArrayMaxDimensions.asm.frag b/tests/sksl/shared/golden/ArrayMaxDimensions.asm.frag
new file mode 100644
index 0000000..2df0733
--- /dev/null
+++ b/tests/sksl/shared/golden/ArrayMaxDimensions.asm.frag
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: program does not contain a main() function
+1 error
diff --git a/tests/sksl/shared/golden/ArrayTypes.asm.frag b/tests/sksl/shared/golden/ArrayTypes.asm.frag
new file mode 100644
index 0000000..551ff8e
--- /dev/null
+++ b/tests/sksl/shared/golden/ArrayTypes.asm.frag
@@ -0,0 +1,59 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %_arr_v2float_int_2 ArrayStride 16
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%v2float = OpTypeVector %float 2
+%int = OpTypeInt 32 1
+%int_2 = OpConstant %int 2
+%_arr_v2float_int_2 = OpTypeArray %v2float %int_2
+%_ptr_Function__arr_v2float_int_2 = OpTypePointer Function %_arr_v2float_int_2
+%float_1 = OpConstant %float 1
+%19 = OpConstantComposite %v2float %float_1 %float_1
+%float_2 = OpConstant %float 2
+%21 = OpConstantComposite %v2float %float_2 %float_2
+%int_0 = OpConstant %int 0
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%float_3 = OpConstant %float 3
+%31 = OpConstantComposite %v2float %float_3 %float_3
+%float_4 = OpConstant %float 4
+%33 = OpConstantComposite %v2float %float_4 %float_4
+%int_1 = OpConstant %int 1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%13 = OpVariable %_ptr_Function__arr_v2float_int_2 Function
+%30 = OpVariable %_ptr_Function__arr_v2float_int_2 Function
+%23 = OpCompositeConstruct %_arr_v2float_int_2 %19 %21
+OpStore %13 %23
+%25 = OpAccessChain %_ptr_Function_v2float %13 %int_0
+%27 = OpLoad %v2float %25
+%28 = OpCompositeExtract %float %27 0
+%29 = OpCompositeExtract %float %27 1
+%35 = OpCompositeConstruct %_arr_v2float_int_2 %31 %33
+OpStore %30 %35
+%37 = OpAccessChain %_ptr_Function_v2float %30 %int_1
+%38 = OpLoad %v2float %37
+%39 = OpCompositeExtract %float %38 0
+%40 = OpCompositeExtract %float %38 1
+%41 = OpCompositeConstruct %v4float %28 %29 %39 %40
+OpStore %sk_FragColor %41
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Assignment.asm.frag b/tests/sksl/shared/golden/Assignment.asm.frag
new file mode 100644
index 0000000..bdead9f
--- /dev/null
+++ b/tests/sksl/shared/golden/Assignment.asm.frag
@@ -0,0 +1,226 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpName %ai "ai"
+OpName %ai4 "ai4"
+OpName %ah2x4 "ah2x4"
+OpName %af4 "af4"
+OpName %S "S"
+OpMemberName %S 0 "f"
+OpMemberName %S 1 "af"
+OpMemberName %S 2 "h4"
+OpMemberName %S 3 "ah4"
+OpName %s "s"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %23 RelaxedPrecision
+OpDecorate %_arr_int_int_1 ArrayStride 16
+OpDecorate %_arr_v4int_int_1 ArrayStride 16
+OpDecorate %_arr_mat2v4float_int_1 ArrayStride 32
+OpDecorate %53 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %52 RelaxedPrecision
+OpDecorate %_arr_v4float_int_1 ArrayStride 16
+OpDecorate %_arr_float_int_5 ArrayStride 16
+OpDecorate %_arr_v4float_int_5 ArrayStride 16
+OpMemberDecorate %S 0 Offset 0
+OpMemberDecorate %S 1 Offset 16
+OpMemberDecorate %S 2 Offset 96
+OpMemberDecorate %S 2 RelaxedPrecision
+OpMemberDecorate %S 3 Offset 112
+OpMemberDecorate %S 3 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %89 RelaxedPrecision
+OpDecorate %118 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %146 RelaxedPrecision
+OpDecorate %148 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_0 = OpConstant %float 0
+%_ptr_Function_float = OpTypePointer Function %float
+%int = OpTypeInt 32 1
+%int_3 = OpConstant %int 3
+%v2float = OpTypeVector %float 2
+%20 = OpConstantComposite %v2float %float_0 %float_0
+%int_1 = OpConstant %int 1
+%_arr_int_int_1 = OpTypeArray %int %int_1
+%_ptr_Function__arr_int_int_1 = OpTypePointer Function %_arr_int_int_1
+%int_0 = OpConstant %int 0
+%_ptr_Function_int = OpTypePointer Function %int
+%v4int = OpTypeVector %int 4
+%_arr_v4int_int_1 = OpTypeArray %v4int %int_1
+%_ptr_Function__arr_v4int_int_1 = OpTypePointer Function %_arr_v4int_int_1
+%int_2 = OpConstant %int 2
+%int_4 = OpConstant %int 4
+%35 = OpConstantComposite %v4int %int_1 %int_2 %int_3 %int_4
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%mat2v4float = OpTypeMatrix %v4float 2
+%_arr_mat2v4float_int_1 = OpTypeArray %mat2v4float %int_1
+%_ptr_Function__arr_mat2v4float_int_1 = OpTypePointer Function %_arr_mat2v4float_int_1
+%float_1 = OpConstant %float 1
+%float_2 = OpConstant %float 2
+%float_3 = OpConstant %float 3
+%float_4 = OpConstant %float 4
+%float_5 = OpConstant %float 5
+%float_6 = OpConstant %float 6
+%float_7 = OpConstant %float 7
+%float_8 = OpConstant %float 8
+%_ptr_Function_mat2v4float = OpTypePointer Function %mat2v4float
+%_arr_v4float_int_1 = OpTypeArray %v4float %int_1
+%_ptr_Function__arr_v4float_int_1 = OpTypePointer Function %_arr_v4float_int_1
+%float_0_0 = OpConstant %float 0
+%float_1_0 = OpConstant %float 1
+%67 = OpConstantComposite %v4float %float_1_0 %float_1_0 %float_1_0 %float_1_0
+%int_5 = OpConstant %int 5
+%_arr_float_int_5 = OpTypeArray %float %int_5
+%_arr_v4float_int_5 = OpTypeArray %v4float %int_5
+%S = OpTypeStruct %float %_arr_float_int_5 %v4float %_arr_v4float_int_5
+%_ptr_Function_S = OpTypePointer Function %S
+%float_9 = OpConstant %float 9
+%v3float = OpTypeVector %float 3
+%80 = OpConstantComposite %v3float %float_9 %float_9 %float_9
+%86 = OpConstantComposite %v2float %float_5 %float_5
+%float_2_0 = OpConstant %float 2
+%93 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%95 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%97 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%99 = OpConstantComposite %v4int %int_1 %int_2 %int_3 %int_4
+%98 = OpConstantComposite %v4float %99 %99 %99 %99
+%mat3v3float = OpTypeMatrix %v3float 3
+%_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
+%float_3_0 = OpConstant %float 3
+%float_4_0 = OpConstant %float 4
+%float_5_0 = OpConstant %float 5
+%float_6_0 = OpConstant %float 6
+%float_7_0 = OpConstant %float 7
+%float_8_0 = OpConstant %float 8
+%float_9_0 = OpConstant %float 9
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+%138 = OpConstantComposite %v4float %float_0_0 %float_0_0 %float_0_0 %float_0_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_v4float Function
+%ai = OpVariable %_ptr_Function__arr_int_int_1 Function
+%ai4 = OpVariable %_ptr_Function__arr_v4int_int_1 Function
+%ah2x4 = OpVariable %_ptr_Function__arr_mat2v4float_int_1 Function
+%af4 = OpVariable %_ptr_Function__arr_v4float_int_1 Function
+%s = OpVariable %_ptr_Function_S Function
+%100 = OpVariable %_ptr_Function_mat3v3float Function
+%16 = OpAccessChain %_ptr_Function_float %x %int_3
+OpStore %16 %float_0
+%22 = OpLoad %v4float %x
+%23 = OpVectorShuffle %v4float %22 %20 5 4 2 3
+OpStore %x %23
+%29 = OpAccessChain %_ptr_Function_int %ai %int_0
+OpStore %29 %int_0
+%38 = OpAccessChain %_ptr_Function_v4int %ai4 %int_0
+OpStore %38 %35
+%53 = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
+%54 = OpCompositeConstruct %v4float %float_5 %float_6 %float_7 %float_8
+%52 = OpCompositeConstruct %mat2v4float %53 %54
+%55 = OpAccessChain %_ptr_Function_mat2v4float %ah2x4 %int_0
+OpStore %55 %52
+%57 = OpAccessChain %_ptr_Function_int %ai %int_0
+OpStore %57 %int_0
+%58 = OpAccessChain %_ptr_Function_int %ai %int_0
+%59 = OpLoad %int %58
+%60 = OpAccessChain %_ptr_Function_int %ai %59
+OpStore %60 %int_0
+%65 = OpAccessChain %_ptr_Function_v4float %af4 %int_0
+%66 = OpAccessChain %_ptr_Function_float %65 %int_0
+OpStore %66 %float_0_0
+%69 = OpAccessChain %_ptr_Function_v4float %af4 %int_0
+%70 = OpLoad %v4float %69
+%71 = OpVectorShuffle %v4float %70 %67 6 4 7 5
+OpStore %69 %71
+%78 = OpAccessChain %_ptr_Function_float %s %int_0
+OpStore %78 %float_0_0
+%79 = OpAccessChain %_ptr_Function_float %s %int_1 %int_1
+OpStore %79 %float_0_0
+%83 = OpAccessChain %_ptr_Function_v4float %s %int_2
+%84 = OpLoad %v4float %83
+%85 = OpVectorShuffle %v4float %84 %80 5 6 4 3
+OpStore %83 %85
+%87 = OpAccessChain %_ptr_Function_v4float %s %int_3 %int_2
+%88 = OpLoad %v4float %87
+%89 = OpVectorShuffle %v4float %88 %86 0 4 2 5
+OpStore %87 %89
+%90 = OpAccessChain %_ptr_Function_float %s %int_0
+OpStore %90 %float_1_0
+%92 = OpAccessChain %_ptr_Function_float %s %int_1 %int_0
+OpStore %92 %float_2_0
+%94 = OpAccessChain %_ptr_Function_v4float %s %int_2
+OpStore %94 %93
+%96 = OpAccessChain %_ptr_Function_v4float %s %int_3 %int_0
+OpStore %96 %95
+OpStore %sk_FragColor %97
+OpStore %sk_FragColor %98
+%111 = OpCompositeConstruct %v3float %float_1_0 %float_2_0 %float_3_0
+%112 = OpCompositeConstruct %v3float %float_4_0 %float_5_0 %float_6_0
+%113 = OpCompositeConstruct %v3float %float_7_0 %float_8_0 %float_9_0
+%110 = OpCompositeConstruct %mat3v3float %111 %112 %113
+OpStore %100 %110
+%114 = OpAccessChain %_ptr_Function_v3float %100 %int_0
+%116 = OpLoad %v3float %114
+%117 = OpVectorShuffle %v4float %116 %116 0 0 1 2
+OpStore %sk_FragColor %117
+%118 = OpLoad %v4float %x
+OpStore %sk_FragColor %118
+%120 = OpAccessChain %_ptr_Function_int %ai %int_0
+%121 = OpLoad %int %120
+%119 = OpConvertSToF %float %121
+%122 = OpCompositeConstruct %v4float %119 %119 %119 %119
+OpStore %sk_FragColor %122
+%123 = OpAccessChain %_ptr_Function_v4int %ai4 %int_0
+%124 = OpLoad %v4int %123
+%125 = OpCompositeExtract %int %124 0
+%126 = OpConvertSToF %float %125
+%127 = OpCompositeExtract %int %124 1
+%128 = OpConvertSToF %float %127
+%129 = OpCompositeExtract %int %124 2
+%130 = OpConvertSToF %float %129
+%131 = OpCompositeExtract %int %124 3
+%132 = OpConvertSToF %float %131
+%133 = OpCompositeConstruct %v4float %126 %128 %130 %132
+OpStore %sk_FragColor %133
+%134 = OpAccessChain %_ptr_Function_v4float %ah2x4 %int_0 %int_0
+%135 = OpLoad %v4float %134
+OpStore %sk_FragColor %135
+%136 = OpAccessChain %_ptr_Function_v4float %af4 %int_0
+%137 = OpLoad %v4float %136
+OpStore %sk_FragColor %137
+OpStore %sk_FragColor %138
+%139 = OpAccessChain %_ptr_Function_float %s %int_0
+%140 = OpLoad %float %139
+%141 = OpCompositeConstruct %v4float %140 %140 %140 %140
+OpStore %sk_FragColor %141
+%142 = OpAccessChain %_ptr_Function_float %s %int_1 %int_1
+%143 = OpLoad %float %142
+%144 = OpCompositeConstruct %v4float %143 %143 %143 %143
+OpStore %sk_FragColor %144
+%145 = OpAccessChain %_ptr_Function_v4float %s %int_2
+%146 = OpLoad %v4float %145
+OpStore %sk_FragColor %146
+%147 = OpAccessChain %_ptr_Function_v4float %s %int_3 %int_0
+%148 = OpLoad %v4float %147
+OpStore %sk_FragColor %148
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/BoolFolding.asm.frag b/tests/sksl/shared/golden/BoolFolding.asm.frag
new file mode 100644
index 0000000..d3d4687
--- /dev/null
+++ b/tests/sksl/shared/golden/BoolFolding.asm.frag
@@ -0,0 +1,47 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_n2 = OpConstant %float -2
+%float_3 = OpConstant %float 3
+%float_n4 = OpConstant %float -4
+%float_5 = OpConstant %float 5
+%float_n6 = OpConstant %float -6
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_1
+%19 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %19 %float_n2
+%21 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %21 %float_3
+%23 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %23 %float_n4
+%25 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %25 %float_5
+%27 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %27 %float_n6
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Caps.asm.frag b/tests/sksl/shared/golden/Caps.asm.frag
new file mode 100644
index 0000000..76c238f
--- /dev/null
+++ b/tests/sksl/shared/golden/Caps.asm.frag
@@ -0,0 +1,33 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %17 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%13 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%16 = OpLoad %v4float %sk_FragColor
+%17 = OpVectorShuffle %v4float %16 %13 4 5 6 3
+OpStore %sk_FragColor %17
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/CastsRoundTowardZero.asm.frag b/tests/sksl/shared/golden/CastsRoundTowardZero.asm.frag
new file mode 100644
index 0000000..2669255
--- /dev/null
+++ b/tests/sksl/shared/golden/CastsRoundTowardZero.asm.frag
@@ -0,0 +1,32 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%float_2 = OpConstant %float 2
+%15 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpStore %sk_FragColor %15
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Clockwise.asm.frag b/tests/sksl/shared/golden/Clockwise.asm.frag
new file mode 100644
index 0000000..1750480
--- /dev/null
+++ b/tests/sksl/shared/golden/Clockwise.asm.frag
@@ -0,0 +1,36 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %14 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%int_n1 = OpConstant %int -1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpLoad %bool %sk_Clockwise
+%15 = OpLogicalNot %bool %14
+%16 = OpSelect %int %15 %int_1 %int_n1
+%13 = OpConvertSToF %float %16
+%20 = OpCompositeConstruct %v4float %13 %13 %13 %13
+OpStore %sk_FragColor %20
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ComplexDelete.asm.frag b/tests/sksl/shared/golden/ComplexDelete.asm.frag
new file mode 100644
index 0000000..061d69a
--- /dev/null
+++ b/tests/sksl/shared/golden/ComplexDelete.asm.frag
@@ -0,0 +1,109 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %colorXform "colorXform"
+OpName %sampler "sampler"
+OpName %main "main"
+OpName %tmpColor "tmpColor"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %colorXform DescriptorSet 0
+OpDecorate %sampler RelaxedPrecision
+OpDecorate %sampler Binding 0
+OpDecorate %23 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%mat4v4float = OpTypeMatrix %v4float 4
+%_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
+%colorXform = OpVariable %_ptr_Uniform_mat4v4float Uniform
+%16 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%15 = OpTypeSampledImage %16
+%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
+%sampler = OpVariable %_ptr_UniformConstant_15 UniformConstant
+%void = OpTypeVoid
+%18 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%v2float = OpTypeVector %float 2
+%24 = OpConstantComposite %v2float %float_1 %float_1
+%float_0 = OpConstant %float 0
+%v4bool = OpTypeVector %bool 4
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %18
+%19 = OpLabel
+%tmpColor = OpVariable %_ptr_Function_v4float Function
+%54 = OpVariable %_ptr_Function_v4float Function
+%23 = OpLoad %15 %sampler
+%22 = OpImageSampleImplicitLod %v4float %23 %24
+OpStore %tmpColor %22
+%27 = OpLoad %mat4v4float %colorXform
+%30 = OpCompositeConstruct %v4float %float_1 %float_0 %float_0 %float_0
+%31 = OpCompositeConstruct %v4float %float_0 %float_1 %float_0 %float_0
+%32 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %float_0
+%33 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_1
+%28 = OpCompositeConstruct %mat4v4float %30 %31 %32 %33
+%35 = OpCompositeExtract %v4float %27 0
+%36 = OpCompositeExtract %v4float %28 0
+%37 = OpFOrdNotEqual %v4bool %35 %36
+%38 = OpAny %bool %37
+%39 = OpCompositeExtract %v4float %27 1
+%40 = OpCompositeExtract %v4float %28 1
+%41 = OpFOrdNotEqual %v4bool %39 %40
+%42 = OpAny %bool %41
+%43 = OpLogicalOr %bool %38 %42
+%44 = OpCompositeExtract %v4float %27 2
+%45 = OpCompositeExtract %v4float %28 2
+%46 = OpFOrdNotEqual %v4bool %44 %45
+%47 = OpAny %bool %46
+%48 = OpLogicalOr %bool %43 %47
+%49 = OpCompositeExtract %v4float %27 3
+%50 = OpCompositeExtract %v4float %28 3
+%51 = OpFOrdNotEqual %v4bool %49 %50
+%52 = OpAny %bool %51
+%53 = OpLogicalOr %bool %48 %52
+OpSelectionMerge %57 None
+OpBranchConditional %53 %55 %56
+%55 = OpLabel
+%59 = OpLoad %mat4v4float %colorXform
+%60 = OpLoad %v4float %tmpColor
+%61 = OpVectorShuffle %v3float %60 %60 0 1 2
+%63 = OpCompositeExtract %float %61 0
+%64 = OpCompositeExtract %float %61 1
+%65 = OpCompositeExtract %float %61 2
+%66 = OpCompositeConstruct %v4float %63 %64 %65 %float_1
+%67 = OpMatrixTimesVector %v4float %59 %66
+%68 = OpVectorShuffle %v3float %67 %67 0 1 2
+%69 = OpCompositeConstruct %v3float %float_0 %float_0 %float_0
+%70 = OpLoad %v4float %tmpColor
+%71 = OpCompositeExtract %float %70 3
+%72 = OpCompositeConstruct %v3float %71 %71 %71
+%58 = OpExtInst %v3float %1 FClamp %68 %69 %72
+%73 = OpCompositeExtract %float %58 0
+%74 = OpCompositeExtract %float %58 1
+%75 = OpCompositeExtract %float %58 2
+%76 = OpLoad %v4float %tmpColor
+%77 = OpCompositeExtract %float %76 3
+%78 = OpCompositeConstruct %v4float %73 %74 %75 %77
+OpStore %54 %78
+OpBranch %57
+%56 = OpLabel
+%79 = OpLoad %v4float %tmpColor
+OpStore %54 %79
+OpBranch %57
+%57 = OpLabel
+%80 = OpLoad %v4float %54
+OpStore %sk_FragColor %80
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ConstArray.asm.frag b/tests/sksl/shared/golden/ConstArray.asm.frag
new file mode 100644
index 0000000..80d9e26
--- /dev/null
+++ b/tests/sksl/shared/golden/ConstArray.asm.frag
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: runtime-sized arrays are not supported in SPIR-V
+1 error
diff --git a/tests/sksl/shared/golden/ConstVariableComparison.asm.frag b/tests/sksl/shared/golden/ConstVariableComparison.asm.frag
new file mode 100644
index 0000000..b4a67d5
--- /dev/null
+++ b/tests/sksl/shared/golden/ConstVariableComparison.asm.frag
@@ -0,0 +1,18 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ConstantIf.asm.frag b/tests/sksl/shared/golden/ConstantIf.asm.frag
new file mode 100644
index 0000000..17aedaf
--- /dev/null
+++ b/tests/sksl/shared/golden/ConstantIf.asm.frag
@@ -0,0 +1,32 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_5 = OpConstant %float 5
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_5
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Control.asm.frag b/tests/sksl/shared/golden/Control.asm.frag
new file mode 100644
index 0000000..84f9e90
--- /dev/null
+++ b/tests/sksl/shared/golden/Control.asm.frag
@@ -0,0 +1,120 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %i "i"
+OpName %i_0 "i"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %34 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_2 = OpConstant %float 2
+%float_5 = OpConstant %float 5
+%float_0_75 = OpConstant %float 0.75
+%20 = OpConstantComposite %v4float %float_0_75 %float_0_75 %float_0_75 %float_0_75
+%int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+%int_0 = OpConstant %int 0
+%int_10 = OpConstant %int 10
+%float_0_5 = OpConstant %float 0.5
+%int_1 = OpConstant %int 1
+%float_0_25 = OpConstant %float 0.25
+%int_2 = OpConstant %int 2
+%main = OpFunction %void None %11
+%12 = OpLabel
+%i = OpVariable %_ptr_Function_int Function
+%i_0 = OpVariable %_ptr_Function_int Function
+%13 = OpExtInst %float %1 Sqrt %float_2
+%16 = OpFOrdGreaterThan %bool %13 %float_5
+OpSelectionMerge %19 None
+OpBranchConditional %16 %17 %18
+%17 = OpLabel
+OpStore %sk_FragColor %20
+OpBranch %19
+%18 = OpLabel
+OpKill
+%19 = OpLabel
+OpStore %i %int_0
+OpBranch %26
+%26 = OpLabel
+OpLoopMerge %30 %29 None
+OpBranch %27
+%27 = OpLabel
+%31 = OpLoad %int %i
+%33 = OpSLessThan %bool %31 %int_10
+OpBranchConditional %33 %28 %30
+%28 = OpLabel
+%34 = OpLoad %v4float %sk_FragColor
+%36 = OpVectorTimesScalar %v4float %34 %float_0_5
+OpStore %sk_FragColor %36
+%37 = OpLoad %int %i
+%39 = OpIAdd %int %37 %int_1
+OpStore %i %39
+OpBranch %29
+%29 = OpLabel
+OpBranch %26
+%30 = OpLabel
+OpBranch %40
+%40 = OpLabel
+OpLoopMerge %44 %43 None
+OpBranch %41
+%41 = OpLabel
+%45 = OpLoad %v4float %sk_FragColor
+%47 = OpCompositeConstruct %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25
+%48 = OpFAdd %v4float %45 %47
+OpStore %sk_FragColor %48
+OpBranch %42
+%42 = OpLabel
+%49 = OpLoad %v4float %sk_FragColor
+%50 = OpCompositeExtract %float %49 0
+%51 = OpFOrdLessThan %bool %50 %float_0_75
+OpBranchConditional %51 %43 %44
+%43 = OpLabel
+OpBranch %40
+%44 = OpLabel
+OpStore %i_0 %int_0
+OpBranch %53
+%53 = OpLabel
+OpLoopMerge %57 %56 None
+OpBranch %54
+%54 = OpLabel
+%58 = OpLoad %int %i_0
+%59 = OpSLessThan %bool %58 %int_10
+OpBranchConditional %59 %55 %57
+%55 = OpLabel
+%60 = OpLoad %int %i_0
+%62 = OpSMod %int %60 %int_2
+%63 = OpIEqual %bool %62 %int_1
+OpSelectionMerge %66 None
+OpBranchConditional %63 %64 %65
+%64 = OpLabel
+OpBranch %57
+%65 = OpLabel
+OpBranch %56
+%66 = OpLabel
+OpBranch %56
+%56 = OpLabel
+%67 = OpLoad %int %i_0
+%68 = OpIAdd %int %67 %int_1
+OpStore %i_0 %68
+OpBranch %53
+%57 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/DeadDoWhileLoop.asm.frag b/tests/sksl/shared/golden/DeadDoWhileLoop.asm.frag
new file mode 100644
index 0000000..66701a7
--- /dev/null
+++ b/tests/sksl/shared/golden/DeadDoWhileLoop.asm.frag
@@ -0,0 +1,41 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%18 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%false = OpConstantFalse %bool
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpBranch %13
+%13 = OpLabel
+OpLoopMerge %17 %16 None
+OpBranch %14
+%14 = OpLabel
+OpStore %sk_FragColor %18
+OpBranch %15
+%15 = OpLabel
+OpBranchConditional %false %16 %17
+%16 = OpLabel
+OpBranch %13
+%17 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/DeadIfStatement.asm.frag b/tests/sksl/shared/golden/DeadIfStatement.asm.frag
new file mode 100644
index 0000000..b4a67d5
--- /dev/null
+++ b/tests/sksl/shared/golden/DeadIfStatement.asm.frag
@@ -0,0 +1,18 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/DeadLoopVariable.asm.frag b/tests/sksl/shared/golden/DeadLoopVariable.asm.frag
new file mode 100644
index 0000000..2d42328
--- /dev/null
+++ b/tests/sksl/shared/golden/DeadLoopVariable.asm.frag
@@ -0,0 +1,30 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%true = OpConstantTrue %bool
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpBranch %9
+%9 = OpLabel
+OpLoopMerge %13 %12 None
+OpBranch %10
+%10 = OpLabel
+OpBranchConditional %true %11 %13
+%11 = OpLabel
+OpBranch %13
+%12 = OpLabel
+OpBranch %9
+%13 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/DependentInitializers.asm.frag b/tests/sksl/shared/golden/DependentInitializers.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/DependentInitializers.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/DerivativesUnused.asm.frag b/tests/sksl/shared/golden/DerivativesUnused.asm.frag
new file mode 100644
index 0000000..a583852
--- /dev/null
+++ b/tests/sksl/shared/golden/DerivativesUnused.asm.frag
@@ -0,0 +1,32 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_1
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Discard.asm.frag b/tests/sksl/shared/golden/Discard.asm.frag
new file mode 100644
index 0000000..b242792
--- /dev/null
+++ b/tests/sksl/shared/golden/Discard.asm.frag
@@ -0,0 +1,26 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpKill
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/FloatFolding.asm.frag b/tests/sksl/shared/golden/FloatFolding.asm.frag
new file mode 100644
index 0000000..03a94ad
--- /dev/null
+++ b/tests/sksl/shared/golden/FloatFolding.asm.frag
@@ -0,0 +1,136 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %73 RelaxedPrecision
+OpDecorate %74 RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %77 RelaxedPrecision
+OpDecorate %79 RelaxedPrecision
+OpDecorate %81 RelaxedPrecision
+OpDecorate %83 RelaxedPrecision
+OpDecorate %84 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_34 = OpConstant %float 34
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_30 = OpConstant %float 30
+%float_64 = OpConstant %float 64
+%float_16 = OpConstant %float 16
+%float_19 = OpConstant %float 19
+%float_1 = OpConstant %float 1
+%float_n2 = OpConstant %float -2
+%float_3 = OpConstant %float 3
+%float_n4 = OpConstant %float -4
+%float_5 = OpConstant %float 5
+%float_n6 = OpConstant %float -6
+%float_7 = OpConstant %float 7
+%float_n8 = OpConstant %float -8
+%float_9 = OpConstant %float 9
+%float_n10 = OpConstant %float -10
+%float_11 = OpConstant %float 11
+%float_n12 = OpConstant %float -12
+%float_1_0 = OpConstant %float 1
+%float_2 = OpConstant %float 2
+%float_3_0 = OpConstant %float 3
+%float_0 = OpConstant %float 0
+%float_5_0 = OpConstant %float 5
+%float_6 = OpConstant %float 6
+%float_8 = OpConstant %float 8
+%float_2_0 = OpConstant %float 2
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_34
+%19 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %19 %float_30
+%21 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %21 %float_64
+%23 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %23 %float_16
+%25 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %25 %float_19
+%27 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %27 %float_1
+%29 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %29 %float_n2
+%31 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %31 %float_3
+%33 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %33 %float_n4
+%35 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %35 %float_5
+%37 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %37 %float_n6
+%39 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %39 %float_7
+%41 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %41 %float_n8
+%43 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %43 %float_9
+%45 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %45 %float_n10
+%47 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %47 %float_11
+%49 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %49 %float_n12
+%50 = OpExtInst %float %1 Sqrt %float_1_0
+%52 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %52 %50
+%53 = OpExtInst %float %1 Sqrt %float_2
+%55 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %55 %53
+%56 = OpExtInst %float %1 Sqrt %float_3_0
+%58 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %58 %56
+%60 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %60 %float_0
+%61 = OpExtInst %float %1 Sqrt %float_5_0
+%63 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %63 %61
+%64 = OpExtInst %float %1 Sqrt %float_6
+%66 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %66 %64
+%67 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %67 %float_0
+%68 = OpExtInst %float %1 Sqrt %float_8
+%70 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %70 %68
+%71 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %71 %float_0
+%72 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+%73 = OpLoad %float %72
+%74 = OpFAdd %float %73 %float_1
+OpStore %72 %74
+%75 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+%76 = OpLoad %float %75
+%77 = OpFSub %float %76 %float_1
+OpStore %75 %77
+%78 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+%79 = OpLoad %float %78
+%81 = OpFMul %float %79 %float_2_0
+OpStore %78 %81
+%82 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+%83 = OpLoad %float %82
+%84 = OpFDiv %float %83 %float_2_0
+OpStore %82 %84
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/FrExp.asm.frag b/tests/sksl/shared/golden/FrExp.asm.frag
new file mode 100644
index 0000000..d68e7b4
--- /dev/null
+++ b/tests/sksl/shared/golden/FrExp.asm.frag
@@ -0,0 +1,40 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %exp "exp"
+OpName %foo "foo"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Function_float = OpTypePointer Function %float
+%float_0_5 = OpConstant %float 0.5
+%main = OpFunction %void None %11
+%12 = OpLabel
+%exp = OpVariable %_ptr_Function_int Function
+%foo = OpVariable %_ptr_Function_float Function
+%18 = OpExtInst %float %1 Frexp %float_0_5 %exp
+OpStore %foo %18
+%21 = OpLoad %int %exp
+%20 = OpConvertSToF %float %21
+%22 = OpCompositeConstruct %v4float %20 %20 %20 %20
+OpStore %sk_FragColor %22
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/FragCoordsFlipY.asm.frag b/tests/sksl/shared/golden/FragCoordsFlipY.asm.frag
new file mode 100644
index 0000000..d42ded1
--- /dev/null
+++ b/tests/sksl/shared/golden/FragCoordsFlipY.asm.frag
@@ -0,0 +1,6 @@
+### Compilation failed:
+
+error: 3: RTHeightOffset is negative
+error: 3: layout(binding=...) is required in SPIR-V
+error: 3: layout(set=...) is required in SPIR-V
+3 errors
diff --git a/tests/sksl/shared/golden/FragCoordsNew.asm.frag b/tests/sksl/shared/golden/FragCoordsNew.asm.frag
new file mode 100644
index 0000000..d42ded1
--- /dev/null
+++ b/tests/sksl/shared/golden/FragCoordsNew.asm.frag
@@ -0,0 +1,6 @@
+### Compilation failed:
+
+error: 3: RTHeightOffset is negative
+error: 3: layout(binding=...) is required in SPIR-V
+error: 3: layout(set=...) is required in SPIR-V
+3 errors
diff --git a/tests/sksl/shared/golden/FragCoordsOld.asm.frag b/tests/sksl/shared/golden/FragCoordsOld.asm.frag
new file mode 100644
index 0000000..d42ded1
--- /dev/null
+++ b/tests/sksl/shared/golden/FragCoordsOld.asm.frag
@@ -0,0 +1,6 @@
+### Compilation failed:
+
+error: 3: RTHeightOffset is negative
+error: 3: layout(binding=...) is required in SPIR-V
+error: 3: layout(set=...) is required in SPIR-V
+3 errors
diff --git a/tests/sksl/shared/golden/FunctionArgumentMatch.asm.frag b/tests/sksl/shared/golden/FunctionArgumentMatch.asm.frag
new file mode 100644
index 0000000..b4a67d5
--- /dev/null
+++ b/tests/sksl/shared/golden/FunctionArgumentMatch.asm.frag
@@ -0,0 +1,18 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/FunctionPrototype.asm.frag b/tests/sksl/shared/golden/FunctionPrototype.asm.frag
new file mode 100644
index 0000000..60de92d
--- /dev/null
+++ b/tests/sksl/shared/golden/FunctionPrototype.asm.frag
@@ -0,0 +1,45 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %this_function_is_defined_before_use "this_function_is_defined_before_use"
+OpName %main "main"
+OpName %this_function_is_defined_after_use "this_function_is_defined_after_use"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%12 = OpTypeFunction %v4float
+%float_1 = OpConstant %float 1
+%14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%void = OpTypeVoid
+%17 = OpTypeFunction %void
+%float_2 = OpConstant %float 2
+%22 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%this_function_is_defined_before_use = OpFunction %v4float None %12
+%13 = OpLabel
+OpReturnValue %14
+OpFunctionEnd
+%main = OpFunction %void None %17
+%18 = OpLabel
+%19 = OpFunctionCall %v4float %this_function_is_defined_before_use
+OpStore %sk_FragColor %19
+%20 = OpFunctionCall %v4float %this_function_is_defined_after_use
+OpStore %sk_FragColor %20
+OpReturn
+OpFunctionEnd
+%this_function_is_defined_after_use = OpFunction %v4float None %12
+%21 = OpLabel
+OpReturnValue %22
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Functions.asm.frag b/tests/sksl/shared/golden/Functions.asm.frag
new file mode 100644
index 0000000..80956d7
--- /dev/null
+++ b/tests/sksl/shared/golden/Functions.asm.frag
@@ -0,0 +1,84 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpName %_2_y "_2_y"
+OpName %_3_z "_3_z"
+OpName %_4_0_foo "_4_0_foo"
+OpName %_5_a "_5_a"
+OpName %_6_1_arr "_6_1_arr"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %_arr_float_int_2 ArrayStride 16
+OpDecorate %_arr__arr_float_int_2_int_3 ArrayStride 32
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_10 = OpConstant %float 10
+%int = OpTypeInt 32 1
+%int_2 = OpConstant %int 2
+%_arr_float_int_2 = OpTypeArray %float %int_2
+%_ptr_Function__arr_float_int_2 = OpTypePointer Function %_arr_float_int_2
+%int_0 = OpConstant %int 0
+%float_20 = OpConstant %float 20
+%int_1 = OpConstant %int 1
+%int_3 = OpConstant %int 3
+%_arr__arr_float_int_2_int_3 = OpTypeArray %_arr_float_int_2 %int_3
+%_ptr_Function__arr__arr_float_int_2_int_3 = OpTypePointer Function %_arr__arr_float_int_2_int_3
+%float_123 = OpConstant %float 123
+%float_456 = OpConstant %float 456
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_float Function
+%_2_y = OpVariable %_ptr_Function__arr_float_int_2 Function
+%_3_z = OpVariable %_ptr_Function_float Function
+%_4_0_foo = OpVariable %_ptr_Function_float Function
+%_5_a = OpVariable %_ptr_Function__arr__arr_float_int_2_int_3 Function
+%_6_1_arr = OpVariable %_ptr_Function_float Function
+OpStore %x %float_10
+%23 = OpAccessChain %_ptr_Function_float %_2_y %int_0
+OpStore %23 %float_10
+%26 = OpAccessChain %_ptr_Function_float %_2_y %int_1
+OpStore %26 %float_20
+%28 = OpAccessChain %_ptr_Function_float %_2_y %int_0
+%29 = OpLoad %float %28
+%30 = OpAccessChain %_ptr_Function_float %_2_y %int_1
+%31 = OpLoad %float %30
+%32 = OpFMul %float %29 %31
+OpStore %_4_0_foo %32
+%33 = OpLoad %float %_4_0_foo
+OpStore %_3_z %33
+%39 = OpAccessChain %_ptr_Function_float %_5_a %int_0 %int_0
+OpStore %39 %float_123
+%41 = OpAccessChain %_ptr_Function_float %_5_a %int_1 %int_2
+OpStore %41 %float_456
+%43 = OpAccessChain %_ptr_Function_float %_5_a %int_0 %int_0
+%44 = OpLoad %float %43
+%45 = OpAccessChain %_ptr_Function_float %_5_a %int_1 %int_2
+%46 = OpLoad %float %45
+%47 = OpFMul %float %44 %46
+OpStore %_6_1_arr %47
+%48 = OpLoad %float %_3_z
+%49 = OpLoad %float %_6_1_arr
+%50 = OpFAdd %float %48 %49
+OpStore %x %50
+%51 = OpLoad %float %x
+%52 = OpCompositeConstruct %v4float %51 %51 %51 %51
+OpStore %sk_FragColor %52
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Geometry.asm.frag b/tests/sksl/shared/golden/Geometry.asm.frag
new file mode 100644
index 0000000..8655ace
--- /dev/null
+++ b/tests/sksl/shared/golden/Geometry.asm.frag
@@ -0,0 +1,60 @@
+OpCapability Geometry
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Geometry %main "main" %3 %8 %sk_InvocationID
+OpExecutionMode %main InputPoints
+OpExecutionMode %main OutputLineStrip
+OpExecutionMode %main OutputVertices 2
+OpExecutionMode %main Invocations 2
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_InvocationID "sk_InvocationID"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %_arr_sk_PerVertex_int_1 ArrayStride 32
+OpDecorate %sk_InvocationID BuiltIn InvocationId
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_sk_PerVertex_int_1 = OpTypeArray %sk_PerVertex %int_1
+%_ptr_Input__arr_sk_PerVertex_int_1 = OpTypePointer Input %_arr_sk_PerVertex_int_1
+%8 = OpVariable %_ptr_Input__arr_sk_PerVertex_int_1 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%sk_InvocationID = OpVariable %_ptr_Input_int Input
+%void = OpTypeVoid
+%16 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%float_n0_5 = OpConstant %float -0.5
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_0_5 = OpConstant %float 0.5
+%main = OpFunction %void None %16
+%17 = OpLabel
+%19 = OpAccessChain %_ptr_Input_v4float %8 %int_0 %int_0
+%21 = OpLoad %v4float %19
+%25 = OpLoad %int %sk_InvocationID
+%24 = OpConvertSToF %float %25
+%26 = OpCompositeConstruct %v4float %float_n0_5 %float_0 %float_0 %24
+%27 = OpFAdd %v4float %21 %26
+%28 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %28 %27
+OpEmitVertex
+%31 = OpAccessChain %_ptr_Input_v4float %8 %int_0 %int_0
+%32 = OpLoad %v4float %31
+%35 = OpLoad %int %sk_InvocationID
+%34 = OpConvertSToF %float %35
+%36 = OpCompositeConstruct %v4float %float_0_5 %float_0 %float_0 %34
+%37 = OpFAdd %v4float %32 %36
+%38 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %38 %37
+OpEmitVertex
+OpEndPrimitive
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/GeometryExtension.asm.frag b/tests/sksl/shared/golden/GeometryExtension.asm.frag
new file mode 100644
index 0000000..592863f
--- /dev/null
+++ b/tests/sksl/shared/golden/GeometryExtension.asm.frag
@@ -0,0 +1,50 @@
+OpCapability Geometry
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Geometry %main "main" %3 %8 %sk_InvocationID
+OpExecutionMode %main InputPoints
+OpExecutionMode %main OutputLineStrip
+OpExecutionMode %main OutputVertices 2
+OpExecutionMode %main Invocations 3
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_InvocationID "sk_InvocationID"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %_arr_sk_PerVertex_int_1 ArrayStride 32
+OpDecorate %sk_InvocationID BuiltIn InvocationId
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_sk_PerVertex_int_1 = OpTypeArray %sk_PerVertex %int_1
+%_ptr_Input__arr_sk_PerVertex_int_1 = OpTypePointer Input %_arr_sk_PerVertex_int_1
+%8 = OpVariable %_ptr_Input__arr_sk_PerVertex_int_1 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%sk_InvocationID = OpVariable %_ptr_Input_int Input
+%void = OpTypeVoid
+%16 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%float_n0_5 = OpConstant %float -0.5
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%main = OpFunction %void None %16
+%17 = OpLabel
+%19 = OpAccessChain %_ptr_Input_v4float %8 %int_0 %int_0
+%21 = OpLoad %v4float %19
+%25 = OpLoad %int %sk_InvocationID
+%24 = OpConvertSToF %float %25
+%26 = OpCompositeConstruct %v4float %float_n0_5 %float_0 %float_0 %24
+%27 = OpFAdd %v4float %21 %26
+%28 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %28 %27
+OpEmitVertex
+OpEndPrimitive
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/GeometryGSInvocations.asm.frag b/tests/sksl/shared/golden/GeometryGSInvocations.asm.frag
new file mode 100644
index 0000000..592863f
--- /dev/null
+++ b/tests/sksl/shared/golden/GeometryGSInvocations.asm.frag
@@ -0,0 +1,50 @@
+OpCapability Geometry
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Geometry %main "main" %3 %8 %sk_InvocationID
+OpExecutionMode %main InputPoints
+OpExecutionMode %main OutputLineStrip
+OpExecutionMode %main OutputVertices 2
+OpExecutionMode %main Invocations 3
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_InvocationID "sk_InvocationID"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %_arr_sk_PerVertex_int_1 ArrayStride 32
+OpDecorate %sk_InvocationID BuiltIn InvocationId
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_sk_PerVertex_int_1 = OpTypeArray %sk_PerVertex %int_1
+%_ptr_Input__arr_sk_PerVertex_int_1 = OpTypePointer Input %_arr_sk_PerVertex_int_1
+%8 = OpVariable %_ptr_Input__arr_sk_PerVertex_int_1 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%sk_InvocationID = OpVariable %_ptr_Input_int Input
+%void = OpTypeVoid
+%16 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%float_n0_5 = OpConstant %float -0.5
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%main = OpFunction %void None %16
+%17 = OpLabel
+%19 = OpAccessChain %_ptr_Input_v4float %8 %int_0 %int_0
+%21 = OpLoad %v4float %19
+%25 = OpLoad %int %sk_InvocationID
+%24 = OpConvertSToF %float %25
+%26 = OpCompositeConstruct %v4float %float_n0_5 %float_0 %float_0 %24
+%27 = OpFAdd %v4float %21 %26
+%28 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %28 %27
+OpEmitVertex
+OpEndPrimitive
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/GeometryNoGSInvocations.asm.frag b/tests/sksl/shared/golden/GeometryNoGSInvocations.asm.frag
new file mode 100644
index 0000000..5f7b84d
--- /dev/null
+++ b/tests/sksl/shared/golden/GeometryNoGSInvocations.asm.frag
@@ -0,0 +1,84 @@
+OpCapability Geometry
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Geometry %main "main" %4 %9
+OpExecutionMode %main InputPoints
+OpExecutionMode %main OutputLineStrip
+OpExecutionMode %main OutputVertices 4
+OpExecutionMode %main Invocations 1
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_InvocationID "sk_InvocationID"
+OpName %_invoke "_invoke"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %_arr_sk_PerVertex_int_1 ArrayStride 32
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%4 = OpVariable %_ptr_Output_sk_PerVertex Output
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_sk_PerVertex_int_1 = OpTypeArray %sk_PerVertex %int_1
+%_ptr_Input__arr_sk_PerVertex_int_1 = OpTypePointer Input %_arr_sk_PerVertex_int_1
+%9 = OpVariable %_ptr_Input__arr_sk_PerVertex_int_1 Input
+%_ptr_Private_int = OpTypePointer Private %int
+%sk_InvocationID = OpVariable %_ptr_Private_int Private
+%void = OpTypeVoid
+%17 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%float_0_5 = OpConstant %float 0.5
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_n0_5 = OpConstant %float -0.5
+%int_2 = OpConstant %int 2
+%bool = OpTypeBool
+%_invoke = OpFunction %void None %17
+%18 = OpLabel
+%20 = OpAccessChain %_ptr_Input_v4float %9 %int_0 %int_0
+%22 = OpLoad %v4float %20
+%26 = OpLoad %int %sk_InvocationID
+%25 = OpConvertSToF %float %26
+%27 = OpCompositeConstruct %v4float %float_0_5 %float_0 %float_0 %25
+%28 = OpFAdd %v4float %22 %27
+%29 = OpAccessChain %_ptr_Output_v4float %4 %int_0
+OpStore %29 %28
+OpEmitVertex
+%32 = OpAccessChain %_ptr_Input_v4float %9 %int_0 %int_0
+%33 = OpLoad %v4float %32
+%36 = OpLoad %int %sk_InvocationID
+%35 = OpConvertSToF %float %36
+%37 = OpCompositeConstruct %v4float %float_n0_5 %float_0 %float_0 %35
+%38 = OpFAdd %v4float %33 %37
+%39 = OpAccessChain %_ptr_Output_v4float %4 %int_0
+OpStore %39 %38
+OpEmitVertex
+OpReturn
+OpFunctionEnd
+%main = OpFunction %void None %17
+%41 = OpLabel
+OpStore %sk_InvocationID %int_0
+OpBranch %42
+%42 = OpLabel
+OpLoopMerge %46 %45 None
+OpBranch %43
+%43 = OpLabel
+%47 = OpLoad %int %sk_InvocationID
+%49 = OpSLessThan %bool %47 %int_2
+OpBranchConditional %49 %44 %46
+%44 = OpLabel
+%51 = OpFunctionCall %void %_invoke
+OpEndPrimitive
+OpBranch %45
+%45 = OpLabel
+%53 = OpLoad %int %sk_InvocationID
+%54 = OpIAdd %int %53 %int_1
+OpStore %sk_InvocationID %54
+OpBranch %42
+%46 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/GeometryNoGSInvocationsReorder.asm.frag b/tests/sksl/shared/golden/GeometryNoGSInvocationsReorder.asm.frag
new file mode 100644
index 0000000..a389176
--- /dev/null
+++ b/tests/sksl/shared/golden/GeometryNoGSInvocationsReorder.asm.frag
@@ -0,0 +1,84 @@
+OpCapability Geometry
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Geometry %main "main" %4 %9
+OpExecutionMode %main InputPoints
+OpExecutionMode %main OutputLineStrip
+OpExecutionMode %main OutputVertices 2
+OpExecutionMode %main Invocations 1
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_InvocationID "sk_InvocationID"
+OpName %_invoke "_invoke"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %_arr_sk_PerVertex_int_1 ArrayStride 32
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%4 = OpVariable %_ptr_Output_sk_PerVertex Output
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_sk_PerVertex_int_1 = OpTypeArray %sk_PerVertex %int_1
+%_ptr_Input__arr_sk_PerVertex_int_1 = OpTypePointer Input %_arr_sk_PerVertex_int_1
+%9 = OpVariable %_ptr_Input__arr_sk_PerVertex_int_1 Input
+%_ptr_Private_int = OpTypePointer Private %int
+%sk_InvocationID = OpVariable %_ptr_Private_int Private
+%void = OpTypeVoid
+%17 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%float_0_5 = OpConstant %float 0.5
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%float_n0_5 = OpConstant %float -0.5
+%int_2 = OpConstant %int 2
+%bool = OpTypeBool
+%_invoke = OpFunction %void None %17
+%18 = OpLabel
+%20 = OpAccessChain %_ptr_Input_v4float %9 %int_0 %int_0
+%22 = OpLoad %v4float %20
+%26 = OpLoad %int %sk_InvocationID
+%25 = OpConvertSToF %float %26
+%27 = OpCompositeConstruct %v4float %float_0_5 %float_0 %float_0 %25
+%28 = OpFAdd %v4float %22 %27
+%29 = OpAccessChain %_ptr_Output_v4float %4 %int_0
+OpStore %29 %28
+OpEmitVertex
+%32 = OpAccessChain %_ptr_Input_v4float %9 %int_0 %int_0
+%33 = OpLoad %v4float %32
+%36 = OpLoad %int %sk_InvocationID
+%35 = OpConvertSToF %float %36
+%37 = OpCompositeConstruct %v4float %float_n0_5 %float_0 %float_0 %35
+%38 = OpFAdd %v4float %33 %37
+%39 = OpAccessChain %_ptr_Output_v4float %4 %int_0
+OpStore %39 %38
+OpEmitVertex
+OpReturn
+OpFunctionEnd
+%main = OpFunction %void None %17
+%41 = OpLabel
+OpStore %sk_InvocationID %int_0
+OpBranch %42
+%42 = OpLabel
+OpLoopMerge %46 %45 None
+OpBranch %43
+%43 = OpLabel
+%47 = OpLoad %int %sk_InvocationID
+%49 = OpSLessThan %bool %47 %int_2
+OpBranchConditional %49 %44 %46
+%44 = OpLabel
+%51 = OpFunctionCall %void %_invoke
+OpEndPrimitive
+OpBranch %45
+%45 = OpLabel
+%53 = OpLoad %int %sk_InvocationID
+%54 = OpIAdd %int %53 %int_1
+OpStore %sk_InvocationID %54
+OpBranch %42
+%46 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Height.asm.frag b/tests/sksl/shared/golden/Height.asm.frag
new file mode 100644
index 0000000..642860c
--- /dev/null
+++ b/tests/sksl/shared/golden/Height.asm.frag
@@ -0,0 +1,2 @@
+### Compilation failed:
+
diff --git a/tests/sksl/shared/golden/HelloWorld.asm.frag b/tests/sksl/shared/golden/HelloWorld.asm.frag
new file mode 100644
index 0000000..e4cb61c
--- /dev/null
+++ b/tests/sksl/shared/golden/HelloWorld.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_0_75 = OpConstant %float 0.75
+%13 = OpConstantComposite %v4float %float_0_75 %float_0_75 %float_0_75 %float_0_75
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Hex.asm.frag b/tests/sksl/shared/golden/Hex.asm.frag
new file mode 100644
index 0000000..2b5b5f5
--- /dev/null
+++ b/tests/sksl/shared/golden/Hex.asm.frag
@@ -0,0 +1,96 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %i1 "i1"
+OpName %i2 "i2"
+OpName %i3 "i3"
+OpName %i4 "i4"
+OpName %i5 "i5"
+OpName %u1 "u1"
+OpName %u2 "u2"
+OpName %u3 "u3"
+OpName %u4 "u4"
+OpName %u5 "u5"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %53 RelaxedPrecision
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_305441741 = OpConstant %int 305441741
+%int_2147483647 = OpConstant %int 2147483647
+%int_n1 = OpConstant %int -1
+%int_n48879 = OpConstant %int -48879
+%uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_0 = OpConstant %uint 0
+%uint_1 = OpConstant %uint 1
+%uint_305441741 = OpConstant %uint 305441741
+%uint_2147483647 = OpConstant %uint 2147483647
+%uint_4294967295 = OpConstant %uint 4294967295
+%uint_65535 = OpConstant %uint 65535
+%uint_1_0 = OpConstant %uint 1
+%main = OpFunction %void None %7
+%8 = OpLabel
+%i1 = OpVariable %_ptr_Function_int Function
+%i2 = OpVariable %_ptr_Function_int Function
+%i3 = OpVariable %_ptr_Function_int Function
+%i4 = OpVariable %_ptr_Function_int Function
+%i5 = OpVariable %_ptr_Function_int Function
+%u1 = OpVariable %_ptr_Function_uint Function
+%u2 = OpVariable %_ptr_Function_uint Function
+%u3 = OpVariable %_ptr_Function_uint Function
+%u4 = OpVariable %_ptr_Function_uint Function
+%u5 = OpVariable %_ptr_Function_uint Function
+OpStore %i1 %int_0
+%13 = OpLoad %int %i1
+%15 = OpIAdd %int %13 %int_1
+OpStore %i1 %15
+OpStore %i2 %int_305441741
+%18 = OpLoad %int %i2
+%19 = OpIAdd %int %18 %int_1
+OpStore %i2 %19
+OpStore %i3 %int_2147483647
+%22 = OpLoad %int %i3
+%23 = OpIAdd %int %22 %int_1
+OpStore %i3 %23
+OpStore %i4 %int_n1
+%26 = OpLoad %int %i4
+%27 = OpIAdd %int %26 %int_1
+OpStore %i4 %27
+OpStore %i5 %int_n48879
+%30 = OpLoad %int %i5
+%31 = OpIAdd %int %30 %int_1
+OpStore %i5 %31
+OpStore %u1 %uint_0
+%36 = OpLoad %uint %u1
+%38 = OpIAdd %uint %36 %uint_1
+OpStore %u1 %38
+OpStore %u2 %uint_305441741
+%41 = OpLoad %uint %u2
+%42 = OpIAdd %uint %41 %uint_1
+OpStore %u2 %42
+OpStore %u3 %uint_2147483647
+%45 = OpLoad %uint %u3
+%46 = OpIAdd %uint %45 %uint_1
+OpStore %u3 %46
+OpStore %u4 %uint_4294967295
+%49 = OpLoad %uint %u4
+%50 = OpIAdd %uint %49 %uint_1
+OpStore %u4 %50
+OpStore %u5 %uint_65535
+%53 = OpLoad %uint %u5
+%55 = OpIAdd %uint %53 %uint_1_0
+OpStore %u5 %55
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/InstanceID.asm.frag b/tests/sksl/shared/golden/InstanceID.asm.frag
new file mode 100644
index 0000000..2289321
--- /dev/null
+++ b/tests/sksl/shared/golden/InstanceID.asm.frag
@@ -0,0 +1,21 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %sk_InstanceID %id
+OpName %sk_InstanceID "sk_InstanceID"
+OpName %id "id"
+OpName %main "main"
+OpDecorate %sk_InstanceID BuiltIn InstanceIndex
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%sk_InstanceID = OpVariable %_ptr_Input_int Input
+%_ptr_Output_int = OpTypePointer Output %int
+%id = OpVariable %_ptr_Output_int Output
+%void = OpTypeVoid
+%9 = OpTypeFunction %void
+%main = OpFunction %void None %9
+%10 = OpLabel
+%11 = OpLoad %int %sk_InstanceID
+OpStore %id %11
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/IntFolding.asm.frag b/tests/sksl/shared/golden/IntFolding.asm.frag
new file mode 100644
index 0000000..d69204e
--- /dev/null
+++ b/tests/sksl/shared/golden/IntFolding.asm.frag
@@ -0,0 +1,160 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_34 = OpConstant %float 34
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_30 = OpConstant %float 30
+%float_64 = OpConstant %float 64
+%float_16 = OpConstant %float 16
+%float_14 = OpConstant %float 14
+%float_6 = OpConstant %float 6
+%float_5 = OpConstant %float 5
+%float_32 = OpConstant %float 32
+%float_33 = OpConstant %float 33
+%float_1 = OpConstant %float 1
+%float_n2 = OpConstant %float -2
+%float_3 = OpConstant %float 3
+%float_n4 = OpConstant %float -4
+%float_n6 = OpConstant %float -6
+%float_7 = OpConstant %float 7
+%float_n8 = OpConstant %float -8
+%float_9 = OpConstant %float 9
+%float_n10 = OpConstant %float -10
+%float_11 = OpConstant %float 11
+%float_n12 = OpConstant %float -12
+%float_1_0 = OpConstant %float 1
+%float_2 = OpConstant %float 2
+%float_3_0 = OpConstant %float 3
+%float_0 = OpConstant %float 0
+%float_5_0 = OpConstant %float 5
+%float_6_0 = OpConstant %float 6
+%float_8 = OpConstant %float 8
+%_ptr_Function_int = OpTypePointer Function %int
+%int_1 = OpConstant %int 1
+%int_2 = OpConstant %int 2
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_int Function
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_34
+%19 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %19 %float_30
+%21 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %21 %float_64
+%23 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %23 %float_16
+%25 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %25 %float_14
+%27 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %27 %float_6
+%29 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %29 %float_5
+%30 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %30 %float_16
+%32 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %32 %float_32
+%34 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %34 %float_33
+%36 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %36 %float_1
+%38 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %38 %float_n2
+%40 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %40 %float_3
+%42 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %42 %float_n4
+%43 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %43 %float_5
+%45 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %45 %float_n6
+%47 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %47 %float_7
+%49 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %49 %float_n8
+%51 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %51 %float_9
+%53 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %53 %float_n10
+%55 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %55 %float_11
+%57 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %57 %float_n12
+%60 = OpExtInst %float %1 Sqrt %float_1_0
+%59 = OpConvertFToS %int %60
+%58 = OpConvertSToF %float %59
+%62 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %62 %58
+%65 = OpExtInst %float %1 Sqrt %float_2
+%64 = OpConvertFToS %int %65
+%63 = OpConvertSToF %float %64
+%67 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %67 %63
+%70 = OpExtInst %float %1 Sqrt %float_3_0
+%69 = OpConvertFToS %int %70
+%68 = OpConvertSToF %float %69
+%72 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %72 %68
+%74 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %74 %float_0
+%77 = OpExtInst %float %1 Sqrt %float_5_0
+%76 = OpConvertFToS %int %77
+%75 = OpConvertSToF %float %76
+%79 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %79 %75
+%82 = OpExtInst %float %1 Sqrt %float_6_0
+%81 = OpConvertFToS %int %82
+%80 = OpConvertSToF %float %81
+%84 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %84 %80
+%85 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %85 %float_0
+%88 = OpExtInst %float %1 Sqrt %float_8
+%87 = OpConvertFToS %int %88
+%86 = OpConvertSToF %float %87
+%90 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %90 %86
+%91 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %91 %float_0
+%95 = OpExtInst %float %1 Sqrt %float_2
+%94 = OpConvertFToS %int %95
+OpStore %x %94
+%96 = OpLoad %int %x
+%98 = OpIAdd %int %96 %int_1
+OpStore %x %98
+%99 = OpLoad %int %x
+%100 = OpISub %int %99 %int_1
+OpStore %x %100
+%101 = OpLoad %int %x
+%103 = OpIMul %int %101 %int_2
+OpStore %x %103
+%104 = OpLoad %int %x
+%105 = OpSDiv %int %104 %int_2
+OpStore %x %105
+%107 = OpLoad %int %x
+%106 = OpConvertSToF %float %107
+%108 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %108 %106
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/InterfaceBlockAnonymous.asm.frag b/tests/sksl/shared/golden/InterfaceBlockAnonymous.asm.frag
new file mode 100644
index 0000000..60d6cbe
--- /dev/null
+++ b/tests/sksl/shared/golden/InterfaceBlockAnonymous.asm.frag
@@ -0,0 +1,68 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %testBlock "testBlock"
+OpMemberName %testBlock 0 "x"
+OpMemberName %testBlock 1 "y"
+OpMemberName %testBlock 2 "z"
+OpMemberName %testBlock 3 "w"
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %_arr_float_int_2 ArrayStride 16
+OpMemberDecorate %testBlock 0 Offset 0
+OpMemberDecorate %testBlock 0 RelaxedPrecision
+OpMemberDecorate %testBlock 1 Offset 16
+OpMemberDecorate %testBlock 1 RelaxedPrecision
+OpMemberDecorate %testBlock 2 Binding 12
+OpMemberDecorate %testBlock 2 Offset 48
+OpMemberDecorate %testBlock 2 ColMajor
+OpMemberDecorate %testBlock 2 MatrixStride 16
+OpMemberDecorate %testBlock 2 RelaxedPrecision
+OpMemberDecorate %testBlock 3 Offset 96
+OpMemberDecorate %testBlock 3 RelaxedPrecision
+OpDecorate %testBlock Block
+OpDecorate %3 DescriptorSet 0
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %24 RelaxedPrecision
+OpDecorate %27 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+%float = OpTypeFloat 32
+%int = OpTypeInt 32 1
+%int_2 = OpConstant %int 2
+%_arr_float_int_2 = OpTypeArray %float %int_2
+%v2float = OpTypeVector %float 2
+%mat3v2float = OpTypeMatrix %v2float 3
+%bool = OpTypeBool
+%testBlock = OpTypeStruct %float %_arr_float_int_2 %mat3v2float %bool
+%_ptr_Uniform_testBlock = OpTypePointer Uniform %testBlock
+%3 = OpVariable %_ptr_Uniform_testBlock Uniform
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%19 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Uniform_float = OpTypePointer Uniform %float
+%int_1 = OpConstant %int 1
+%float_0 = OpConstant %float 0
+%main = OpFunction %void None %19
+%20 = OpLabel
+%22 = OpAccessChain %_ptr_Uniform_float %3 %int_0
+%24 = OpLoad %float %22
+%26 = OpAccessChain %_ptr_Uniform_float %3 %int_1 %int_0
+%27 = OpLoad %float %26
+%28 = OpAccessChain %_ptr_Uniform_float %3 %int_1 %int_1
+%29 = OpLoad %float %28
+%31 = OpCompositeConstruct %v4float %24 %27 %29 %float_0
+OpStore %sk_FragColor %31
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/InterfaceBlockArray.asm.frag b/tests/sksl/shared/golden/InterfaceBlockArray.asm.frag
new file mode 100644
index 0000000..c38a5e1
--- /dev/null
+++ b/tests/sksl/shared/golden/InterfaceBlockArray.asm.frag
@@ -0,0 +1,45 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %testBlock "testBlock"
+OpMemberName %testBlock 0 "x"
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpMemberDecorate %testBlock 0 Offset 0
+OpDecorate %_arr_testBlock_int_2 ArrayStride 16
+OpDecorate %_arr_testBlock_int_2 Block
+OpDecorate %3 DescriptorSet 0
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%testBlock = OpTypeStruct %float
+%int = OpTypeInt 32 1
+%int_2 = OpConstant %int 2
+%_arr_testBlock_int_2 = OpTypeArray %testBlock %int_2
+%_ptr_Uniform__arr_testBlock_int_2 = OpTypePointer Uniform %_arr_testBlock_int_2
+%3 = OpVariable %_ptr_Uniform__arr_testBlock_int_2 Uniform
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%17 = OpTypeFunction %void
+%int_1 = OpConstant %int 1
+%int_0 = OpConstant %int 0
+%_ptr_Uniform_float = OpTypePointer Uniform %float
+%main = OpFunction %void None %17
+%18 = OpLabel
+%21 = OpAccessChain %_ptr_Uniform_float %3 %int_1 %int_0
+%23 = OpLoad %float %21
+%24 = OpCompositeConstruct %v4float %23 %23 %23 %23
+OpStore %sk_FragColor %24
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/InterfaceBlockNamed.asm.frag b/tests/sksl/shared/golden/InterfaceBlockNamed.asm.frag
new file mode 100644
index 0000000..d384e7b
--- /dev/null
+++ b/tests/sksl/shared/golden/InterfaceBlockNamed.asm.frag
@@ -0,0 +1,41 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %testBlock "testBlock"
+OpMemberName %testBlock 0 "x"
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpMemberDecorate %testBlock 0 Offset 0
+OpDecorate %testBlock Block
+OpDecorate %3 DescriptorSet 0
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%testBlock = OpTypeStruct %float
+%_ptr_Uniform_testBlock = OpTypePointer Uniform %testBlock
+%3 = OpVariable %_ptr_Uniform_testBlock Uniform
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%_ptr_Uniform_float = OpTypePointer Uniform %float
+%main = OpFunction %void None %14
+%15 = OpLabel
+%18 = OpAccessChain %_ptr_Uniform_float %3 %int_0
+%20 = OpLoad %float %18
+%21 = OpCompositeConstruct %v4float %20 %20 %20 %20
+OpStore %sk_FragColor %21
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Matrices.asm.frag b/tests/sksl/shared/golden/Matrices.asm.frag
new file mode 100644
index 0000000..642860c
--- /dev/null
+++ b/tests/sksl/shared/golden/Matrices.asm.frag
@@ -0,0 +1,2 @@
+### Compilation failed:
+
diff --git a/tests/sksl/shared/golden/MatrixFolding.asm.frag b/tests/sksl/shared/golden/MatrixFolding.asm.frag
new file mode 100644
index 0000000..8335dcd
--- /dev/null
+++ b/tests/sksl/shared/golden/MatrixFolding.asm.frag
@@ -0,0 +1,71 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_n2 = OpConstant %float -2
+%float_3 = OpConstant %float 3
+%float_n4 = OpConstant %float -4
+%float_5 = OpConstant %float 5
+%float_n6 = OpConstant %float -6
+%float_7 = OpConstant %float 7
+%float_n8 = OpConstant %float -8
+%float_9 = OpConstant %float 9
+%float_10 = OpConstant %float 10
+%float_11 = OpConstant %float 11
+%float_12 = OpConstant %float 12
+%float_13 = OpConstant %float 13
+%float_14 = OpConstant %float 14
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_1
+%19 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %19 %float_n2
+%21 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %21 %float_3
+%23 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %23 %float_n4
+%25 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %25 %float_5
+%27 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %27 %float_n6
+%29 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %29 %float_7
+%31 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %31 %float_n8
+%33 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %33 %float_9
+%35 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %35 %float_10
+%37 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %37 %float_11
+%39 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %39 %float_12
+%41 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %41 %float_13
+%43 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %43 %float_14
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/MultipleAssignments.asm.frag b/tests/sksl/shared/golden/MultipleAssignments.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/MultipleAssignments.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/NegatedVectorLiteral.asm.frag b/tests/sksl/shared/golden/NegatedVectorLiteral.asm.frag
new file mode 100644
index 0000000..7fd8e8f
--- /dev/null
+++ b/tests/sksl/shared/golden/NegatedVectorLiteral.asm.frag
@@ -0,0 +1,49 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_2 = OpConstant %int 2
+%int_3 = OpConstant %int 3
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_1
+%18 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_1
+OpStore %18 %float_1
+%20 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_2
+OpStore %20 %float_1
+%22 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_3
+OpStore %22 %float_1
+%24 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %24 %float_1
+%25 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_1
+OpStore %25 %float_1
+%26 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_2
+OpStore %26 %float_1
+%27 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_3
+OpStore %27 %float_1
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/NoFragCoordsPos.asm.frag b/tests/sksl/shared/golden/NoFragCoordsPos.asm.frag
new file mode 100644
index 0000000..e818dd3
--- /dev/null
+++ b/tests/sksl/shared/golden/NoFragCoordsPos.asm.frag
@@ -0,0 +1,31 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %3 %pos
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %pos "pos"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %sk_PerVertex Block
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%pos = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%main = OpFunction %void None %11
+%12 = OpLabel
+%13 = OpLoad %v4float %pos
+%16 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %16 %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/NoFragCoordsPosRT.asm.frag b/tests/sksl/shared/golden/NoFragCoordsPosRT.asm.frag
new file mode 100644
index 0000000..ac71563
--- /dev/null
+++ b/tests/sksl/shared/golden/NoFragCoordsPosRT.asm.frag
@@ -0,0 +1,58 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %3 %pos
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_RTAdjust "sk_RTAdjust"
+OpName %pos "pos"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %sk_PerVertex Block
+OpDecorate %sk_RTAdjust DescriptorSet 0
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%sk_RTAdjust = OpVariable %_ptr_Uniform_v4float Uniform
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%pos = OpVariable %_ptr_Input_v4float Input
+%void = OpTypeVoid
+%13 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%v2float = OpTypeVector %float 2
+%float_0 = OpConstant %float 0
+%main = OpFunction %void None %13
+%14 = OpLabel
+%15 = OpLoad %v4float %pos
+%18 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %18 %15
+%20 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%21 = OpLoad %v4float %20
+%22 = OpVectorShuffle %v2float %21 %21 0 1
+%24 = OpLoad %v4float %sk_RTAdjust
+%25 = OpVectorShuffle %v2float %24 %24 0 2
+%26 = OpFMul %v2float %22 %25
+%27 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%28 = OpLoad %v4float %27
+%29 = OpVectorShuffle %v2float %28 %28 3 3
+%30 = OpLoad %v4float %sk_RTAdjust
+%31 = OpVectorShuffle %v2float %30 %30 1 3
+%32 = OpFMul %v2float %29 %31
+%33 = OpFAdd %v2float %26 %32
+%34 = OpCompositeExtract %float %33 0
+%35 = OpCompositeExtract %float %33 1
+%37 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%38 = OpLoad %v4float %37
+%39 = OpCompositeExtract %float %38 3
+%40 = OpCompositeConstruct %v4float %34 %35 %float_0 %39
+%41 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %41 %40
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/NormalizationGeo.asm.frag b/tests/sksl/shared/golden/NormalizationGeo.asm.frag
new file mode 100644
index 0000000..174d4e4
--- /dev/null
+++ b/tests/sksl/shared/golden/NormalizationGeo.asm.frag
@@ -0,0 +1,106 @@
+OpCapability Geometry
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Geometry %main "main" %3 %8 %sk_InvocationID
+OpExecutionMode %main InputPoints
+OpExecutionMode %main OutputLineStrip
+OpExecutionMode %main OutputVertices 2
+OpExecutionMode %main Invocations 2
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_InvocationID "sk_InvocationID"
+OpName %sk_RTAdjust "sk_RTAdjust"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %_arr_sk_PerVertex_int_1 ArrayStride 32
+OpDecorate %sk_InvocationID BuiltIn InvocationId
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_sk_PerVertex_int_1 = OpTypeArray %sk_PerVertex %int_1
+%_ptr_Input__arr_sk_PerVertex_int_1 = OpTypePointer Input %_arr_sk_PerVertex_int_1
+%8 = OpVariable %_ptr_Input__arr_sk_PerVertex_int_1 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%sk_InvocationID = OpVariable %_ptr_Input_int Input
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%sk_RTAdjust = OpVariable %_ptr_Uniform_v4float Uniform
+%void = OpTypeVoid
+%18 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%float_n0_5 = OpConstant %float -0.5
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%v2float = OpTypeVector %float 2
+%float_0_5 = OpConstant %float 0.5
+%main = OpFunction %void None %18
+%19 = OpLabel
+%21 = OpAccessChain %_ptr_Input_v4float %8 %int_0 %int_0
+%23 = OpLoad %v4float %21
+%27 = OpLoad %int %sk_InvocationID
+%26 = OpConvertSToF %float %27
+%28 = OpCompositeConstruct %v4float %float_n0_5 %float_0 %float_0 %26
+%29 = OpFAdd %v4float %23 %28
+%30 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %30 %29
+%32 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%33 = OpLoad %v4float %32
+%34 = OpVectorShuffle %v2float %33 %33 0 1
+%36 = OpLoad %v4float %sk_RTAdjust
+%37 = OpVectorShuffle %v2float %36 %36 0 2
+%38 = OpFMul %v2float %34 %37
+%39 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%40 = OpLoad %v4float %39
+%41 = OpVectorShuffle %v2float %40 %40 3 3
+%42 = OpLoad %v4float %sk_RTAdjust
+%43 = OpVectorShuffle %v2float %42 %42 1 3
+%44 = OpFMul %v2float %41 %43
+%45 = OpFAdd %v2float %38 %44
+%46 = OpCompositeExtract %float %45 0
+%47 = OpCompositeExtract %float %45 1
+%48 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%49 = OpLoad %v4float %48
+%50 = OpCompositeExtract %float %49 3
+%51 = OpCompositeConstruct %v4float %46 %47 %float_0 %50
+%52 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %52 %51
+OpEmitVertex
+%54 = OpAccessChain %_ptr_Input_v4float %8 %int_0 %int_0
+%55 = OpLoad %v4float %54
+%58 = OpLoad %int %sk_InvocationID
+%57 = OpConvertSToF %float %58
+%59 = OpCompositeConstruct %v4float %float_0_5 %float_0 %float_0 %57
+%60 = OpFAdd %v4float %55 %59
+%61 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %61 %60
+%62 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%63 = OpLoad %v4float %62
+%64 = OpVectorShuffle %v2float %63 %63 0 1
+%65 = OpLoad %v4float %sk_RTAdjust
+%66 = OpVectorShuffle %v2float %65 %65 0 2
+%67 = OpFMul %v2float %64 %66
+%68 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%69 = OpLoad %v4float %68
+%70 = OpVectorShuffle %v2float %69 %69 3 3
+%71 = OpLoad %v4float %sk_RTAdjust
+%72 = OpVectorShuffle %v2float %71 %71 1 3
+%73 = OpFMul %v2float %70 %72
+%74 = OpFAdd %v2float %67 %73
+%75 = OpCompositeExtract %float %74 0
+%76 = OpCompositeExtract %float %74 1
+%77 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%78 = OpLoad %v4float %77
+%79 = OpCompositeExtract %float %78 3
+%80 = OpCompositeConstruct %v4float %75 %76 %float_0 %79
+%81 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %81 %80
+OpEmitVertex
+OpEndPrimitive
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/NormalizationVert.asm.frag b/tests/sksl/shared/golden/NormalizationVert.asm.frag
new file mode 100644
index 0000000..4545b97
--- /dev/null
+++ b/tests/sksl/shared/golden/NormalizationVert.asm.frag
@@ -0,0 +1,56 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %3
+OpName %sk_PerVertex "sk_PerVertex"
+OpMemberName %sk_PerVertex 0 "sk_Position"
+OpMemberName %sk_PerVertex 1 "sk_PointSize"
+OpName %sk_RTAdjust "sk_RTAdjust"
+OpName %main "main"
+OpMemberDecorate %sk_PerVertex 0 BuiltIn Position
+OpMemberDecorate %sk_PerVertex 1 BuiltIn PointSize
+OpDecorate %sk_PerVertex Block
+OpDecorate %sk_RTAdjust DescriptorSet 0
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%sk_PerVertex = OpTypeStruct %v4float %float
+%_ptr_Output_sk_PerVertex = OpTypePointer Output %sk_PerVertex
+%3 = OpVariable %_ptr_Output_sk_PerVertex Output
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%sk_RTAdjust = OpVariable %_ptr_Uniform_v4float Uniform
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%v2float = OpTypeVector %float 2
+%float_0 = OpConstant %float 0
+%main = OpFunction %void None %11
+%12 = OpLabel
+%17 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %17 %13
+%19 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%20 = OpLoad %v4float %19
+%21 = OpVectorShuffle %v2float %20 %20 0 1
+%23 = OpLoad %v4float %sk_RTAdjust
+%24 = OpVectorShuffle %v2float %23 %23 0 2
+%25 = OpFMul %v2float %21 %24
+%26 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%27 = OpLoad %v4float %26
+%28 = OpVectorShuffle %v2float %27 %27 3 3
+%29 = OpLoad %v4float %sk_RTAdjust
+%30 = OpVectorShuffle %v2float %29 %29 1 3
+%31 = OpFMul %v2float %28 %30
+%32 = OpFAdd %v2float %25 %31
+%33 = OpCompositeExtract %float %32 0
+%34 = OpCompositeExtract %float %32 1
+%36 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+%37 = OpLoad %v4float %36
+%38 = OpCompositeExtract %float %37 3
+%39 = OpCompositeConstruct %v4float %33 %34 %float_0 %38
+%40 = OpAccessChain %_ptr_Output_v4float %3 %int_0
+OpStore %40 %39
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/NumberConversions.asm.frag b/tests/sksl/shared/golden/NumberConversions.asm.frag
new file mode 100644
index 0000000..c8ef98c
--- /dev/null
+++ b/tests/sksl/shared/golden/NumberConversions.asm.frag
@@ -0,0 +1,360 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %s "s"
+OpName %i "i"
+OpName %us "us"
+OpName %ui "ui"
+OpName %h "h"
+OpName %f "f"
+OpName %s2s "s2s"
+OpName %i2s "i2s"
+OpName %us2s "us2s"
+OpName %ui2s "ui2s"
+OpName %h2s "h2s"
+OpName %f2s "f2s"
+OpName %s2i "s2i"
+OpName %i2i "i2i"
+OpName %us2i "us2i"
+OpName %ui2i "ui2i"
+OpName %h2i "h2i"
+OpName %f2i "f2i"
+OpName %s2us "s2us"
+OpName %i2us "i2us"
+OpName %us2us "us2us"
+OpName %ui2us "ui2us"
+OpName %h2us "h2us"
+OpName %f2us "f2us"
+OpName %s2ui "s2ui"
+OpName %i2ui "i2ui"
+OpName %us2ui "us2ui"
+OpName %ui2ui "ui2ui"
+OpName %h2ui "h2ui"
+OpName %f2ui "f2ui"
+OpName %s2f "s2f"
+OpName %i2f "i2f"
+OpName %us2f "us2f"
+OpName %ui2f "ui2f"
+OpName %h2f "h2f"
+OpName %f2f "f2f"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %s RelaxedPrecision
+OpDecorate %us RelaxedPrecision
+OpDecorate %h RelaxedPrecision
+OpDecorate %s2s RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %i2s RelaxedPrecision
+OpDecorate %us2s RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %ui2s RelaxedPrecision
+OpDecorate %h2s RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %f2s RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+OpDecorate %54 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %s2us RelaxedPrecision
+OpDecorate %66 RelaxedPrecision
+OpDecorate %i2us RelaxedPrecision
+OpDecorate %us2us RelaxedPrecision
+OpDecorate %71 RelaxedPrecision
+OpDecorate %ui2us RelaxedPrecision
+OpDecorate %h2us RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %f2us RelaxedPrecision
+OpDecorate %82 RelaxedPrecision
+OpDecorate %87 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %98 RelaxedPrecision
+OpDecorate %104 RelaxedPrecision
+OpDecorate %109 RelaxedPrecision
+OpDecorate %116 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %126 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %133 RelaxedPrecision
+OpDecorate %136 RelaxedPrecision
+OpDecorate %139 RelaxedPrecision
+OpDecorate %142 RelaxedPrecision
+OpDecorate %145 RelaxedPrecision
+OpDecorate %166 RelaxedPrecision
+OpDecorate %169 RelaxedPrecision
+OpDecorate %172 RelaxedPrecision
+OpDecorate %178 RelaxedPrecision
+OpDecorate %180 RelaxedPrecision
+OpDecorate %181 RelaxedPrecision
+OpDecorate %182 RelaxedPrecision
+OpDecorate %183 RelaxedPrecision
+OpDecorate %184 RelaxedPrecision
+OpDecorate %187 RelaxedPrecision
+OpDecorate %190 RelaxedPrecision
+OpDecorate %193 RelaxedPrecision
+OpDecorate %196 RelaxedPrecision
+OpDecorate %199 RelaxedPrecision
+OpDecorate %202 RelaxedPrecision
+OpDecorate %215 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%int = OpTypeInt 32 1
+%_ptr_Private_int = OpTypePointer Private %int
+%s = OpVariable %_ptr_Private_int Private
+%float_1 = OpConstant %float 1
+%i = OpVariable %_ptr_Private_int Private
+%uint = OpTypeInt 32 0
+%_ptr_Private_uint = OpTypePointer Private %uint
+%us = OpVariable %_ptr_Private_uint Private
+%ui = OpVariable %_ptr_Private_uint Private
+%_ptr_Private_float = OpTypePointer Private %float
+%h = OpVariable %_ptr_Private_float Private
+%f = OpVariable %_ptr_Private_float Private
+%s2s = OpVariable %_ptr_Private_int Private
+%i2s = OpVariable %_ptr_Private_int Private
+%us2s = OpVariable %_ptr_Private_int Private
+%ui2s = OpVariable %_ptr_Private_int Private
+%h2s = OpVariable %_ptr_Private_int Private
+%f2s = OpVariable %_ptr_Private_int Private
+%s2i = OpVariable %_ptr_Private_int Private
+%i2i = OpVariable %_ptr_Private_int Private
+%us2i = OpVariable %_ptr_Private_int Private
+%ui2i = OpVariable %_ptr_Private_int Private
+%h2i = OpVariable %_ptr_Private_int Private
+%f2i = OpVariable %_ptr_Private_int Private
+%s2us = OpVariable %_ptr_Private_uint Private
+%i2us = OpVariable %_ptr_Private_uint Private
+%us2us = OpVariable %_ptr_Private_uint Private
+%ui2us = OpVariable %_ptr_Private_uint Private
+%h2us = OpVariable %_ptr_Private_uint Private
+%f2us = OpVariable %_ptr_Private_uint Private
+%s2ui = OpVariable %_ptr_Private_uint Private
+%i2ui = OpVariable %_ptr_Private_uint Private
+%us2ui = OpVariable %_ptr_Private_uint Private
+%ui2ui = OpVariable %_ptr_Private_uint Private
+%h2ui = OpVariable %_ptr_Private_uint Private
+%f2ui = OpVariable %_ptr_Private_uint Private
+%s2f = OpVariable %_ptr_Private_float Private
+%i2f = OpVariable %_ptr_Private_float Private
+%us2f = OpVariable %_ptr_Private_float Private
+%ui2f = OpVariable %_ptr_Private_float Private
+%h2f = OpVariable %_ptr_Private_float Private
+%f2f = OpVariable %_ptr_Private_float Private
+%void = OpTypeVoid
+%113 = OpTypeFunction %void
+%_ptr_Output_float = OpTypePointer Output %float
+%int_0 = OpConstant %int 0
+%main = OpFunction %void None %113
+%114 = OpLabel
+%14 = OpExtInst %float %1 Sqrt %float_1
+%13 = OpConvertFToS %int %14
+OpStore %s %13
+%18 = OpExtInst %float %1 Sqrt %float_1
+%17 = OpConvertFToS %int %18
+OpStore %i %17
+%23 = OpExtInst %float %1 Sqrt %float_1
+%22 = OpConvertFToU %uint %23
+OpStore %us %22
+%26 = OpExtInst %float %1 Sqrt %float_1
+%25 = OpConvertFToU %uint %26
+OpStore %ui %25
+%29 = OpExtInst %float %1 Sqrt %float_1
+OpStore %h %29
+%31 = OpExtInst %float %1 Sqrt %float_1
+OpStore %f %31
+%33 = OpLoad %int %s
+OpStore %s2s %33
+%35 = OpLoad %int %i
+OpStore %i2s %35
+%38 = OpLoad %uint %us
+%37 = OpBitcast %int %38
+OpStore %us2s %37
+%41 = OpLoad %uint %ui
+%40 = OpBitcast %int %41
+OpStore %ui2s %40
+%44 = OpLoad %float %h
+%43 = OpConvertFToS %int %44
+OpStore %h2s %43
+%47 = OpLoad %float %f
+%46 = OpConvertFToS %int %47
+OpStore %f2s %46
+%49 = OpLoad %int %s
+OpStore %s2i %49
+%51 = OpLoad %int %i
+OpStore %i2i %51
+%54 = OpLoad %uint %us
+%53 = OpBitcast %int %54
+OpStore %us2i %53
+%57 = OpLoad %uint %ui
+%56 = OpBitcast %int %57
+OpStore %ui2i %56
+%60 = OpLoad %float %h
+%59 = OpConvertFToS %int %60
+OpStore %h2i %59
+%63 = OpLoad %float %f
+%62 = OpConvertFToS %int %63
+OpStore %f2i %62
+%66 = OpLoad %int %s
+%65 = OpBitcast %uint %66
+OpStore %s2us %65
+%69 = OpLoad %int %i
+%68 = OpBitcast %uint %69
+OpStore %i2us %68
+%71 = OpLoad %uint %us
+OpStore %us2us %71
+%73 = OpLoad %uint %ui
+OpStore %ui2us %73
+%76 = OpLoad %float %h
+%75 = OpConvertFToU %uint %76
+OpStore %h2us %75
+%79 = OpLoad %float %f
+%78 = OpConvertFToU %uint %79
+OpStore %f2us %78
+%82 = OpLoad %int %s
+%81 = OpBitcast %uint %82
+OpStore %s2ui %81
+%85 = OpLoad %int %i
+%84 = OpBitcast %uint %85
+OpStore %i2ui %84
+%87 = OpLoad %uint %us
+OpStore %us2ui %87
+%89 = OpLoad %uint %ui
+OpStore %ui2ui %89
+%92 = OpLoad %float %h
+%91 = OpConvertFToU %uint %92
+OpStore %h2ui %91
+%95 = OpLoad %float %f
+%94 = OpConvertFToU %uint %95
+OpStore %f2ui %94
+%98 = OpLoad %int %s
+%97 = OpConvertSToF %float %98
+OpStore %s2f %97
+%101 = OpLoad %int %i
+%100 = OpConvertSToF %float %101
+OpStore %i2f %100
+%104 = OpLoad %uint %us
+%103 = OpConvertUToF %float %104
+OpStore %us2f %103
+%107 = OpLoad %uint %ui
+%106 = OpConvertUToF %float %107
+OpStore %ui2f %106
+%109 = OpLoad %float %h
+OpStore %h2f %109
+%111 = OpLoad %float %f
+OpStore %f2f %111
+%116 = OpLoad %int %s
+%117 = OpLoad %int %i
+%118 = OpIAdd %int %116 %117
+%120 = OpLoad %uint %us
+%119 = OpBitcast %int %120
+%121 = OpIAdd %int %118 %119
+%115 = OpConvertSToF %float %121
+%123 = OpLoad %uint %ui
+%122 = OpConvertUToF %float %123
+%124 = OpFAdd %float %115 %122
+%125 = OpLoad %float %h
+%126 = OpFAdd %float %124 %125
+%127 = OpLoad %float %f
+%128 = OpFAdd %float %126 %127
+%130 = OpLoad %int %s2s
+%129 = OpConvertSToF %float %130
+%131 = OpFAdd %float %128 %129
+%133 = OpLoad %int %i2s
+%132 = OpConvertSToF %float %133
+%134 = OpFAdd %float %131 %132
+%136 = OpLoad %int %us2s
+%135 = OpConvertSToF %float %136
+%137 = OpFAdd %float %134 %135
+%139 = OpLoad %int %ui2s
+%138 = OpConvertSToF %float %139
+%140 = OpFAdd %float %137 %138
+%142 = OpLoad %int %h2s
+%141 = OpConvertSToF %float %142
+%143 = OpFAdd %float %140 %141
+%145 = OpLoad %int %f2s
+%144 = OpConvertSToF %float %145
+%146 = OpFAdd %float %143 %144
+%148 = OpLoad %int %s2i
+%147 = OpConvertSToF %float %148
+%149 = OpFAdd %float %146 %147
+%151 = OpLoad %int %i2i
+%150 = OpConvertSToF %float %151
+%152 = OpFAdd %float %149 %150
+%154 = OpLoad %int %us2i
+%153 = OpConvertSToF %float %154
+%155 = OpFAdd %float %152 %153
+%157 = OpLoad %int %ui2i
+%156 = OpConvertSToF %float %157
+%158 = OpFAdd %float %155 %156
+%160 = OpLoad %int %h2i
+%159 = OpConvertSToF %float %160
+%161 = OpFAdd %float %158 %159
+%163 = OpLoad %int %f2i
+%162 = OpConvertSToF %float %163
+%164 = OpFAdd %float %161 %162
+%166 = OpLoad %uint %s2us
+%165 = OpConvertUToF %float %166
+%167 = OpFAdd %float %164 %165
+%169 = OpLoad %uint %i2us
+%168 = OpConvertUToF %float %169
+%170 = OpFAdd %float %167 %168
+%172 = OpLoad %uint %us2us
+%171 = OpConvertUToF %float %172
+%173 = OpFAdd %float %170 %171
+%174 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %174 %173
+%177 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+%178 = OpLoad %float %177
+%180 = OpLoad %uint %ui2us
+%181 = OpLoad %uint %h2us
+%182 = OpIAdd %uint %180 %181
+%183 = OpLoad %uint %f2us
+%184 = OpIAdd %uint %182 %183
+%179 = OpConvertUToF %float %184
+%186 = OpLoad %uint %s2ui
+%185 = OpConvertUToF %float %186
+%187 = OpFAdd %float %179 %185
+%189 = OpLoad %uint %i2ui
+%188 = OpConvertUToF %float %189
+%190 = OpFAdd %float %187 %188
+%192 = OpLoad %uint %us2ui
+%191 = OpConvertUToF %float %192
+%193 = OpFAdd %float %190 %191
+%195 = OpLoad %uint %ui2ui
+%194 = OpConvertUToF %float %195
+%196 = OpFAdd %float %193 %194
+%198 = OpLoad %uint %h2ui
+%197 = OpConvertUToF %float %198
+%199 = OpFAdd %float %196 %197
+%201 = OpLoad %uint %f2ui
+%200 = OpConvertUToF %float %201
+%202 = OpFAdd %float %199 %200
+%203 = OpLoad %float %s2f
+%204 = OpFAdd %float %202 %203
+%205 = OpLoad %float %i2f
+%206 = OpFAdd %float %204 %205
+%207 = OpLoad %float %us2f
+%208 = OpFAdd %float %206 %207
+%209 = OpLoad %float %ui2f
+%210 = OpFAdd %float %208 %209
+%211 = OpLoad %float %h2f
+%212 = OpFAdd %float %210 %211
+%213 = OpLoad %float %f2f
+%214 = OpFAdd %float %212 %213
+%215 = OpFAdd %float %178 %214
+OpStore %177 %215
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Offset.asm.frag b/tests/sksl/shared/golden/Offset.asm.frag
new file mode 100644
index 0000000..ab18de6
--- /dev/null
+++ b/tests/sksl/shared/golden/Offset.asm.frag
@@ -0,0 +1,48 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %Test "Test"
+OpMemberName %Test 0 "x"
+OpMemberName %Test 1 "y"
+OpMemberName %Test 2 "z"
+OpName %t "t"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpMemberDecorate %Test 0 Offset 0
+OpMemberDecorate %Test 1 Offset 4
+OpMemberDecorate %Test 2 Offset 8
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%Test = OpTypeStruct %int %int %int
+%_ptr_Function_Test = OpTypePointer Function %Test
+%int_0 = OpConstant %int 0
+%_ptr_Function_int = OpTypePointer Function %int
+%_ptr_Output_float = OpTypePointer Output %float
+%main = OpFunction %void None %11
+%12 = OpLabel
+%t = OpVariable %_ptr_Function_Test Function
+%18 = OpAccessChain %_ptr_Function_int %t %int_0
+OpStore %18 %int_0
+%21 = OpAccessChain %_ptr_Function_int %t %int_0
+%22 = OpLoad %int %21
+%20 = OpConvertSToF %float %22
+%23 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %23 %20
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Operators.asm.frag b/tests/sksl/shared/golden/Operators.asm.frag
new file mode 100644
index 0000000..125cf7e
--- /dev/null
+++ b/tests/sksl/shared/golden/Operators.asm.frag
@@ -0,0 +1,6 @@
+### Compilation failed:
+
+error: 1: unsupported token
+error: 1: unsupported token
+error: 1: unsupported token
+3 errors
diff --git a/tests/sksl/shared/golden/Ossfuzz26167.asm.frag b/tests/sksl/shared/golden/Ossfuzz26167.asm.frag
new file mode 100644
index 0000000..b4a67d5
--- /dev/null
+++ b/tests/sksl/shared/golden/Ossfuzz26167.asm.frag
@@ -0,0 +1,18 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Ossfuzz27614.asm.frag b/tests/sksl/shared/golden/Ossfuzz27614.asm.frag
new file mode 100644
index 0000000..b4a67d5
--- /dev/null
+++ b/tests/sksl/shared/golden/Ossfuzz27614.asm.frag
@@ -0,0 +1,18 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/OutParams.asm.frag b/tests/sksl/shared/golden/OutParams.asm.frag
new file mode 100644
index 0000000..2a3b533
--- /dev/null
+++ b/tests/sksl/shared/golden/OutParams.asm.frag
@@ -0,0 +1,216 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %h3 "h3"
+OpName %h4 "h4"
+OpName %h3x3 "h3x3"
+OpName %h4x4 "h4x4"
+OpName %i4 "i4"
+OpName %f3 "f3"
+OpName %f2x2 "f2x2"
+OpName %b4 "b4"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %26 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+OpDecorate %31 RelaxedPrecision
+OpDecorate %33 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %42 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %49 RelaxedPrecision
+OpDecorate %50 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %64 RelaxedPrecision
+OpDecorate %65 RelaxedPrecision
+OpDecorate %63 RelaxedPrecision
+OpDecorate %63 RelaxedPrecision
+OpDecorate %69 RelaxedPrecision
+OpDecorate %72 RelaxedPrecision
+OpDecorate %75 RelaxedPrecision
+OpDecorate %137 RelaxedPrecision
+OpDecorate %142 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%v3float = OpTypeVector %float 3
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+%float_3 = OpConstant %float 3
+%16 = OpConstantComposite %v3float %float_3 %float_3 %float_3
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_4 = OpConstant %float 4
+%20 = OpConstantComposite %v4float %float_4 %float_4 %float_4 %float_4
+%float_2 = OpConstant %float 2
+%v2float = OpTypeVector %float 2
+%22 = OpConstantComposite %v2float %float_2 %float_2
+%27 = OpConstantComposite %v4float %float_4 %float_4 %float_4 %float_4
+%float_1 = OpConstant %float 1
+%mat3v3float = OpTypeMatrix %v3float 3
+%_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
+%float_0 = OpConstant %float 0
+%mat4v4float = OpTypeMatrix %v4float 4
+%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
+%52 = OpConstantComposite %v3float %float_3 %float_3 %float_3
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%int_3 = OpConstant %int 3
+%_ptr_Function_float = OpTypePointer Function %float
+%mat2v2float = OpTypeMatrix %v2float 2
+%_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float
+%int_0 = OpConstant %int 0
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%v4int = OpTypeVector %int 4
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%int_4 = OpConstant %int 4
+%81 = OpConstantComposite %v4int %int_4 %int_4 %int_4 %int_4
+%v3int = OpTypeVector %int 3
+%83 = OpConstantComposite %v3int %int_3 %int_3 %int_3
+%float_3_0 = OpConstant %float 3
+%92 = OpConstantComposite %v3float %float_3_0 %float_3_0 %float_3_0
+%float_2_0 = OpConstant %float 2
+%94 = OpConstantComposite %v2float %float_2_0 %float_2_0
+%float_1_0 = OpConstant %float 1
+%float_4_0 = OpConstant %float 4
+%v4bool = OpTypeVector %bool 4
+%_ptr_Function_v4bool = OpTypePointer Function %v4bool
+%false = OpConstantFalse %bool
+%132 = OpConstantComposite %v4bool %false %false %false %false
+%v2bool = OpTypeVector %bool 2
+%134 = OpConstantComposite %v2bool %false %false
+%float_0_0 = OpConstant %float 0
+%true = OpConstantTrue %bool
+%main = OpFunction %void None %11
+%12 = OpLabel
+%h3 = OpVariable %_ptr_Function_v3float Function
+%h4 = OpVariable %_ptr_Function_v4float Function
+%h3x3 = OpVariable %_ptr_Function_mat3v3float Function
+%h4x4 = OpVariable %_ptr_Function_mat4v4float Function
+%60 = OpVariable %_ptr_Function_mat2v2float Function
+%i4 = OpVariable %_ptr_Function_v4int Function
+%f3 = OpVariable %_ptr_Function_v3float Function
+%f2x2 = OpVariable %_ptr_Function_mat2v2float Function
+%111 = OpVariable %_ptr_Function_mat3v3float Function
+%119 = OpVariable %_ptr_Function_mat4v4float Function
+%b4 = OpVariable %_ptr_Function_v4bool Function
+OpStore %h3 %16
+OpStore %h4 %20
+%25 = OpLoad %v3float %h3
+%26 = OpVectorShuffle %v3float %25 %22 3 1 4
+OpStore %h3 %26
+%28 = OpLoad %v4float %h4
+%29 = OpVectorShuffle %v4float %28 %27 6 7 4 5
+OpStore %h4 %29
+%31 = OpLoad %v3float %h3
+%32 = OpCompositeExtract %float %31 0
+%33 = OpLoad %v4float %h4
+%34 = OpCompositeExtract %float %33 0
+%35 = OpCompositeConstruct %v4float %float_1 %float_2 %32 %34
+OpStore %sk_FragColor %35
+%41 = OpCompositeConstruct %v3float %float_3 %float_0 %float_0
+%42 = OpCompositeConstruct %v3float %float_0 %float_3 %float_0
+%43 = OpCompositeConstruct %v3float %float_0 %float_0 %float_3
+%39 = OpCompositeConstruct %mat3v3float %41 %42 %43
+OpStore %h3x3 %39
+%48 = OpCompositeConstruct %v4float %float_4 %float_0 %float_0 %float_0
+%49 = OpCompositeConstruct %v4float %float_0 %float_4 %float_0 %float_0
+%50 = OpCompositeConstruct %v4float %float_0 %float_0 %float_4 %float_0
+%51 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_4
+%47 = OpCompositeConstruct %mat4v4float %48 %49 %50 %51
+OpStore %h4x4 %47
+%55 = OpAccessChain %_ptr_Function_v3float %h3x3 %int_1
+OpStore %55 %52
+%57 = OpAccessChain %_ptr_Function_v4float %h4x4 %int_3
+%58 = OpAccessChain %_ptr_Function_float %57 %int_3
+OpStore %58 %float_1
+%64 = OpCompositeConstruct %v2float %float_2 %float_0
+%65 = OpCompositeConstruct %v2float %float_0 %float_2
+%63 = OpCompositeConstruct %mat2v2float %64 %65
+OpStore %60 %63
+%67 = OpAccessChain %_ptr_Function_v2float %60 %int_0
+%69 = OpLoad %v2float %67
+%70 = OpVectorExtractDynamic %float %69 %int_0
+%71 = OpAccessChain %_ptr_Function_v3float %h3x3 %int_0
+%72 = OpLoad %v3float %71
+%73 = OpVectorExtractDynamic %float %72 %int_0
+%74 = OpAccessChain %_ptr_Function_v4float %h4x4 %int_0
+%75 = OpLoad %v4float %74
+%76 = OpVectorExtractDynamic %float %75 %int_0
+%77 = OpCompositeConstruct %v4float %70 %73 %76 %float_1
+OpStore %sk_FragColor %77
+OpStore %i4 %81
+%85 = OpLoad %v4int %i4
+%86 = OpVectorShuffle %v4int %85 %83 4 5 6 3
+OpStore %i4 %86
+%88 = OpLoad %v4int %i4
+%89 = OpCompositeExtract %int %88 0
+%87 = OpConvertSToF %float %89
+%90 = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %87
+OpStore %sk_FragColor %90
+OpStore %f3 %92
+%96 = OpLoad %v3float %f3
+%97 = OpVectorShuffle %v3float %96 %94 3 4 2
+OpStore %f3 %97
+%99 = OpLoad %v3float %f3
+%100 = OpCompositeExtract %float %99 0
+%102 = OpCompositeConstruct %v4float %float_1_0 %float_2_0 %100 %float_4_0
+OpStore %sk_FragColor %102
+%105 = OpCompositeConstruct %v2float %float_2_0 %float_0
+%106 = OpCompositeConstruct %v2float %float_0 %float_2_0
+%104 = OpCompositeConstruct %mat2v2float %105 %106
+OpStore %f2x2 %104
+%107 = OpAccessChain %_ptr_Function_float %f2x2 %int_0 %int_0
+OpStore %107 %float_1_0
+%108 = OpAccessChain %_ptr_Function_v2float %f2x2 %int_0
+%109 = OpLoad %v2float %108
+%110 = OpVectorExtractDynamic %float %109 %int_0
+%113 = OpCompositeConstruct %v3float %float_3_0 %float_0 %float_0
+%114 = OpCompositeConstruct %v3float %float_0 %float_3_0 %float_0
+%115 = OpCompositeConstruct %v3float %float_0 %float_0 %float_3_0
+%112 = OpCompositeConstruct %mat3v3float %113 %114 %115
+OpStore %111 %112
+%116 = OpAccessChain %_ptr_Function_v3float %111 %int_0
+%117 = OpLoad %v3float %116
+%118 = OpVectorExtractDynamic %float %117 %int_0
+%121 = OpCompositeConstruct %v4float %float_4_0 %float_0 %float_0 %float_0
+%122 = OpCompositeConstruct %v4float %float_0 %float_4_0 %float_0 %float_0
+%123 = OpCompositeConstruct %v4float %float_0 %float_0 %float_4_0 %float_0
+%124 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_4_0
+%120 = OpCompositeConstruct %mat4v4float %121 %122 %123 %124
+OpStore %119 %120
+%125 = OpAccessChain %_ptr_Function_v4float %119 %int_0
+%126 = OpLoad %v4float %125
+%127 = OpVectorExtractDynamic %float %126 %int_0
+%128 = OpCompositeConstruct %v4float %110 %118 %127 %float_1
+OpStore %sk_FragColor %128
+OpStore %b4 %132
+%136 = OpLoad %v4bool %b4
+%137 = OpVectorShuffle %v4bool %136 %134 4 1 2 5
+OpStore %b4 %137
+%138 = OpSelect %float %false %float_1 %float_0_0
+%141 = OpSelect %float %true %float_1 %float_0_0
+%142 = OpLoad %v4bool %b4
+%143 = OpCompositeExtract %bool %142 0
+%144 = OpSelect %float %143 %float_1 %float_0_0
+%145 = OpCompositeConstruct %v4float %float_1 %138 %141 %144
+OpStore %sk_FragColor %145
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/OutParamsTricky.asm.frag b/tests/sksl/shared/golden/OutParamsTricky.asm.frag
new file mode 100644
index 0000000..ff51256
--- /dev/null
+++ b/tests/sksl/shared/golden/OutParamsTricky.asm.frag
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 12: unable to retrieve lvalue from swizzle
+1 error
diff --git a/tests/sksl/shared/golden/RectangleTexture.asm.frag b/tests/sksl/shared/golden/RectangleTexture.asm.frag
new file mode 100644
index 0000000..485804b
--- /dev/null
+++ b/tests/sksl/shared/golden/RectangleTexture.asm.frag
@@ -0,0 +1,55 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %test2D "test2D"
+OpName %test2DRect "test2DRect"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %test2D RelaxedPrecision
+OpDecorate %test2D Binding 0
+OpDecorate %test2DRect RelaxedPrecision
+OpDecorate %test2DRect Binding 1
+OpDecorate %19 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+OpDecorate %27 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%13 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%12 = OpTypeSampledImage %13
+%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
+%test2D = OpVariable %_ptr_UniformConstant_12 UniformConstant
+%test2DRect = OpVariable %_ptr_UniformConstant_12 UniformConstant
+%void = OpTypeVoid
+%16 = OpTypeFunction %void
+%float_0_5 = OpConstant %float 0.5
+%v2float = OpTypeVector %float 2
+%20 = OpConstantComposite %v2float %float_0_5 %float_0_5
+%25 = OpConstantComposite %v2float %float_0_5 %float_0_5
+%v3float = OpTypeVector %float 3
+%28 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+%main = OpFunction %void None %16
+%17 = OpLabel
+%19 = OpLoad %12 %test2D
+%18 = OpImageSampleImplicitLod %v4float %19 %20
+OpStore %sk_FragColor %18
+%24 = OpLoad %12 %test2DRect
+%23 = OpImageSampleImplicitLod %v4float %24 %25
+OpStore %sk_FragColor %23
+%27 = OpLoad %12 %test2DRect
+%26 = OpImageSampleProjImplicitLod %v4float %27 %28
+OpStore %sk_FragColor %26
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ResizeMatrix.asm.frag b/tests/sksl/shared/golden/ResizeMatrix.asm.frag
new file mode 100644
index 0000000..642860c
--- /dev/null
+++ b/tests/sksl/shared/golden/ResizeMatrix.asm.frag
@@ -0,0 +1,2 @@
+### Compilation failed:
+
diff --git a/tests/sksl/shared/golden/SampleMask.asm.frag b/tests/sksl/shared/golden/SampleMask.asm.frag
new file mode 100644
index 0000000..8aa178d
--- /dev/null
+++ b/tests/sksl/shared/golden/SampleMask.asm.frag
@@ -0,0 +1,33 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_SampleMask %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_SampleMask "sk_SampleMask"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %_arr_int_int_1 ArrayStride 16
+OpDecorate %sk_SampleMask BuiltIn SampleMask
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%int = OpTypeInt 32 1
+%int_1 = OpConstant %int 1
+%_arr_int_int_1 = OpTypeArray %int %int_1
+%_ptr_Output__arr_int_int_1 = OpTypePointer Output %_arr_int_int_1
+%sk_SampleMask = OpVariable %_ptr_Output__arr_int_int_1 Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%12 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Output_int = OpTypePointer Output %int
+%int_8 = OpConstant %int 8
+%main = OpFunction %void None %12
+%13 = OpLabel
+%15 = OpAccessChain %_ptr_Output_int %sk_SampleMask %int_0
+%17 = OpLoad %int %15
+%19 = OpBitwiseOr %int %17 %int_8
+OpStore %15 %19
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ScopedSymbol.asm.frag b/tests/sksl/shared/golden/ScopedSymbol.asm.frag
new file mode 100644
index 0000000..b4a67d5
--- /dev/null
+++ b/tests/sksl/shared/golden/ScopedSymbol.asm.frag
@@ -0,0 +1,18 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%7 = OpTypeFunction %void
+%main = OpFunction %void None %7
+%8 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/ShortCircuitBoolFolding.asm.frag b/tests/sksl/shared/golden/ShortCircuitBoolFolding.asm.frag
new file mode 100644
index 0000000..e7dd183
--- /dev/null
+++ b/tests/sksl/shared/golden/ShortCircuitBoolFolding.asm.frag
@@ -0,0 +1,146 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragCoord %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragCoord "sk_FragCoord"
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %expr1 "expr1"
+OpName %expr2 "expr2"
+OpDecorate %sk_FragCoord BuiltIn FragCoord
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %25 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %47 RelaxedPrecision
+OpDecorate %55 RelaxedPrecision
+OpDecorate %61 RelaxedPrecision
+OpDecorate %66 RelaxedPrecision
+OpDecorate %71 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%sk_FragCoord = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%13 = OpTypeFunction %void
+%_ptr_Function_bool = OpTypePointer Function %bool
+%float_0 = OpConstant %float 0
+%float_1 = OpConstant %float 1
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_3 = OpConstant %float 3
+%float_4 = OpConstant %float 4
+%float_5 = OpConstant %float 5
+%float_6 = OpConstant %float 6
+%main = OpFunction %void None %13
+%14 = OpLabel
+%expr1 = OpVariable %_ptr_Function_bool Function
+%expr2 = OpVariable %_ptr_Function_bool Function
+%17 = OpLoad %v4float %sk_FragCoord
+%18 = OpCompositeExtract %float %17 0
+%20 = OpFOrdGreaterThan %bool %18 %float_0
+OpStore %expr1 %20
+%22 = OpLoad %v4float %sk_FragCoord
+%23 = OpCompositeExtract %float %22 1
+%24 = OpFOrdGreaterThan %bool %23 %float_0
+OpStore %expr2 %24
+%25 = OpLoad %bool %expr1
+OpSelectionMerge %28 None
+OpBranchConditional %25 %26 %27
+%26 = OpLabel
+%30 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %30 %float_1
+OpBranch %28
+%27 = OpLabel
+%35 = OpLoad %bool %expr1
+%34 = OpLogicalNot %bool %35
+OpSelectionMerge %38 None
+OpBranchConditional %34 %36 %37
+%36 = OpLabel
+%40 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %40 %float_3
+OpBranch %38
+%37 = OpLabel
+%41 = OpLoad %bool %expr2
+OpSelectionMerge %44 None
+OpBranchConditional %41 %42 %43
+%42 = OpLabel
+%46 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %46 %float_4
+OpBranch %44
+%43 = OpLabel
+%47 = OpLoad %bool %expr2
+OpSelectionMerge %50 None
+OpBranchConditional %47 %48 %49
+%48 = OpLabel
+%52 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %52 %float_5
+OpBranch %50
+%49 = OpLabel
+%54 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %54 %float_6
+OpBranch %50
+%50 = OpLabel
+OpBranch %44
+%44 = OpLabel
+OpBranch %38
+%38 = OpLabel
+OpBranch %28
+%28 = OpLabel
+%55 = OpLoad %bool %expr1
+OpSelectionMerge %58 None
+OpBranchConditional %55 %56 %57
+%56 = OpLabel
+%59 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %59 %float_1
+OpBranch %58
+%57 = OpLabel
+%61 = OpLoad %bool %expr1
+%60 = OpLogicalNot %bool %61
+OpSelectionMerge %64 None
+OpBranchConditional %60 %62 %63
+%62 = OpLabel
+%65 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %65 %float_3
+OpBranch %64
+%63 = OpLabel
+%66 = OpLoad %bool %expr2
+OpSelectionMerge %69 None
+OpBranchConditional %66 %67 %68
+%67 = OpLabel
+%70 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %70 %float_4
+OpBranch %69
+%68 = OpLabel
+%71 = OpLoad %bool %expr2
+OpSelectionMerge %74 None
+OpBranchConditional %71 %72 %73
+%72 = OpLabel
+%75 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %75 %float_5
+OpBranch %74
+%73 = OpLabel
+%76 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %76 %float_6
+OpBranch %74
+%74 = OpLabel
+OpBranch %69
+%69 = OpLabel
+OpBranch %64
+%64 = OpLabel
+OpBranch %58
+%58 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StackingVectorCasts.asm.frag b/tests/sksl/shared/golden/StackingVectorCasts.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/StackingVectorCasts.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticIf.asm.frag b/tests/sksl/shared/golden/StaticIf.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticIf.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitch.asm.frag b/tests/sksl/shared/golden/StaticSwitch.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitch.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithBreak.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithBreak.asm.frag
new file mode 100644
index 0000000..c8352c6
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithBreak.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_0 = OpConstant %float 0
+%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithBreakInsideBlock.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithBreakInsideBlock.asm.frag
new file mode 100644
index 0000000..c8352c6
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithBreakInsideBlock.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_0 = OpConstant %float 0
+%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithConditionalBreak.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithConditionalBreak.asm.frag
new file mode 100644
index 0000000..19c5fe7
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithConditionalBreak.asm.frag
@@ -0,0 +1,53 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_0 = OpConstant %float 0
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_float Function
+OpStore %x %float_0
+OpSelectionMerge %18 None
+OpSwitch %int_0 %18 0 %19 1 %20
+%19 = OpLabel
+OpStore %x %float_0
+%21 = OpExtInst %float %1 Sqrt %float_1
+%23 = OpFOrdLessThan %bool %float_0 %21
+OpSelectionMerge %25 None
+OpBranchConditional %23 %24 %25
+%24 = OpLabel
+OpBranch %18
+%25 = OpLabel
+OpBranch %20
+%20 = OpLabel
+OpStore %x %float_1
+OpBranch %18
+%18 = OpLabel
+%26 = OpLoad %float %x
+%27 = OpCompositeConstruct %v4float %26 %26 %26 %26
+OpStore %sk_FragColor %27
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithConditionalBreakInsideBlock.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithConditionalBreakInsideBlock.asm.frag
new file mode 100644
index 0000000..5f95f47
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithConditionalBreakInsideBlock.asm.frag
@@ -0,0 +1,46 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_0 = OpConstant %float 0
+%float_1 = OpConstant %float 1
+%24 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpSelectionMerge %15 None
+OpSwitch %int_0 %15 0 %16 1 %17
+%16 = OpLabel
+%19 = OpExtInst %float %1 Sqrt %float_1
+%21 = OpFOrdLessThan %bool %float_0 %19
+OpSelectionMerge %23 None
+OpBranchConditional %21 %22 %23
+%22 = OpLabel
+OpStore %sk_FragColor %24
+OpBranch %15
+%23 = OpLabel
+OpBranch %17
+%17 = OpLabel
+OpBranch %15
+%15 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithFallthroughA.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithFallthroughA.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithFallthroughA.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithFallthroughB.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithFallthroughB.asm.frag
new file mode 100644
index 0000000..ba548be
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithFallthroughB.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithStaticConditionalBreak.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithStaticConditionalBreak.asm.frag
new file mode 100644
index 0000000..c8352c6
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithStaticConditionalBreak.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_0 = OpConstant %float 0
+%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StaticSwitchWithStaticConditionalBreakInsideBlock.asm.frag b/tests/sksl/shared/golden/StaticSwitchWithStaticConditionalBreakInsideBlock.asm.frag
new file mode 100644
index 0000000..c8352c6
--- /dev/null
+++ b/tests/sksl/shared/golden/StaticSwitchWithStaticConditionalBreakInsideBlock.asm.frag
@@ -0,0 +1,29 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_0 = OpConstant %float 0
+%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/StructMaxDepth.asm.frag b/tests/sksl/shared/golden/StructMaxDepth.asm.frag
new file mode 100644
index 0000000..2df0733
--- /dev/null
+++ b/tests/sksl/shared/golden/StructMaxDepth.asm.frag
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: program does not contain a main() function
+1 error
diff --git a/tests/sksl/shared/golden/Structs.asm.frag b/tests/sksl/shared/golden/Structs.asm.frag
new file mode 100644
index 0000000..802921c
--- /dev/null
+++ b/tests/sksl/shared/golden/Structs.asm.frag
@@ -0,0 +1,71 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %A "A"
+OpMemberName %A 0 "x"
+OpMemberName %A 1 "y"
+OpName %a1 "a1"
+OpName %B "B"
+OpMemberName %B 0 "x"
+OpMemberName %B 1 "y"
+OpMemberName %B 2 "z"
+OpName %b1 "b1"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpMemberDecorate %A 0 Offset 0
+OpMemberDecorate %A 1 Offset 4
+OpDecorate %a1 RelaxedPrecision
+OpDecorate %_arr_float_int_2 ArrayStride 16
+OpMemberDecorate %B 0 Offset 0
+OpMemberDecorate %B 1 Offset 16
+OpMemberDecorate %B 2 Binding 1
+OpMemberDecorate %B 2 Offset 48
+OpMemberDecorate %B 2 RelaxedPrecision
+OpDecorate %b1 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%int = OpTypeInt 32 1
+%A = OpTypeStruct %int %int
+%_ptr_Private_A = OpTypePointer Private %A
+%a1 = OpVariable %_ptr_Private_A Private
+%int_2 = OpConstant %int 2
+%_arr_float_int_2 = OpTypeArray %float %int_2
+%B = OpTypeStruct %float %_arr_float_int_2 %A
+%_ptr_Private_B = OpTypePointer Private %B
+%b1 = OpVariable %_ptr_Private_B Private
+%void = OpTypeVoid
+%20 = OpTypeFunction %void
+%int_0 = OpConstant %int 0
+%_ptr_Private_int = OpTypePointer Private %int
+%float_0 = OpConstant %float 0
+%_ptr_Private_float = OpTypePointer Private %float
+%_ptr_Output_float = OpTypePointer Output %float
+%main = OpFunction %void None %20
+%21 = OpLabel
+%23 = OpAccessChain %_ptr_Private_int %a1 %int_0
+OpStore %23 %int_0
+%26 = OpAccessChain %_ptr_Private_float %b1 %int_0
+OpStore %26 %float_0
+%29 = OpAccessChain %_ptr_Private_int %a1 %int_0
+%30 = OpLoad %int %29
+%28 = OpConvertSToF %float %30
+%31 = OpAccessChain %_ptr_Private_float %b1 %int_0
+%32 = OpLoad %float %31
+%33 = OpFAdd %float %28 %32
+%34 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %34 %33
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Switch.asm.frag b/tests/sksl/shared/golden/Switch.asm.frag
new file mode 100644
index 0000000..ec3e1e6
--- /dev/null
+++ b/tests/sksl/shared/golden/Switch.asm.frag
@@ -0,0 +1,50 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_1 = OpConstant %float 1
+%int = OpTypeInt 32 1
+%float_0 = OpConstant %float 0
+%float_2 = OpConstant %float 2
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_float Function
+%16 = OpExtInst %float %1 Sqrt %float_1
+%15 = OpConvertFToS %int %16
+OpSelectionMerge %19 None
+OpSwitch %15 %22 0 %20 1 %21
+%20 = OpLabel
+OpStore %x %float_0
+OpBranch %19
+%21 = OpLabel
+OpStore %x %float_1
+OpBranch %19
+%22 = OpLabel
+OpStore %x %float_2
+OpBranch %19
+%19 = OpLabel
+%25 = OpLoad %float %x
+%26 = OpCompositeConstruct %v4float %25 %25 %25 %25
+OpStore %sk_FragColor %26
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/SwitchContainingDeadCode.asm.frag b/tests/sksl/shared/golden/SwitchContainingDeadCode.asm.frag
new file mode 100644
index 0000000..b6e9e55
--- /dev/null
+++ b/tests/sksl/shared/golden/SwitchContainingDeadCode.asm.frag
@@ -0,0 +1,41 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_2 = OpConstant %float 2
+%int = OpTypeInt 32 1
+%21 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%main = OpFunction %void None %11
+%12 = OpLabel
+%14 = OpExtInst %float %1 Sqrt %float_2
+%13 = OpConvertFToS %int %14
+OpSelectionMerge %17 None
+OpSwitch %13 %20 0 %18 1 %19
+%18 = OpLabel
+OpBranch %19
+%19 = OpLabel
+OpBranch %20
+%20 = OpLabel
+OpBranch %17
+%17 = OpLabel
+OpStore %sk_FragColor %21
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/SwitchWithFallthrough.asm.frag b/tests/sksl/shared/golden/SwitchWithFallthrough.asm.frag
new file mode 100644
index 0000000..47cdfa2
--- /dev/null
+++ b/tests/sksl/shared/golden/SwitchWithFallthrough.asm.frag
@@ -0,0 +1,48 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_0 = OpConstant %float 0
+%float_3 = OpConstant %float 3
+%int = OpTypeInt 32 1
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_float Function
+OpStore %x %float_0
+%17 = OpExtInst %float %1 Sqrt %float_3
+%16 = OpConvertFToS %int %17
+OpSelectionMerge %20 None
+OpSwitch %16 %20 0 %21 1 %22
+%21 = OpLabel
+OpStore %x %float_0
+OpBranch %22
+%22 = OpLabel
+OpStore %x %float_1
+OpBranch %20
+%20 = OpLabel
+%24 = OpLoad %float %x
+%25 = OpCompositeConstruct %v4float %24 %24 %24 %24
+OpStore %sk_FragColor %25
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/SwizzleBoolConstants.asm.frag b/tests/sksl/shared/golden/SwizzleBoolConstants.asm.frag
new file mode 100644
index 0000000..c550ced
--- /dev/null
+++ b/tests/sksl/shared/golden/SwizzleBoolConstants.asm.frag
@@ -0,0 +1,263 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %v "v"
+OpName %result "result"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %21 RelaxedPrecision
+OpDecorate %25 RelaxedPrecision
+OpDecorate %32 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+OpDecorate %44 RelaxedPrecision
+OpDecorate %51 RelaxedPrecision
+OpDecorate %60 RelaxedPrecision
+OpDecorate %62 RelaxedPrecision
+OpDecorate %69 RelaxedPrecision
+OpDecorate %76 RelaxedPrecision
+OpDecorate %85 RelaxedPrecision
+OpDecorate %92 RelaxedPrecision
+OpDecorate %99 RelaxedPrecision
+OpDecorate %100 RelaxedPrecision
+OpDecorate %106 RelaxedPrecision
+OpDecorate %110 RelaxedPrecision
+OpDecorate %113 RelaxedPrecision
+OpDecorate %118 RelaxedPrecision
+OpDecorate %120 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %130 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %138 RelaxedPrecision
+OpDecorate %144 RelaxedPrecision
+OpDecorate %149 RelaxedPrecision
+OpDecorate %151 RelaxedPrecision
+OpDecorate %154 RelaxedPrecision
+OpDecorate %157 RelaxedPrecision
+OpDecorate %162 RelaxedPrecision
+OpDecorate %165 RelaxedPrecision
+OpDecorate %169 RelaxedPrecision
+OpDecorate %179 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%v4bool = OpTypeVector %bool 4
+%_ptr_Function_v4bool = OpTypePointer Function %v4bool
+%float_1 = OpConstant %float 1
+%true = OpConstantTrue %bool
+%v2bool = OpTypeVector %bool 2
+%false = OpConstantFalse %bool
+%v3bool = OpTypeVector %bool 3
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1_0 = OpConstant %float 1
+%175 = OpConstantComposite %v4float %float_1_0 %float_1_0 %float_1_0 %float_1_0
+%float_0 = OpConstant %float 0
+%177 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%main = OpFunction %void None %11
+%12 = OpLabel
+%v = OpVariable %_ptr_Function_v4bool Function
+%result = OpVariable %_ptr_Function_v4bool Function
+%170 = OpVariable %_ptr_Function_v4float Function
+%16 = OpExtInst %float %1 Sqrt %float_1
+%18 = OpFOrdEqual %bool %16 %float_1
+%19 = OpCompositeConstruct %v4bool %18 %18 %18 %18
+OpStore %v %19
+%21 = OpLoad %v4bool %v
+%22 = OpCompositeExtract %bool %21 0
+%24 = OpCompositeConstruct %v4bool %22 %true %true %true
+OpStore %result %24
+%25 = OpLoad %v4bool %v
+%26 = OpVectorShuffle %v2bool %25 %25 0 1
+%28 = OpCompositeExtract %bool %26 0
+%29 = OpCompositeExtract %bool %26 1
+%31 = OpCompositeConstruct %v4bool %28 %29 %false %true
+OpStore %result %31
+%32 = OpLoad %v4bool %v
+%33 = OpCompositeExtract %bool %32 0
+%34 = OpCompositeConstruct %v2bool %33 %true
+%35 = OpCompositeExtract %bool %34 0
+%36 = OpCompositeExtract %bool %34 1
+%37 = OpCompositeConstruct %v4bool %35 %36 %true %false
+OpStore %result %37
+%38 = OpLoad %v4bool %v
+%39 = OpCompositeExtract %bool %38 1
+%40 = OpCompositeConstruct %v2bool %false %39
+%41 = OpCompositeExtract %bool %40 0
+%42 = OpCompositeExtract %bool %40 1
+%43 = OpCompositeConstruct %v4bool %41 %42 %true %true
+OpStore %result %43
+%44 = OpLoad %v4bool %v
+%45 = OpVectorShuffle %v3bool %44 %44 0 1 2
+%47 = OpCompositeExtract %bool %45 0
+%48 = OpCompositeExtract %bool %45 1
+%49 = OpCompositeExtract %bool %45 2
+%50 = OpCompositeConstruct %v4bool %47 %48 %49 %true
+OpStore %result %50
+%51 = OpLoad %v4bool %v
+%52 = OpVectorShuffle %v2bool %51 %51 0 1
+%53 = OpCompositeExtract %bool %52 0
+%54 = OpCompositeExtract %bool %52 1
+%55 = OpCompositeConstruct %v3bool %53 %54 %true
+%56 = OpCompositeExtract %bool %55 0
+%57 = OpCompositeExtract %bool %55 1
+%58 = OpCompositeExtract %bool %55 2
+%59 = OpCompositeConstruct %v4bool %56 %57 %58 %true
+OpStore %result %59
+%60 = OpLoad %v4bool %v
+%61 = OpCompositeExtract %bool %60 0
+%62 = OpLoad %v4bool %v
+%63 = OpCompositeExtract %bool %62 2
+%64 = OpCompositeConstruct %v3bool %61 %false %63
+%65 = OpCompositeExtract %bool %64 0
+%66 = OpCompositeExtract %bool %64 1
+%67 = OpCompositeExtract %bool %64 2
+%68 = OpCompositeConstruct %v4bool %65 %66 %67 %true
+OpStore %result %68
+%69 = OpLoad %v4bool %v
+%70 = OpCompositeExtract %bool %69 0
+%71 = OpCompositeConstruct %v3bool %70 %true %false
+%72 = OpCompositeExtract %bool %71 0
+%73 = OpCompositeExtract %bool %71 1
+%74 = OpCompositeExtract %bool %71 2
+%75 = OpCompositeConstruct %v4bool %72 %73 %74 %false
+OpStore %result %75
+%76 = OpLoad %v4bool %v
+%77 = OpVectorShuffle %v2bool %76 %76 1 2
+%78 = OpCompositeExtract %bool %77 0
+%79 = OpCompositeExtract %bool %77 1
+%80 = OpCompositeConstruct %v3bool %true %78 %79
+%81 = OpCompositeExtract %bool %80 0
+%82 = OpCompositeExtract %bool %80 1
+%83 = OpCompositeExtract %bool %80 2
+%84 = OpCompositeConstruct %v4bool %81 %82 %83 %false
+OpStore %result %84
+%85 = OpLoad %v4bool %v
+%86 = OpCompositeExtract %bool %85 1
+%87 = OpCompositeConstruct %v3bool %false %86 %true
+%88 = OpCompositeExtract %bool %87 0
+%89 = OpCompositeExtract %bool %87 1
+%90 = OpCompositeExtract %bool %87 2
+%91 = OpCompositeConstruct %v4bool %88 %89 %90 %false
+OpStore %result %91
+%92 = OpLoad %v4bool %v
+%93 = OpCompositeExtract %bool %92 2
+%94 = OpCompositeConstruct %v3bool %true %true %93
+%95 = OpCompositeExtract %bool %94 0
+%96 = OpCompositeExtract %bool %94 1
+%97 = OpCompositeExtract %bool %94 2
+%98 = OpCompositeConstruct %v4bool %95 %96 %97 %false
+OpStore %result %98
+%99 = OpLoad %v4bool %v
+OpStore %result %99
+%100 = OpLoad %v4bool %v
+%101 = OpVectorShuffle %v3bool %100 %100 0 1 2
+%102 = OpCompositeExtract %bool %101 0
+%103 = OpCompositeExtract %bool %101 1
+%104 = OpCompositeExtract %bool %101 2
+%105 = OpCompositeConstruct %v4bool %102 %103 %104 %true
+OpStore %result %105
+%106 = OpLoad %v4bool %v
+%107 = OpVectorShuffle %v2bool %106 %106 0 1
+%108 = OpCompositeExtract %bool %107 0
+%109 = OpCompositeExtract %bool %107 1
+%110 = OpLoad %v4bool %v
+%111 = OpCompositeExtract %bool %110 3
+%112 = OpCompositeConstruct %v4bool %108 %109 %false %111
+OpStore %result %112
+%113 = OpLoad %v4bool %v
+%114 = OpVectorShuffle %v2bool %113 %113 0 1
+%115 = OpCompositeExtract %bool %114 0
+%116 = OpCompositeExtract %bool %114 1
+%117 = OpCompositeConstruct %v4bool %115 %116 %true %false
+OpStore %result %117
+%118 = OpLoad %v4bool %v
+%119 = OpCompositeExtract %bool %118 0
+%120 = OpLoad %v4bool %v
+%121 = OpVectorShuffle %v2bool %120 %120 2 3
+%122 = OpCompositeExtract %bool %121 0
+%123 = OpCompositeExtract %bool %121 1
+%124 = OpCompositeConstruct %v4bool %119 %true %122 %123
+OpStore %result %124
+%125 = OpLoad %v4bool %v
+%126 = OpCompositeExtract %bool %125 0
+%127 = OpLoad %v4bool %v
+%128 = OpCompositeExtract %bool %127 2
+%129 = OpCompositeConstruct %v4bool %126 %false %128 %true
+OpStore %result %129
+%130 = OpLoad %v4bool %v
+%131 = OpCompositeExtract %bool %130 0
+%132 = OpLoad %v4bool %v
+%133 = OpCompositeExtract %bool %132 3
+%134 = OpCompositeConstruct %v4bool %131 %true %true %133
+OpStore %result %134
+%135 = OpLoad %v4bool %v
+%136 = OpCompositeExtract %bool %135 0
+%137 = OpCompositeConstruct %v4bool %136 %true %false %true
+OpStore %result %137
+%138 = OpLoad %v4bool %v
+%139 = OpVectorShuffle %v3bool %138 %138 1 2 3
+%140 = OpCompositeExtract %bool %139 0
+%141 = OpCompositeExtract %bool %139 1
+%142 = OpCompositeExtract %bool %139 2
+%143 = OpCompositeConstruct %v4bool %true %140 %141 %142
+OpStore %result %143
+%144 = OpLoad %v4bool %v
+%145 = OpVectorShuffle %v2bool %144 %144 1 2
+%146 = OpCompositeExtract %bool %145 0
+%147 = OpCompositeExtract %bool %145 1
+%148 = OpCompositeConstruct %v4bool %false %146 %147 %true
+OpStore %result %148
+%149 = OpLoad %v4bool %v
+%150 = OpCompositeExtract %bool %149 1
+%151 = OpLoad %v4bool %v
+%152 = OpCompositeExtract %bool %151 3
+%153 = OpCompositeConstruct %v4bool %false %150 %true %152
+OpStore %result %153
+%154 = OpLoad %v4bool %v
+%155 = OpCompositeExtract %bool %154 1
+%156 = OpCompositeConstruct %v4bool %true %155 %true %true
+OpStore %result %156
+%157 = OpLoad %v4bool %v
+%158 = OpVectorShuffle %v2bool %157 %157 2 3
+%159 = OpCompositeExtract %bool %158 0
+%160 = OpCompositeExtract %bool %158 1
+%161 = OpCompositeConstruct %v4bool %false %false %159 %160
+OpStore %result %161
+%162 = OpLoad %v4bool %v
+%163 = OpCompositeExtract %bool %162 2
+%164 = OpCompositeConstruct %v4bool %false %false %163 %true
+OpStore %result %164
+%165 = OpLoad %v4bool %v
+%166 = OpCompositeExtract %bool %165 3
+%167 = OpCompositeConstruct %v4bool %false %true %true %166
+OpStore %result %167
+%169 = OpLoad %v4bool %result
+%168 = OpAny %bool %169
+OpSelectionMerge %174 None
+OpBranchConditional %168 %172 %173
+%172 = OpLabel
+OpStore %170 %175
+OpBranch %174
+%173 = OpLabel
+OpStore %170 %177
+OpBranch %174
+%174 = OpLabel
+%179 = OpLoad %v4float %170
+OpStore %sk_FragColor %179
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/SwizzleConstants.asm.frag b/tests/sksl/shared/golden/SwizzleConstants.asm.frag
new file mode 100644
index 0000000..69d7811
--- /dev/null
+++ b/tests/sksl/shared/golden/SwizzleConstants.asm.frag
@@ -0,0 +1,238 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %v "v"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %18 RelaxedPrecision
+OpDecorate %22 RelaxedPrecision
+OpDecorate %28 RelaxedPrecision
+OpDecorate %35 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %48 RelaxedPrecision
+OpDecorate %57 RelaxedPrecision
+OpDecorate %59 RelaxedPrecision
+OpDecorate %66 RelaxedPrecision
+OpDecorate %73 RelaxedPrecision
+OpDecorate %82 RelaxedPrecision
+OpDecorate %89 RelaxedPrecision
+OpDecorate %96 RelaxedPrecision
+OpDecorate %97 RelaxedPrecision
+OpDecorate %103 RelaxedPrecision
+OpDecorate %107 RelaxedPrecision
+OpDecorate %110 RelaxedPrecision
+OpDecorate %115 RelaxedPrecision
+OpDecorate %117 RelaxedPrecision
+OpDecorate %122 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %129 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %135 RelaxedPrecision
+OpDecorate %141 RelaxedPrecision
+OpDecorate %146 RelaxedPrecision
+OpDecorate %148 RelaxedPrecision
+OpDecorate %151 RelaxedPrecision
+OpDecorate %154 RelaxedPrecision
+OpDecorate %159 RelaxedPrecision
+OpDecorate %162 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_1 = OpConstant %float 1
+%float_1_0 = OpConstant %float 1
+%v2float = OpTypeVector %float 2
+%float_0 = OpConstant %float 0
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %11
+%12 = OpLabel
+%v = OpVariable %_ptr_Function_v4float Function
+%15 = OpExtInst %float %1 Sqrt %float_1
+%17 = OpCompositeConstruct %v4float %15 %15 %15 %15
+OpStore %v %17
+%18 = OpLoad %v4float %v
+%19 = OpCompositeExtract %float %18 0
+%21 = OpCompositeConstruct %v4float %19 %float_1_0 %float_1_0 %float_1_0
+OpStore %sk_FragColor %21
+%22 = OpLoad %v4float %v
+%23 = OpVectorShuffle %v2float %22 %22 0 1
+%25 = OpCompositeExtract %float %23 0
+%26 = OpCompositeExtract %float %23 1
+%27 = OpCompositeConstruct %v4float %25 %26 %float_1_0 %float_1_0
+OpStore %sk_FragColor %27
+%28 = OpLoad %v4float %v
+%29 = OpCompositeExtract %float %28 0
+%30 = OpCompositeConstruct %v2float %29 %float_1_0
+%31 = OpCompositeExtract %float %30 0
+%32 = OpCompositeExtract %float %30 1
+%33 = OpCompositeConstruct %v4float %31 %32 %float_1_0 %float_1_0
+OpStore %sk_FragColor %33
+%35 = OpLoad %v4float %v
+%36 = OpCompositeExtract %float %35 1
+%37 = OpCompositeConstruct %v2float %float_0 %36
+%38 = OpCompositeExtract %float %37 0
+%39 = OpCompositeExtract %float %37 1
+%40 = OpCompositeConstruct %v4float %38 %39 %float_1_0 %float_1_0
+OpStore %sk_FragColor %40
+%41 = OpLoad %v4float %v
+%42 = OpVectorShuffle %v3float %41 %41 0 1 2
+%44 = OpCompositeExtract %float %42 0
+%45 = OpCompositeExtract %float %42 1
+%46 = OpCompositeExtract %float %42 2
+%47 = OpCompositeConstruct %v4float %44 %45 %46 %float_1_0
+OpStore %sk_FragColor %47
+%48 = OpLoad %v4float %v
+%49 = OpVectorShuffle %v2float %48 %48 0 1
+%50 = OpCompositeExtract %float %49 0
+%51 = OpCompositeExtract %float %49 1
+%52 = OpCompositeConstruct %v3float %50 %51 %float_1_0
+%53 = OpCompositeExtract %float %52 0
+%54 = OpCompositeExtract %float %52 1
+%55 = OpCompositeExtract %float %52 2
+%56 = OpCompositeConstruct %v4float %53 %54 %55 %float_1_0
+OpStore %sk_FragColor %56
+%57 = OpLoad %v4float %v
+%58 = OpCompositeExtract %float %57 0
+%59 = OpLoad %v4float %v
+%60 = OpCompositeExtract %float %59 2
+%61 = OpCompositeConstruct %v3float %58 %float_0 %60
+%62 = OpCompositeExtract %float %61 0
+%63 = OpCompositeExtract %float %61 1
+%64 = OpCompositeExtract %float %61 2
+%65 = OpCompositeConstruct %v4float %62 %63 %64 %float_1_0
+OpStore %sk_FragColor %65
+%66 = OpLoad %v4float %v
+%67 = OpCompositeExtract %float %66 0
+%68 = OpCompositeConstruct %v3float %67 %float_1_0 %float_0
+%69 = OpCompositeExtract %float %68 0
+%70 = OpCompositeExtract %float %68 1
+%71 = OpCompositeExtract %float %68 2
+%72 = OpCompositeConstruct %v4float %69 %70 %71 %float_1_0
+OpStore %sk_FragColor %72
+%73 = OpLoad %v4float %v
+%74 = OpVectorShuffle %v2float %73 %73 1 2
+%75 = OpCompositeExtract %float %74 0
+%76 = OpCompositeExtract %float %74 1
+%77 = OpCompositeConstruct %v3float %float_1_0 %75 %76
+%78 = OpCompositeExtract %float %77 0
+%79 = OpCompositeExtract %float %77 1
+%80 = OpCompositeExtract %float %77 2
+%81 = OpCompositeConstruct %v4float %78 %79 %80 %float_1_0
+OpStore %sk_FragColor %81
+%82 = OpLoad %v4float %v
+%83 = OpCompositeExtract %float %82 1
+%84 = OpCompositeConstruct %v3float %float_0 %83 %float_1_0
+%85 = OpCompositeExtract %float %84 0
+%86 = OpCompositeExtract %float %84 1
+%87 = OpCompositeExtract %float %84 2
+%88 = OpCompositeConstruct %v4float %85 %86 %87 %float_1_0
+OpStore %sk_FragColor %88
+%89 = OpLoad %v4float %v
+%90 = OpCompositeExtract %float %89 2
+%91 = OpCompositeConstruct %v3float %float_1_0 %float_1_0 %90
+%92 = OpCompositeExtract %float %91 0
+%93 = OpCompositeExtract %float %91 1
+%94 = OpCompositeExtract %float %91 2
+%95 = OpCompositeConstruct %v4float %92 %93 %94 %float_1_0
+OpStore %sk_FragColor %95
+%96 = OpLoad %v4float %v
+OpStore %sk_FragColor %96
+%97 = OpLoad %v4float %v
+%98 = OpVectorShuffle %v3float %97 %97 0 1 2
+%99 = OpCompositeExtract %float %98 0
+%100 = OpCompositeExtract %float %98 1
+%101 = OpCompositeExtract %float %98 2
+%102 = OpCompositeConstruct %v4float %99 %100 %101 %float_1_0
+OpStore %sk_FragColor %102
+%103 = OpLoad %v4float %v
+%104 = OpVectorShuffle %v2float %103 %103 0 1
+%105 = OpCompositeExtract %float %104 0
+%106 = OpCompositeExtract %float %104 1
+%107 = OpLoad %v4float %v
+%108 = OpCompositeExtract %float %107 3
+%109 = OpCompositeConstruct %v4float %105 %106 %float_0 %108
+OpStore %sk_FragColor %109
+%110 = OpLoad %v4float %v
+%111 = OpVectorShuffle %v2float %110 %110 0 1
+%112 = OpCompositeExtract %float %111 0
+%113 = OpCompositeExtract %float %111 1
+%114 = OpCompositeConstruct %v4float %112 %113 %float_1_0 %float_0
+OpStore %sk_FragColor %114
+%115 = OpLoad %v4float %v
+%116 = OpCompositeExtract %float %115 0
+%117 = OpLoad %v4float %v
+%118 = OpVectorShuffle %v2float %117 %117 2 3
+%119 = OpCompositeExtract %float %118 0
+%120 = OpCompositeExtract %float %118 1
+%121 = OpCompositeConstruct %v4float %116 %float_1_0 %119 %120
+OpStore %sk_FragColor %121
+%122 = OpLoad %v4float %v
+%123 = OpCompositeExtract %float %122 0
+%124 = OpLoad %v4float %v
+%125 = OpCompositeExtract %float %124 2
+%126 = OpCompositeConstruct %v4float %123 %float_0 %125 %float_1_0
+OpStore %sk_FragColor %126
+%127 = OpLoad %v4float %v
+%128 = OpCompositeExtract %float %127 0
+%129 = OpLoad %v4float %v
+%130 = OpCompositeExtract %float %129 3
+%131 = OpCompositeConstruct %v4float %128 %float_1_0 %float_1_0 %130
+OpStore %sk_FragColor %131
+%132 = OpLoad %v4float %v
+%133 = OpCompositeExtract %float %132 0
+%134 = OpCompositeConstruct %v4float %133 %float_1_0 %float_0 %float_1_0
+OpStore %sk_FragColor %134
+%135 = OpLoad %v4float %v
+%136 = OpVectorShuffle %v3float %135 %135 1 2 3
+%137 = OpCompositeExtract %float %136 0
+%138 = OpCompositeExtract %float %136 1
+%139 = OpCompositeExtract %float %136 2
+%140 = OpCompositeConstruct %v4float %float_1_0 %137 %138 %139
+OpStore %sk_FragColor %140
+%141 = OpLoad %v4float %v
+%142 = OpVectorShuffle %v2float %141 %141 1 2
+%143 = OpCompositeExtract %float %142 0
+%144 = OpCompositeExtract %float %142 1
+%145 = OpCompositeConstruct %v4float %float_0 %143 %144 %float_1_0
+OpStore %sk_FragColor %145
+%146 = OpLoad %v4float %v
+%147 = OpCompositeExtract %float %146 1
+%148 = OpLoad %v4float %v
+%149 = OpCompositeExtract %float %148 3
+%150 = OpCompositeConstruct %v4float %float_0 %147 %float_1_0 %149
+OpStore %sk_FragColor %150
+%151 = OpLoad %v4float %v
+%152 = OpCompositeExtract %float %151 1
+%153 = OpCompositeConstruct %v4float %float_1_0 %152 %float_1_0 %float_1_0
+OpStore %sk_FragColor %153
+%154 = OpLoad %v4float %v
+%155 = OpVectorShuffle %v2float %154 %154 2 3
+%156 = OpCompositeExtract %float %155 0
+%157 = OpCompositeExtract %float %155 1
+%158 = OpCompositeConstruct %v4float %float_0 %float_0 %156 %157
+OpStore %sk_FragColor %158
+%159 = OpLoad %v4float %v
+%160 = OpCompositeExtract %float %159 2
+%161 = OpCompositeConstruct %v4float %float_0 %float_0 %160 %float_1_0
+OpStore %sk_FragColor %161
+%162 = OpLoad %v4float %v
+%163 = OpCompositeExtract %float %162 3
+%164 = OpCompositeConstruct %v4float %float_0 %float_1_0 %float_1_0 %163
+OpStore %sk_FragColor %164
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/SwizzleLTRB.asm.frag b/tests/sksl/shared/golden/SwizzleLTRB.asm.frag
new file mode 100644
index 0000000..8074f15
--- /dev/null
+++ b/tests/sksl/shared/golden/SwizzleLTRB.asm.frag
@@ -0,0 +1,30 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %13 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%main = OpFunction %void None %11
+%12 = OpLabel
+%13 = OpLoad %v4float %sk_FragColor
+%14 = OpVectorShuffle %v4float %13 %13 3 2 1 0
+OpStore %sk_FragColor %14
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/SwizzleOpt.asm.frag b/tests/sksl/shared/golden/SwizzleOpt.asm.frag
new file mode 100644
index 0000000..8c57f4df
--- /dev/null
+++ b/tests/sksl/shared/golden/SwizzleOpt.asm.frag
@@ -0,0 +1,5 @@
+### Compilation failed:
+
+error: 44: unable to retrieve lvalue from swizzle
+error: 45: unable to retrieve lvalue from swizzle
+2 errors
diff --git a/tests/sksl/shared/golden/SwizzleScalar.asm.frag b/tests/sksl/shared/golden/SwizzleScalar.asm.frag
new file mode 100644
index 0000000..40c4bd4
--- /dev/null
+++ b/tests/sksl/shared/golden/SwizzleScalar.asm.frag
@@ -0,0 +1,59 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %x "x"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %17 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_4 = OpConstant %float 4
+%v2float = OpTypeVector %float 2
+%float_0 = OpConstant %float 0
+%float_1 = OpConstant %float 1
+%v3float = OpTypeVector %float 3
+%main = OpFunction %void None %11
+%12 = OpLabel
+%x = OpVariable %_ptr_Function_float Function
+%15 = OpExtInst %float %1 Sqrt %float_4
+OpStore %x %15
+%17 = OpLoad %float %x
+%18 = OpCompositeConstruct %v2float %17 %17
+%20 = OpCompositeExtract %float %18 0
+%21 = OpCompositeExtract %float %18 1
+%24 = OpCompositeConstruct %v4float %20 %21 %float_0 %float_1
+OpStore %sk_FragColor %24
+%25 = OpExtInst %float %1 Sqrt %float_4
+%26 = OpCompositeConstruct %v2float %25 %25
+%27 = OpCompositeExtract %float %26 0
+%28 = OpCompositeExtract %float %26 1
+%29 = OpCompositeConstruct %v4float %27 %28 %float_0 %float_1
+OpStore %sk_FragColor %29
+%30 = OpExtInst %float %1 Sqrt %float_4
+%31 = OpCompositeConstruct %v4float %float_0 %30 %float_0 %float_1
+OpStore %sk_FragColor %31
+%32 = OpExtInst %float %1 Sqrt %float_4
+%33 = OpCompositeConstruct %v2float %32 %32
+%34 = OpCompositeExtract %float %33 0
+%35 = OpCompositeExtract %float %33 1
+%36 = OpCompositeConstruct %v3float %34 %35 %float_0
+%38 = OpVectorShuffle %v4float %36 %36 2 0 2 1
+OpStore %sk_FragColor %38
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/TernaryAsLValueEntirelyFoldable.asm.frag b/tests/sksl/shared/golden/TernaryAsLValueEntirelyFoldable.asm.frag
new file mode 100644
index 0000000..9d36860
--- /dev/null
+++ b/tests/sksl/shared/golden/TernaryAsLValueEntirelyFoldable.asm.frag
@@ -0,0 +1,30 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_1 = OpConstant %float 1
+%float_0 = OpConstant %float 0
+%13 = OpConstantComposite %v4float %float_1 %float_0 %float_1 %float_1
+%main = OpFunction %void None %11
+%12 = OpLabel
+OpStore %sk_FragColor %13
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/TernaryAsLValueFoldableTest.asm.frag b/tests/sksl/shared/golden/TernaryAsLValueFoldableTest.asm.frag
new file mode 100644
index 0000000..84e961a
--- /dev/null
+++ b/tests/sksl/shared/golden/TernaryAsLValueFoldableTest.asm.frag
@@ -0,0 +1,44 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %r "r"
+OpName %g "g"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %20 RelaxedPrecision
+OpDecorate %21 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_1 = OpConstant %float 1
+%float_0 = OpConstant %float 0
+%float_1_0 = OpConstant %float 1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%r = OpVariable %_ptr_Function_float Function
+%g = OpVariable %_ptr_Function_float Function
+%16 = OpExtInst %float %1 Sqrt %float_1
+OpStore %r %16
+%18 = OpExtInst %float %1 Sqrt %float_0
+OpStore %g %18
+%20 = OpLoad %float %r
+%21 = OpLoad %float %g
+%23 = OpCompositeConstruct %v4float %20 %21 %float_1_0 %float_1_0
+OpStore %sk_FragColor %23
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Texture1D.asm.frag b/tests/sksl/shared/golden/Texture1D.asm.frag
new file mode 100644
index 0000000..98a397e
--- /dev/null
+++ b/tests/sksl/shared/golden/Texture1D.asm.frag
@@ -0,0 +1,59 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %tex "tex"
+OpName %main "main"
+OpName %a "a"
+OpName %b "b"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %tex RelaxedPrecision
+OpDecorate %tex Binding 0
+OpDecorate %20 RelaxedPrecision
+OpDecorate %24 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%13 = OpTypeImage %float 1D 0 0 0 1 Unknown
+%12 = OpTypeSampledImage %13
+%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
+%tex = OpVariable %_ptr_UniformConstant_12 UniformConstant
+%void = OpTypeVoid
+%15 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_0 = OpConstant %float 0
+%v2float = OpTypeVector %float 2
+%25 = OpConstantComposite %v2float %float_0 %float_0
+%main = OpFunction %void None %15
+%16 = OpLabel
+%a = OpVariable %_ptr_Function_v4float Function
+%b = OpVariable %_ptr_Function_v4float Function
+%20 = OpLoad %12 %tex
+%19 = OpImageSampleImplicitLod %v4float %20 %float_0
+OpStore %a %19
+%24 = OpLoad %12 %tex
+%23 = OpImageSampleProjImplicitLod %v4float %24 %25
+OpStore %b %23
+%27 = OpLoad %v4float %a
+%28 = OpVectorShuffle %v2float %27 %27 0 1
+%29 = OpCompositeExtract %float %28 0
+%30 = OpCompositeExtract %float %28 1
+%31 = OpLoad %v4float %b
+%32 = OpVectorShuffle %v2float %31 %31 2 3
+%33 = OpCompositeExtract %float %32 0
+%34 = OpCompositeExtract %float %32 1
+%35 = OpCompositeConstruct %v4float %29 %30 %33 %34
+OpStore %sk_FragColor %35
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Texture2D.asm.frag b/tests/sksl/shared/golden/Texture2D.asm.frag
new file mode 100644
index 0000000..28f4ecc
--- /dev/null
+++ b/tests/sksl/shared/golden/Texture2D.asm.frag
@@ -0,0 +1,61 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %tex "tex"
+OpName %main "main"
+OpName %a "a"
+OpName %b "b"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %tex RelaxedPrecision
+OpDecorate %tex Binding 0
+OpDecorate %20 RelaxedPrecision
+OpDecorate %26 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%13 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%12 = OpTypeSampledImage %13
+%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
+%tex = OpVariable %_ptr_UniformConstant_12 UniformConstant
+%void = OpTypeVoid
+%15 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_0 = OpConstant %float 0
+%v2float = OpTypeVector %float 2
+%21 = OpConstantComposite %v2float %float_0 %float_0
+%v3float = OpTypeVector %float 3
+%27 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%main = OpFunction %void None %15
+%16 = OpLabel
+%a = OpVariable %_ptr_Function_v4float Function
+%b = OpVariable %_ptr_Function_v4float Function
+%20 = OpLoad %12 %tex
+%19 = OpImageSampleImplicitLod %v4float %20 %21
+OpStore %a %19
+%26 = OpLoad %12 %tex
+%25 = OpImageSampleProjImplicitLod %v4float %26 %27
+OpStore %b %25
+%29 = OpLoad %v4float %a
+%30 = OpVectorShuffle %v2float %29 %29 0 1
+%31 = OpCompositeExtract %float %30 0
+%32 = OpCompositeExtract %float %30 1
+%33 = OpLoad %v4float %b
+%34 = OpVectorShuffle %v2float %33 %33 2 3
+%35 = OpCompositeExtract %float %34 0
+%36 = OpCompositeExtract %float %34 1
+%37 = OpCompositeConstruct %v4float %31 %32 %35 %36
+OpStore %sk_FragColor %37
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/TextureSharpen.asm.frag b/tests/sksl/shared/golden/TextureSharpen.asm.frag
new file mode 100644
index 0000000..2e5fe9b
--- /dev/null
+++ b/tests/sksl/shared/golden/TextureSharpen.asm.frag
@@ -0,0 +1,82 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %one "one"
+OpName %two "two"
+OpName %main "main"
+OpName %a "a"
+OpName %b "b"
+OpName %c "c"
+OpName %d "d"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %one RelaxedPrecision
+OpDecorate %one Binding 0
+OpDecorate %two RelaxedPrecision
+OpDecorate %two Binding 1
+OpDecorate %24 RelaxedPrecision
+OpDecorate %29 RelaxedPrecision
+OpDecorate %34 RelaxedPrecision
+OpDecorate %38 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%13 = OpTypeImage %float 1D 0 0 0 1 Unknown
+%12 = OpTypeSampledImage %13
+%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
+%one = OpVariable %_ptr_UniformConstant_12 UniformConstant
+%17 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%16 = OpTypeSampledImage %17
+%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
+%two = OpVariable %_ptr_UniformConstant_16 UniformConstant
+%void = OpTypeVoid
+%19 = OpTypeFunction %void
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%float_0 = OpConstant %float 0
+%float_n0_5 = OpConstant %float -0.5
+%v2float = OpTypeVector %float 2
+%30 = OpConstantComposite %v2float %float_0 %float_0
+%35 = OpConstantComposite %v2float %float_0 %float_0
+%v3float = OpTypeVector %float 3
+%39 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%main = OpFunction %void None %19
+%20 = OpLabel
+%a = OpVariable %_ptr_Function_v4float Function
+%b = OpVariable %_ptr_Function_v4float Function
+%c = OpVariable %_ptr_Function_v4float Function
+%d = OpVariable %_ptr_Function_v4float Function
+%24 = OpLoad %12 %one
+%23 = OpImageSampleImplicitLod %v4float %24 %float_0 Bias %float_n0_5
+OpStore %a %23
+%29 = OpLoad %16 %two
+%28 = OpImageSampleImplicitLod %v4float %29 %30 Bias %float_n0_5
+OpStore %b %28
+%34 = OpLoad %12 %one
+%33 = OpImageSampleProjImplicitLod %v4float %34 %35 Bias %float_n0_5
+OpStore %c %33
+%38 = OpLoad %16 %two
+%37 = OpImageSampleProjImplicitLod %v4float %38 %39 Bias %float_n0_5
+OpStore %d %37
+%41 = OpLoad %v4float %a
+%42 = OpCompositeExtract %float %41 0
+%43 = OpLoad %v4float %b
+%44 = OpCompositeExtract %float %43 0
+%45 = OpLoad %v4float %c
+%46 = OpCompositeExtract %float %45 0
+%47 = OpLoad %v4float %d
+%48 = OpCompositeExtract %float %47 0
+%49 = OpCompositeConstruct %v4float %42 %44 %46 %48
+OpStore %sk_FragColor %49
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/UnaryPositiveNegative.asm.frag b/tests/sksl/shared/golden/UnaryPositiveNegative.asm.frag
new file mode 100644
index 0000000..7a6ecb2
--- /dev/null
+++ b/tests/sksl/shared/golden/UnaryPositiveNegative.asm.frag
@@ -0,0 +1,33 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %17 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_n1 = OpConstant %float -1
+%v2float = OpTypeVector %float 2
+%13 = OpConstantComposite %v2float %float_n1 %float_n1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%16 = OpLoad %v4float %sk_FragColor
+%17 = OpVectorShuffle %v4float %16 %13 4 5 2 3
+OpStore %sk_FragColor %17
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/UnusedVariables.asm.frag b/tests/sksl/shared/golden/UnusedVariables.asm.frag
new file mode 100644
index 0000000..184e639
--- /dev/null
+++ b/tests/sksl/shared/golden/UnusedVariables.asm.frag
@@ -0,0 +1,48 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %b "b"
+OpName %d "d"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%_ptr_Function_float = OpTypePointer Function %float
+%float_2 = OpConstant %float 2
+%float_3 = OpConstant %float 3
+%float_1 = OpConstant %float 1
+%main = OpFunction %void None %11
+%12 = OpLabel
+%b = OpVariable %_ptr_Function_float Function
+%d = OpVariable %_ptr_Function_float Function
+OpStore %b %float_2
+OpStore %d %float_3
+%18 = OpLoad %float %b
+%20 = OpFAdd %float %18 %float_1
+OpStore %b %20
+%21 = OpLoad %float %d
+%22 = OpFAdd %float %21 %float_1
+OpStore %d %22
+%23 = OpLoad %float %b
+%24 = OpLoad %float %b
+%25 = OpLoad %float %d
+%26 = OpLoad %float %d
+%27 = OpCompositeConstruct %v4float %23 %24 %25 %26
+OpStore %sk_FragColor %27
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/VectorConstructors.asm.frag b/tests/sksl/shared/golden/VectorConstructors.asm.frag
new file mode 100644
index 0000000..6c156bd
--- /dev/null
+++ b/tests/sksl/shared/golden/VectorConstructors.asm.frag
@@ -0,0 +1,94 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %v1 "v1"
+OpName %v2 "v2"
+OpName %v3 "v3"
+OpName %v4 "v4"
+OpName %v5 "v5"
+OpName %v6 "v6"
+OpName %v7 "v7"
+OpName %main "main"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%v2float = OpTypeVector %float 2
+%_ptr_Private_v2float = OpTypePointer Private %v2float
+%v1 = OpVariable %_ptr_Private_v2float Private
+%float_1 = OpConstant %float 1
+%13 = OpConstantComposite %v2float %float_1 %float_1
+%v2 = OpVariable %_ptr_Private_v2float Private
+%float_2 = OpConstant %float 2
+%16 = OpConstantComposite %v2float %float_1 %float_2
+%v3 = OpVariable %_ptr_Private_v2float Private
+%19 = OpConstantComposite %v2float %float_1 %float_1
+%v3float = OpTypeVector %float 3
+%_ptr_Private_v3float = OpTypePointer Private %v3float
+%v4 = OpVariable %_ptr_Private_v3float Private
+%24 = OpConstantComposite %v2float %float_1 %float_1
+%23 = OpConstantComposite %v3float %24 %float_1
+%int = OpTypeInt 32 1
+%v2int = OpTypeVector %int 2
+%_ptr_Private_v2int = OpTypePointer Private %v2int
+%v5 = OpVariable %_ptr_Private_v2int Private
+%int_1 = OpConstant %int 1
+%29 = OpConstantComposite %v2int %int_1 %int_1
+%v6 = OpVariable %_ptr_Private_v2int Private
+%33 = OpConstantComposite %v2float %float_1 %float_2
+%32 = OpConstantComposite %v2int %33 %33
+%v7 = OpVariable %_ptr_Private_v2float Private
+%int_2 = OpConstant %int 2
+%36 = OpConstantComposite %v2int %int_1 %int_2
+%35 = OpConstantComposite %v2float %36 %36
+%void = OpTypeVoid
+%39 = OpTypeFunction %void
+%_ptr_Output_float = OpTypePointer Output %float
+%int_0 = OpConstant %int 0
+%main = OpFunction %void None %39
+%40 = OpLabel
+OpStore %v1 %13
+OpStore %v2 %16
+OpStore %v3 %19
+OpStore %v4 %23
+OpStore %v5 %29
+OpStore %v6 %32
+OpStore %v7 %35
+%41 = OpLoad %v2float %v1
+%42 = OpCompositeExtract %float %41 0
+%43 = OpLoad %v2float %v2
+%44 = OpCompositeExtract %float %43 0
+%45 = OpFAdd %float %42 %44
+%46 = OpLoad %v2float %v3
+%47 = OpCompositeExtract %float %46 0
+%48 = OpFAdd %float %45 %47
+%49 = OpLoad %v3float %v4
+%50 = OpCompositeExtract %float %49 0
+%51 = OpFAdd %float %48 %50
+%53 = OpLoad %v2int %v5
+%54 = OpCompositeExtract %int %53 0
+%52 = OpConvertSToF %float %54
+%55 = OpFAdd %float %51 %52
+%57 = OpLoad %v2int %v6
+%58 = OpCompositeExtract %int %57 0
+%56 = OpConvertSToF %float %58
+%59 = OpFAdd %float %55 %56
+%60 = OpLoad %v2float %v7
+%61 = OpCompositeExtract %float %60 0
+%62 = OpFAdd %float %59 %61
+%63 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %63 %62
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/VectorFolding.asm.frag b/tests/sksl/shared/golden/VectorFolding.asm.frag
new file mode 100644
index 0000000..81eecae
--- /dev/null
+++ b/tests/sksl/shared/golden/VectorFolding.asm.frag
@@ -0,0 +1,371 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise
+OpExecutionMode %main OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %main "main"
+OpName %_0_result "_0_result"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise RelaxedPrecision
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %122 RelaxedPrecision
+OpDecorate %124 RelaxedPrecision
+OpDecorate %125 RelaxedPrecision
+OpDecorate %127 RelaxedPrecision
+OpDecorate %128 RelaxedPrecision
+OpDecorate %131 RelaxedPrecision
+OpDecorate %132 RelaxedPrecision
+OpDecorate %134 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%float_0_5 = OpConstant %float 0.5
+%_ptr_Output_float = OpTypePointer Output %float
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_6 = OpConstant %float 6
+%float_7 = OpConstant %float 7
+%float_9 = OpConstant %float 9
+%float_11 = OpConstant %float 11
+%18 = OpConstantComposite %v4float %float_6 %float_7 %float_9 %float_11
+%23 = OpConstantComposite %v4float %float_7 %float_9 %float_9 %float_9
+%float_2 = OpConstant %float 2
+%float_4 = OpConstant %float 4
+%float_8 = OpConstant %float 8
+%24 = OpConstantComposite %v4float %float_2 %float_4 %float_6 %float_8
+%float_12 = OpConstant %float 12
+%float_3 = OpConstant %float 3
+%28 = OpConstantComposite %v4float %float_12 %float_6 %float_4 %float_3
+%float_6_0 = OpConstant %float 6
+%float_1 = OpConstant %float 1
+%float_n2 = OpConstant %float -2
+%float_3_0 = OpConstant %float 3
+%float_4_0 = OpConstant %float 4
+%float_n5 = OpConstant %float -5
+%float_7_0 = OpConstant %float 7
+%float_n8 = OpConstant %float -8
+%float_9_0 = OpConstant %float 9
+%float_n10 = OpConstant %float -10
+%float_n11 = OpConstant %float -11
+%float_n12 = OpConstant %float -12
+%float_13 = OpConstant %float 13
+%float_n13 = OpConstant %float -13
+%float_1_0 = OpConstant %float 1
+%float_0 = OpConstant %float 0
+%73 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%75 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%76 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%85 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%86 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%float_13_0 = OpConstant %float 13
+%92 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%93 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%float_16 = OpConstant %float 16
+%float_17 = OpConstant %float 17
+%100 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%float_19 = OpConstant %float 19
+%float_19_5 = OpConstant %float 19.5
+%float_20 = OpConstant %float 20
+%float_21 = OpConstant %float 21
+%float_22 = OpConstant %float 22
+%float_23 = OpConstant %float 23
+%float_24 = OpConstant %float 24
+%123 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%126 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%float_2_0 = OpConstant %float 2
+%129 = OpConstantComposite %v4float %float_2_0 %float_2_0 %float_2_0 %float_2_0
+%133 = OpConstantComposite %v4float %float_2_0 %float_2_0 %float_2_0 %float_2_0
+%v4int = OpTypeVector %int 4
+%_ptr_Function_v4int = OpTypePointer Function %v4int
+%int_2 = OpConstant %int 2
+%_ptr_Function_int = OpTypePointer Function %int
+%int_6 = OpConstant %int 6
+%int_7 = OpConstant %int 7
+%int_9 = OpConstant %int 9
+%int_11 = OpConstant %int 11
+%141 = OpConstantComposite %v4int %int_6 %int_7 %int_9 %int_11
+%146 = OpConstantComposite %v4int %int_7 %int_9 %int_9 %int_9
+%int_4 = OpConstant %int 4
+%int_8 = OpConstant %int 8
+%147 = OpConstantComposite %v4int %int_2 %int_4 %int_6 %int_8
+%int_12 = OpConstant %int 12
+%int_3 = OpConstant %int 3
+%150 = OpConstantComposite %v4int %int_12 %int_6 %int_4 %int_3
+%170 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%171 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%172 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%185 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%186 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%193 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%194 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%201 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+%int_1 = OpConstant %int 1
+%224 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1
+%228 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1
+%231 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2
+%234 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2
+%main = OpFunction %void None %11
+%12 = OpLabel
+%_0_result = OpVariable %_ptr_Function_v4int Function
+%14 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %14 %float_0_5
+OpStore %sk_FragColor %18
+OpStore %sk_FragColor %23
+OpStore %sk_FragColor %24
+OpStore %sk_FragColor %28
+%32 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %32 %float_6_0
+%34 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %34 %float_1
+%36 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %36 %float_n2
+%38 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %38 %float_3_0
+%40 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %40 %float_4_0
+%42 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %42 %float_n5
+%43 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %43 %float_6_0
+%45 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %45 %float_7_0
+%47 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %47 %float_n8
+%49 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %49 %float_9_0
+%51 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %51 %float_n10
+%53 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %53 %float_n11
+%55 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %55 %float_n12
+%57 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %57 %float_13
+%58 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %58 %float_n11
+%59 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %59 %float_n12
+%60 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %60 %float_13
+%61 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %61 %float_n11
+%62 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %62 %float_n12
+%64 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %64 %float_n13
+%65 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %65 %float_n11
+%66 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %66 %float_n12
+%67 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %67 %float_n13
+%68 = OpExtInst %float %1 Sqrt %float_1_0
+%70 = OpCompositeConstruct %v4float %68 %68 %68 %68
+OpStore %sk_FragColor %70
+%71 = OpExtInst %float %1 Sqrt %float_2
+%72 = OpCompositeConstruct %v4float %71 %71 %71 %71
+OpStore %sk_FragColor %72
+OpStore %sk_FragColor %73
+OpStore %sk_FragColor %75
+OpStore %sk_FragColor %76
+%77 = OpExtInst %float %1 Sqrt %float_6
+%78 = OpCompositeConstruct %v4float %77 %77 %77 %77
+OpStore %sk_FragColor %78
+%79 = OpExtInst %float %1 Sqrt %float_7
+%80 = OpCompositeConstruct %v4float %79 %79 %79 %79
+OpStore %sk_FragColor %80
+%81 = OpExtInst %float %1 Sqrt %float_8
+%82 = OpCompositeConstruct %v4float %81 %81 %81 %81
+OpStore %sk_FragColor %82
+%83 = OpExtInst %float %1 Sqrt %float_9
+%84 = OpCompositeConstruct %v4float %83 %83 %83 %83
+OpStore %sk_FragColor %84
+OpStore %sk_FragColor %85
+OpStore %sk_FragColor %86
+%87 = OpExtInst %float %1 Sqrt %float_12
+%88 = OpCompositeConstruct %v4float %87 %87 %87 %87
+OpStore %sk_FragColor %88
+%89 = OpExtInst %float %1 Sqrt %float_13_0
+%91 = OpCompositeConstruct %v4float %89 %89 %89 %89
+OpStore %sk_FragColor %91
+OpStore %sk_FragColor %92
+OpStore %sk_FragColor %93
+%94 = OpExtInst %float %1 Sqrt %float_16
+%96 = OpCompositeConstruct %v4float %94 %94 %94 %94
+OpStore %sk_FragColor %96
+%97 = OpExtInst %float %1 Sqrt %float_17
+%99 = OpCompositeConstruct %v4float %97 %97 %97 %97
+OpStore %sk_FragColor %99
+OpStore %sk_FragColor %100
+%101 = OpExtInst %float %1 Sqrt %float_19
+%103 = OpCompositeConstruct %v4float %101 %101 %101 %101
+OpStore %sk_FragColor %103
+%104 = OpExtInst %float %1 Sqrt %float_19_5
+%106 = OpCompositeConstruct %v4float %104 %104 %104 %104
+OpStore %sk_FragColor %106
+%107 = OpExtInst %float %1 Sqrt %float_20
+%109 = OpCompositeConstruct %v4float %107 %107 %107 %107
+OpStore %sk_FragColor %109
+%110 = OpExtInst %float %1 Sqrt %float_21
+%112 = OpCompositeConstruct %v4float %110 %110 %110 %110
+OpStore %sk_FragColor %112
+%113 = OpExtInst %float %1 Sqrt %float_22
+%115 = OpCompositeConstruct %v4float %113 %113 %113 %113
+OpStore %sk_FragColor %115
+%116 = OpExtInst %float %1 Sqrt %float_23
+%118 = OpCompositeConstruct %v4float %116 %116 %116 %116
+OpStore %sk_FragColor %118
+%119 = OpExtInst %float %1 Sqrt %float_24
+%121 = OpCompositeConstruct %v4float %119 %119 %119 %119
+OpStore %sk_FragColor %121
+%122 = OpLoad %v4float %sk_FragColor
+%124 = OpFAdd %v4float %122 %123
+OpStore %sk_FragColor %124
+%125 = OpLoad %v4float %sk_FragColor
+%127 = OpFSub %v4float %125 %126
+OpStore %sk_FragColor %127
+%128 = OpLoad %v4float %sk_FragColor
+%131 = OpFMul %v4float %128 %129
+OpStore %sk_FragColor %131
+%132 = OpLoad %v4float %sk_FragColor
+%134 = OpFDiv %v4float %132 %133
+OpStore %sk_FragColor %134
+%139 = OpAccessChain %_ptr_Function_int %_0_result %int_0
+OpStore %139 %int_2
+OpStore %_0_result %141
+OpStore %_0_result %146
+OpStore %_0_result %147
+OpStore %_0_result %150
+%153 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %153 %float_6_0
+%154 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %154 %float_1
+%155 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %155 %float_n2
+%156 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %156 %float_3_0
+%157 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %157 %float_4_0
+%158 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %158 %float_n5
+%159 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %159 %float_6_0
+%160 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %160 %float_7_0
+%161 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %161 %float_n8
+%162 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %162 %float_9_0
+%163 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0
+OpStore %163 %float_n10
+%165 = OpExtInst %float %1 Sqrt %float_1_0
+%164 = OpConvertFToS %int %165
+%166 = OpCompositeConstruct %v4int %164 %164 %164 %164
+OpStore %_0_result %166
+%168 = OpExtInst %float %1 Sqrt %float_2
+%167 = OpConvertFToS %int %168
+%169 = OpCompositeConstruct %v4int %167 %167 %167 %167
+OpStore %_0_result %169
+OpStore %_0_result %170
+OpStore %_0_result %171
+OpStore %_0_result %172
+%174 = OpExtInst %float %1 Sqrt %float_6
+%173 = OpConvertFToS %int %174
+%175 = OpCompositeConstruct %v4int %173 %173 %173 %173
+OpStore %_0_result %175
+%177 = OpExtInst %float %1 Sqrt %float_7
+%176 = OpConvertFToS %int %177
+%178 = OpCompositeConstruct %v4int %176 %176 %176 %176
+OpStore %_0_result %178
+%180 = OpExtInst %float %1 Sqrt %float_8
+%179 = OpConvertFToS %int %180
+%181 = OpCompositeConstruct %v4int %179 %179 %179 %179
+OpStore %_0_result %181
+%183 = OpExtInst %float %1 Sqrt %float_9
+%182 = OpConvertFToS %int %183
+%184 = OpCompositeConstruct %v4int %182 %182 %182 %182
+OpStore %_0_result %184
+OpStore %_0_result %185
+OpStore %_0_result %186
+%188 = OpExtInst %float %1 Sqrt %float_12
+%187 = OpConvertFToS %int %188
+%189 = OpCompositeConstruct %v4int %187 %187 %187 %187
+OpStore %_0_result %189
+%191 = OpExtInst %float %1 Sqrt %float_13_0
+%190 = OpConvertFToS %int %191
+%192 = OpCompositeConstruct %v4int %190 %190 %190 %190
+OpStore %_0_result %192
+OpStore %_0_result %193
+OpStore %_0_result %194
+%196 = OpExtInst %float %1 Sqrt %float_16
+%195 = OpConvertFToS %int %196
+%197 = OpCompositeConstruct %v4int %195 %195 %195 %195
+OpStore %_0_result %197
+%199 = OpExtInst %float %1 Sqrt %float_17
+%198 = OpConvertFToS %int %199
+%200 = OpCompositeConstruct %v4int %198 %198 %198 %198
+OpStore %_0_result %200
+OpStore %_0_result %201
+%203 = OpExtInst %float %1 Sqrt %float_19
+%202 = OpConvertFToS %int %203
+%204 = OpCompositeConstruct %v4int %202 %202 %202 %202
+OpStore %_0_result %204
+%206 = OpExtInst %float %1 Sqrt %float_19_5
+%205 = OpConvertFToS %int %206
+%207 = OpCompositeConstruct %v4int %205 %205 %205 %205
+OpStore %_0_result %207
+%209 = OpExtInst %float %1 Sqrt %float_20
+%208 = OpConvertFToS %int %209
+%210 = OpCompositeConstruct %v4int %208 %208 %208 %208
+OpStore %_0_result %210
+%212 = OpExtInst %float %1 Sqrt %float_21
+%211 = OpConvertFToS %int %212
+%213 = OpCompositeConstruct %v4int %211 %211 %211 %211
+OpStore %_0_result %213
+%215 = OpExtInst %float %1 Sqrt %float_22
+%214 = OpConvertFToS %int %215
+%216 = OpCompositeConstruct %v4int %214 %214 %214 %214
+OpStore %_0_result %216
+%218 = OpExtInst %float %1 Sqrt %float_23
+%217 = OpConvertFToS %int %218
+%219 = OpCompositeConstruct %v4int %217 %217 %217 %217
+OpStore %_0_result %219
+%221 = OpExtInst %float %1 Sqrt %float_24
+%220 = OpConvertFToS %int %221
+%222 = OpCompositeConstruct %v4int %220 %220 %220 %220
+OpStore %_0_result %222
+%223 = OpLoad %v4int %_0_result
+%226 = OpIAdd %v4int %223 %224
+OpStore %_0_result %226
+%227 = OpLoad %v4int %_0_result
+%229 = OpISub %v4int %227 %228
+OpStore %_0_result %229
+%230 = OpLoad %v4int %_0_result
+%232 = OpIMul %v4int %230 %231
+OpStore %_0_result %232
+%233 = OpLoad %v4int %_0_result
+%235 = OpSDiv %v4int %233 %234
+OpStore %_0_result %235
+%236 = OpLoad %v4int %_0_result
+%237 = OpCompositeExtract %int %236 0
+%238 = OpConvertSToF %float %237
+%239 = OpCompositeExtract %int %236 1
+%240 = OpConvertSToF %float %239
+%241 = OpCompositeExtract %int %236 2
+%242 = OpConvertSToF %float %241
+%243 = OpCompositeExtract %int %236 3
+%244 = OpConvertSToF %float %243
+%245 = OpCompositeConstruct %v4float %238 %240 %242 %244
+OpStore %sk_FragColor %245
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/VertexID.asm.frag b/tests/sksl/shared/golden/VertexID.asm.frag
new file mode 100644
index 0000000..8659720
--- /dev/null
+++ b/tests/sksl/shared/golden/VertexID.asm.frag
@@ -0,0 +1,21 @@
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %sk_VertexID %id
+OpName %sk_VertexID "sk_VertexID"
+OpName %id "id"
+OpName %main "main"
+OpDecorate %sk_VertexID BuiltIn VertexIndex
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%sk_VertexID = OpVariable %_ptr_Input_int Input
+%_ptr_Output_int = OpTypePointer Output %int
+%id = OpVariable %_ptr_Output_int Output
+%void = OpTypeVoid
+%9 = OpTypeFunction %void
+%main = OpFunction %void None %9
+%10 = OpLabel
+%11 = OpLoad %int %sk_VertexID
+OpStore %id %11
+OpReturn
+OpFunctionEnd
diff --git a/tests/sksl/shared/golden/Width.asm.frag b/tests/sksl/shared/golden/Width.asm.frag
new file mode 100644
index 0000000..642860c
--- /dev/null
+++ b/tests/sksl/shared/golden/Width.asm.frag
@@ -0,0 +1,2 @@
+### Compilation failed:
+