Revert "Add most important intrinsics to the interpreter"

This reverts commit 838007f1ffd6557d6887ebd1ea8903ede5d8c540.

Reason for revert: Significant RAM regression detected by Chrome.

Original change's description:
> Add most important intrinsics to the interpreter
> 
> Started with component-wise comparison and mix builtins.
> 
> Implemented min, max, clamp, and saturate using those.
> Moved dot to SkSL as well. Because we now have builtins
> implemented using other (intrinsic) builtins, I had to
> split the include file in two - this lets the intrinsics
> be marked so we can call them from the second phase of
> builtins that are written in SkSL.
> 
> Given that the comparisons and kSelect are now used by
> these, I added vector versions of those instructions.
> I also switched the kSelect args to match GLSL mix(),
> mostly so the logic of mapping intrinsic arguments to
> instruction register args remains simple.
> 
> Inspired by the (never-landed):
> https://skia-review.googlesource.com/c/skia/+/230739
> 
> Change-Id: Iecb0a7e8dc633625ff2cada7fb962bf2137fa881
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272516
> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
> Commit-Queue: Brian Osman <brianosman@google.com>

TBR=bsalomon@google.com,brianosman@google.com,ethannicholas@google.com,reed@google.com

Change-Id: I931a0ccc254b55339c9b077543a0daaf28146b19
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273800
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLByteCode.h b/src/sksl/SkSLByteCode.h
index 2d7df2e..d5a38e2 100644
--- a/src/sksl/SkSLByteCode.h
+++ b/src/sksl/SkSLByteCode.h
@@ -124,37 +124,37 @@
         // uint8_t argumentSize
         kCallExternal,
         // Register target, Register src1, Register src2
-        V(kCompareEQF),
+        kCompareEQF,
         // Register target, Register src1, Register src2
-        V(kCompareEQI),
+        kCompareEQI,
         // Register target, Register src1, Register src2
-        V(kCompareNEQF),
+        kCompareNEQF,
         // Register target, Register src1, Register src2
-        V(kCompareNEQI),
+        kCompareNEQI,
         // Register target, Register src1, Register src2
-        V(kCompareGTF),
+        kCompareGTF,
         // Register target, Register src1, Register src2
-        V(kCompareGTS),
+        kCompareGTS,
         // Register target, Register src1, Register src2
-        V(kCompareGTU),
+        kCompareGTU,
         // Register target, Register src1, Register src2
-        V(kCompareGTEQF),
+        kCompareGTEQF,
         // Register target, Register src1, Register src2
-        V(kCompareGTEQS),
+        kCompareGTEQS,
         // Register target, Register src1, Register src2
-        V(kCompareGTEQU),
+        kCompareGTEQU,
         // Register target, Register src1, Register src2
-        V(kCompareLTF),
+        kCompareLTF,
         // Register target, Register src1, Register src2
-        V(kCompareLTS),
+        kCompareLTS,
         // Register target, Register src1, Register src2
-        V(kCompareLTU),
+        kCompareLTU,
         // Register target, Register src1, Register src2
-        V(kCompareLTEQF),
+        kCompareLTEQF,
         // Register target, Register src1, Register src2
-        V(kCompareLTEQS),
+        kCompareLTEQS,
         // Register target, Register src1, Register src2
-        V(kCompareLTEQU),
+        kCompareLTEQU,
         // no parameters
         kContinue,
         // Register target, Register src
@@ -248,8 +248,8 @@
         kReturnValue,
         // Register target, Register src, uint8_t columns, uint8_t rows
         kScalarToMatrix,
-        // Register target, Register ifFalse, Register ifTrue, Register test (To match GLSL mix)
-        V(kSelect),
+        // Register target, Register test, Register ifTrue, Register ifFalse
+        kSelect,
         // Register target, Register src, uint8_t count
         kShiftLeft,
         // Register target, Register src, uint8_t count
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index b8cd2ac..3a65d8c 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -14,37 +14,14 @@
     : INHERITED(program, errors, nullptr)
     , fOutput(output)
     , fIntrinsics {
-        // "Normal" intrinsics are all $genType f($genType [, $genType...])
-        // and all map to a single instruction (possibly with a vector version)
-        { "cos",     { ByteCode::Instruction::kCos,    false } },
-        { "mix",     { ByteCode::Instruction::kSelect, true  } },
-        { "not",     { ByteCode::Instruction::kNot,    false } },
-        { "sin",     { ByteCode::Instruction::kSin,    false } },
-        { "sqrt",    { ByteCode::Instruction::kSqrt,   false } },
-        { "tan",     { ByteCode::Instruction::kTan,    false } },
-
-        { "lessThan",         { ByteCode::Instruction::kCompareLTF,
-                                ByteCode::Instruction::kCompareLTS,
-                                ByteCode::Instruction::kCompareLTU, true } },
-        { "lessThanEqual",    { ByteCode::Instruction::kCompareLTEQF,
-                                ByteCode::Instruction::kCompareLTEQS,
-                                ByteCode::Instruction::kCompareLTEQU, true } },
-        { "greaterThan",      { ByteCode::Instruction::kCompareGTF,
-                                ByteCode::Instruction::kCompareGTS,
-                                ByteCode::Instruction::kCompareGTU, true } },
-        { "greaterThanEqual", { ByteCode::Instruction::kCompareGTEQF,
-                                ByteCode::Instruction::kCompareGTEQS,
-                                ByteCode::Instruction::kCompareGTEQU, true } },
-        { "equal",            { ByteCode::Instruction::kCompareEQF,
-                                ByteCode::Instruction::kCompareEQI,
-                                ByteCode::Instruction::kCompareEQI, true } },
-        { "notEqual",         { ByteCode::Instruction::kCompareNEQF,
-                                ByteCode::Instruction::kCompareNEQI,
-                                ByteCode::Instruction::kCompareNEQI, true } },
+        // "Normal" intrinsics are all $genType f($genType), mapped to a single instruction
+        { "cos",     ByteCode::Instruction::kCos },
+        { "sin",     ByteCode::Instruction::kSin },
+        { "sqrt",    ByteCode::Instruction::kSqrt },
+        { "tan",     ByteCode::Instruction::kTan },
 
         // Special intrinsics have other signatures, or non-standard code-gen
-        { "all",     SpecialIntrinsic::kAll },
-        { "any",     SpecialIntrinsic::kAny },
+        { "dot",     SpecialIntrinsic::kDot },
         { "inverse", SpecialIntrinsic::kInverse },
         { "print",   SpecialIntrinsic::kPrint },
     } {}
@@ -937,22 +914,33 @@
                                            ByteCode::Register result) {
     if (intrinsic.fIsSpecial) {
         switch (intrinsic.fValue.fSpecial) {
-            case SpecialIntrinsic::kAll:
-            case SpecialIntrinsic::kAny: {
-                SkASSERT(c.fArguments.size() == 1);
+            case SpecialIntrinsic::kDot: {
+                SkASSERT(c.fArguments.size() == 2);
                 int count = SlotCount(c.fArguments[0]->fType);
-                SkASSERT(count > 1);
-                // Fold a bvec down to a single bool:
-                ByteCode::Register arg = this->next(count);
-                ByteCode::Instruction inst = intrinsic.fValue.fSpecial == SpecialIntrinsic::kAll
-                                                        ? ByteCode::Instruction::kAnd
-                                                        : ByteCode::Instruction::kOr;
-                this->writeExpression(*c.fArguments[0], arg);
+                ByteCode::Register left = this->next(count);
+                this->writeExpression(*c.fArguments[0], left);
+                ByteCode::Register right = this->next(count);
+                this->writeExpression(*c.fArguments[1], right);
+                ByteCode::Register product = this->next(count);
+                this->writeTypedInstruction(c.fType,
+                                            ByteCode::Instruction::kMultiplyIN,
+                                            ByteCode::Instruction::kMultiplyIN,
+                                            ByteCode::Instruction::kMultiplyFN);
+                this->write((uint8_t) count);
+                this->write(product);
+                this->write(left);
+                this->write(right);
+                ByteCode::Register total = product;
                 for (int i = 1; i < count; ++i) {
-                    this->write(inst);
-                    this->write(result);
-                    this->write(i == 1 ? arg : result);
-                    this->write(arg + i);
+                    this->writeTypedInstruction(c.fType,
+                                                ByteCode::Instruction::kAddI,
+                                                ByteCode::Instruction::kAddI,
+                                                ByteCode::Instruction::kAddF);
+                    ByteCode::Register sum = i == count - 1 ? result : this->next(1);
+                    this->write(sum);
+                    this->write(total);
+                    this->write(product + i);
+                    total = sum;
                 }
                 break;
             }
@@ -982,7 +970,7 @@
             }
         }
     } else {
-        uint8_t count = (uint8_t) SlotCount(c.fType);
+        int count = SlotCount(c.fType);
         std::vector<ByteCode::Register> argRegs;
         for (const auto& expr : c.fArguments) {
             SkASSERT(SlotCount(expr->fType) == count);
@@ -990,49 +978,21 @@
             this->writeExpression(*expr, reg);
             argRegs.push_back(reg);
         }
-
-        const auto& instructions = intrinsic.fValue.fInstructions;
-        const Type& opType = c.fArguments[0]->fType;
-
-        if (instructions.fUseVector) {
-            if (count == 1) {
-                this->writeTypedInstruction(opType,
-                                            instructions.fFloat,
-                                            instructions.fSigned,
-                                            instructions.fUnsigned);
-            } else {
-                this->writeTypedInstruction(opType,
-                                            VEC(instructions.fFloat),
-                                            VEC(instructions.fSigned),
-                                            VEC(instructions.fUnsigned));
-                this->write(count);
-            }
-            this->write(result);
-            for (ByteCode::Register arg : argRegs) {
-                this->write(arg);
-            }
-        } else {
-            // No vector version of the instruction exists. Emit the scalar instruction N times.
-            for (uint8_t i = 0; i < count; ++i) {
-                this->writeTypedInstruction(opType,
-                                            instructions.fFloat,
-                                            instructions.fSigned,
-                                            instructions.fUnsigned);
+        for (int i = 0; i < count; ++i) {
+            this->write(intrinsic.fValue.fInstruction);
+            if (c.fType.fName != "void") {
                 this->write(result + i);
-                for (ByteCode::Register arg : argRegs) {
-                    this->write(arg + i);
-                }
+            }
+            for (ByteCode::Register arg : argRegs) {
+                this->write(arg + i);
             }
         }
     }
 }
 
 void ByteCodeGenerator::writeFunctionCall(const FunctionCall& c, ByteCode::Register result) {
-    // 'mix' is present as both a "pure" intrinsic (fDefined == false), and an SkSL implementation
-    // in the pre-parsed include files (fDefined == true), depending on argument types. We only
-    // send calls to the former through the intrinsic path here.
     auto found = fIntrinsics.find(c.fFunction.fName);
-    if (found != fIntrinsics.end() && !c.fFunction.fDefined) {
+    if (found != fIntrinsics.end()) {
         return this->writeIntrinsicCall(c, found->second, result);
     }
     int argCount = c.fArguments.size();
@@ -1202,9 +1162,9 @@
     for (int i = 0; i < count; ++i) {
         this->write(ByteCode::Instruction::kSelect);
         this->write(result + i);
-        this->write(ifFalse + i);
-        this->write(ifTrue + i);
         this->write(test);
+        this->write(ifTrue + i);
+        this->write(ifFalse + i);
     }
 }
 
diff --git a/src/sksl/SkSLByteCodeGenerator.h b/src/sksl/SkSLByteCodeGenerator.h
index 15ac882..9afe1a5 100644
--- a/src/sksl/SkSLByteCodeGenerator.h
+++ b/src/sksl/SkSLByteCodeGenerator.h
@@ -61,21 +61,15 @@
 private:
     // Intrinsics which do not simply map to a single opcode
     enum class SpecialIntrinsic {
-        kAll,
-        kAny,
+        kDot,
         kInverse,
         kPrint,
     };
 
     struct Intrinsic {
-        Intrinsic(ByteCode::Instruction i, bool useVector)
+        Intrinsic(ByteCode::Instruction instruction)
             : fIsSpecial(false)
-            , fValue(i, i, i, useVector) {}
-
-        Intrinsic(ByteCode::Instruction f, ByteCode::Instruction s, ByteCode::Instruction u,
-                  bool useVector)
-            : fIsSpecial(false)
-            , fValue(f, s, u, useVector) {}
+            , fValue(instruction) {}
 
         Intrinsic(SpecialIntrinsic special)
             : fIsSpecial(true)
@@ -84,21 +78,13 @@
         bool fIsSpecial;
 
         union Value {
-            Value(ByteCode::Instruction f, ByteCode::Instruction s, ByteCode::Instruction u,
-                  bool useVector)
-                : fInstructions{ f, s, u, useVector } {}
+            Value(ByteCode::Instruction instruction)
+                : fInstruction(instruction) {}
 
             Value(SpecialIntrinsic special)
                 : fSpecial(special) {}
 
-            struct {
-                ByteCode::Instruction fFloat;
-                ByteCode::Instruction fSigned;
-                ByteCode::Instruction fUnsigned;
-
-                bool fUseVector;
-            } fInstructions;
-
+            ByteCode::Instruction fInstruction;
             SpecialIntrinsic fSpecial;
         } fValue;
     };
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index ab31425..92c0c03 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -54,10 +54,6 @@
 #include "sksl_interp.inc"
 ;
 
-static const char* SKSL_INTERP_INLINE_INCLUDE =
-#include "sksl_interp_inline.inc"
-;
-
 static const char* SKSL_VERT_INCLUDE =
 #include "sksl_vert.inc"
 ;
@@ -287,13 +283,9 @@
     this->processIncludeFile(Program::kPipelineStage_Kind, SKSL_PIPELINE_INCLUDE,
                              strlen(SKSL_PIPELINE_INCLUDE), fGpuSymbolTable, &fPipelineInclude,
                              &fPipelineSymbolTable);
-
     this->processIncludeFile(Program::kGeneric_Kind, SKSL_INTERP_INCLUDE,
                              strlen(SKSL_INTERP_INCLUDE), symbols, &fInterpreterInclude,
                              &fInterpreterSymbolTable);
-    this->processIncludeFile(Program::kGeneric_Kind, SKSL_INTERP_INLINE_INCLUDE,
-                             strlen(SKSL_INTERP_INLINE_INCLUDE), std::move(fInterpreterSymbolTable),
-                             &fInterpreterInclude, &fInterpreterSymbolTable);
     grab_intrinsics(&fInterpreterInclude, &fInterpreterIntrinsics);
     // need to hang on to the source so that FunctionDefinition.fSource pointers in this file
     // remain valid
diff --git a/src/sksl/SkSLInterpreter.h b/src/sksl/SkSLInterpreter.h
index a5cf844..5e4db17 100644
--- a/src/sksl/SkSLInterpreter.h
+++ b/src/sksl/SkSLInterpreter.h
@@ -381,22 +381,22 @@
             DISASSEMBLE_VECTOR_BINARY(kAddF, "addF")
             DISASSEMBLE_VECTOR_BINARY(kAddI, "addI")
             DISASSEMBLE_BINARY(kAnd, "and")
-            DISASSEMBLE_VECTOR_BINARY(kCompareEQF, "compare eqF")
-            DISASSEMBLE_VECTOR_BINARY(kCompareEQI, "compare eqI")
-            DISASSEMBLE_VECTOR_BINARY(kCompareNEQF, "compare neqF")
-            DISASSEMBLE_VECTOR_BINARY(kCompareNEQI, "compare neqI")
-            DISASSEMBLE_VECTOR_BINARY(kCompareGTF, "compare gtF")
-            DISASSEMBLE_VECTOR_BINARY(kCompareGTS, "compare gtS")
-            DISASSEMBLE_VECTOR_BINARY(kCompareGTU, "compare gtU")
-            DISASSEMBLE_VECTOR_BINARY(kCompareGTEQF, "compare gteqF")
-            DISASSEMBLE_VECTOR_BINARY(kCompareGTEQS, "compare gteqS")
-            DISASSEMBLE_VECTOR_BINARY(kCompareGTEQU, "compare gteqU")
-            DISASSEMBLE_VECTOR_BINARY(kCompareLTF, "compare ltF")
-            DISASSEMBLE_VECTOR_BINARY(kCompareLTS, "compare ltS")
-            DISASSEMBLE_VECTOR_BINARY(kCompareLTU, "compare ltU")
-            DISASSEMBLE_VECTOR_BINARY(kCompareLTEQF, "compare lteqF")
-            DISASSEMBLE_VECTOR_BINARY(kCompareLTEQS, "compare lteqS")
-            DISASSEMBLE_VECTOR_BINARY(kCompareLTEQU, "compare lteqU")
+            DISASSEMBLE_BINARY(kCompareEQF, "compare eqF")
+            DISASSEMBLE_BINARY(kCompareEQI, "compare eqI")
+            DISASSEMBLE_BINARY(kCompareNEQF, "compare neqF")
+            DISASSEMBLE_BINARY(kCompareNEQI, "compare neqI")
+            DISASSEMBLE_BINARY(kCompareGTF, "compare gtF")
+            DISASSEMBLE_BINARY(kCompareGTS, "compare gtS")
+            DISASSEMBLE_BINARY(kCompareGTU, "compare gtU")
+            DISASSEMBLE_BINARY(kCompareGTEQF, "compare gteqF")
+            DISASSEMBLE_BINARY(kCompareGTEQS, "compare gteqS")
+            DISASSEMBLE_BINARY(kCompareGTEQU, "compare gteqU")
+            DISASSEMBLE_BINARY(kCompareLTF, "compare ltF")
+            DISASSEMBLE_BINARY(kCompareLTS, "compare ltS")
+            DISASSEMBLE_BINARY(kCompareLTU, "compare ltU")
+            DISASSEMBLE_BINARY(kCompareLTEQF, "compare lteqF")
+            DISASSEMBLE_BINARY(kCompareLTEQS, "compare lteqS")
+            DISASSEMBLE_BINARY(kCompareLTEQU, "compare lteqU")
             DISASSEMBLE_VECTOR_BINARY(kSubtractF, "subF")
             DISASSEMBLE_VECTOR_BINARY(kSubtractI, "subI")
             DISASSEMBLE_VECTOR_BINARY(kDivideF, "divF")
@@ -553,23 +553,13 @@
             }
             case ByteCode::Instruction::kSelect: {
                 ByteCode::Register target = read<ByteCode::Register>(ip);
-                ByteCode::Register src2 = read<ByteCode::Register>(ip);
-                ByteCode::Register src1 = read<ByteCode::Register>(ip);
                 ByteCode::Register test = read<ByteCode::Register>(ip);
+                ByteCode::Register src1 = read<ByteCode::Register>(ip);
+                ByteCode::Register src2 = read<ByteCode::Register>(ip);
                 printf("select $%d, $%d, $%d -> %d\n", test.fIndex, src1.fIndex, src2.fIndex,
                        target.fIndex);
                 break;
             }
-            case ByteCode::Instruction::kSelectN: {
-                uint8_t count = read<uint8_t>(ip);
-                ByteCode::Register target = read<ByteCode::Register>(ip);
-                ByteCode::Register src2 = read<ByteCode::Register>(ip);
-                ByteCode::Register src1 = read<ByteCode::Register>(ip);
-                ByteCode::Register test = read<ByteCode::Register>(ip);
-                printf("select%d $%d, $%d, $%d -> %d\n", count, test.fIndex, src1.fIndex,
-                       src2.fIndex, target.fIndex);
-                break;
-            }
             DISASSEMBLE_BINARY(kShiftLeft, "shiftLeft")
             DISASSEMBLE_BINARY(kShiftRightS, "shiftRightS")
             DISASSEMBLE_BINARY(kShiftRightU, "shiftRightU")
@@ -755,37 +745,21 @@
             &&kCall,
             &&kCallExternal,
             &&kCompareEQF,
-            &&kCompareEQFN,
             &&kCompareEQI,
-            &&kCompareEQIN,
             &&kCompareNEQF,
-            &&kCompareNEQFN,
             &&kCompareNEQI,
-            &&kCompareNEQIN,
             &&kCompareGTF,
-            &&kCompareGTFN,
             &&kCompareGTS,
-            &&kCompareGTSN,
             &&kCompareGTU,
-            &&kCompareGTUN,
             &&kCompareGTEQF,
-            &&kCompareGTEQFN,
             &&kCompareGTEQS,
-            &&kCompareGTEQSN,
             &&kCompareGTEQU,
-            &&kCompareGTEQUN,
             &&kCompareLTF,
-            &&kCompareLTFN,
             &&kCompareLTS,
-            &&kCompareLTSN,
             &&kCompareLTU,
-            &&kCompareLTUN,
             &&kCompareLTEQF,
-            &&kCompareLTEQFN,
             &&kCompareLTEQS,
-            &&kCompareLTEQSN,
             &&kCompareLTEQU,
-            &&kCompareLTEQUN,
             &&kContinue,
             &&kCopy,
             &&kCos,
@@ -842,7 +816,6 @@
             &&kReturnValue,
             &&kScalarToMatrix,
             &&kSelect,
-            &&kSelectN,
             &&kShiftLeft,
             &&kShiftRightS,
             &&kShiftRightU,
@@ -883,37 +856,21 @@
         CHECK_LABEL(kCall);
         CHECK_LABEL(kCallExternal);
         CHECK_LABEL(kCompareEQF);
-        CHECK_LABEL(kCompareEQFN);
         CHECK_LABEL(kCompareEQI);
-        CHECK_LABEL(kCompareEQIN);
         CHECK_LABEL(kCompareNEQF);
-        CHECK_LABEL(kCompareNEQFN);
         CHECK_LABEL(kCompareNEQI);
-        CHECK_LABEL(kCompareNEQIN);
         CHECK_LABEL(kCompareGTF);
-        CHECK_LABEL(kCompareGTFN);
         CHECK_LABEL(kCompareGTS);
-        CHECK_LABEL(kCompareGTSN);
         CHECK_LABEL(kCompareGTU);
-        CHECK_LABEL(kCompareGTUN);
         CHECK_LABEL(kCompareGTEQF);
-        CHECK_LABEL(kCompareGTEQFN);
         CHECK_LABEL(kCompareGTEQS);
-        CHECK_LABEL(kCompareGTEQSN);
         CHECK_LABEL(kCompareGTEQU);
-        CHECK_LABEL(kCompareGTEQUN);
         CHECK_LABEL(kCompareLTF);
-        CHECK_LABEL(kCompareLTFN);
         CHECK_LABEL(kCompareLTS);
-        CHECK_LABEL(kCompareLTSN);
         CHECK_LABEL(kCompareLTU);
-        CHECK_LABEL(kCompareLTUN);
         CHECK_LABEL(kCompareLTEQF);
-        CHECK_LABEL(kCompareLTEQFN);
         CHECK_LABEL(kCompareLTEQS);
-        CHECK_LABEL(kCompareLTEQSN);
         CHECK_LABEL(kCompareLTEQU);
-        CHECK_LABEL(kCompareLTEQUN);
         CHECK_LABEL(kContinue);
         CHECK_LABEL(kCopy);
         CHECK_LABEL(kCos);
@@ -970,7 +927,6 @@
         CHECK_LABEL(kReturnValue);
         CHECK_LABEL(kScalarToMatrix);
         CHECK_LABEL(kSelect);
-        CHECK_LABEL(kSelectN);
         CHECK_LABEL(kShiftLeft);
         CHECK_LABEL(kShiftRightS);
         CHECK_LABEL(kShiftRightU);
@@ -1025,22 +981,22 @@
                 VECTOR_BINARY_OP(kAddF, fFloat, fFloat, +)
                 VECTOR_BINARY_OP(kAddI, fInt, fInt, +)
                 BINARY_OP(kAnd, fInt, fInt, &)
-                VECTOR_BINARY_OP(kCompareEQF, fFloat, fInt, ==)
-                VECTOR_BINARY_OP(kCompareEQI, fInt, fInt, ==)
-                VECTOR_BINARY_OP(kCompareNEQF, fFloat, fInt, !=)
-                VECTOR_BINARY_OP(kCompareNEQI, fInt, fInt, !=)
-                VECTOR_BINARY_OP(kCompareGTF, fFloat, fInt, >)
-                VECTOR_BINARY_OP(kCompareGTS, fInt, fInt, >)
-                VECTOR_BINARY_OP(kCompareGTU, fUInt, fUInt, >)
-                VECTOR_BINARY_OP(kCompareGTEQF, fFloat, fInt, >=)
-                VECTOR_BINARY_OP(kCompareGTEQS, fInt, fInt, >=)
-                VECTOR_BINARY_OP(kCompareGTEQU, fUInt, fUInt, >=)
-                VECTOR_BINARY_OP(kCompareLTF, fFloat, fInt, <)
-                VECTOR_BINARY_OP(kCompareLTS, fInt, fInt, <)
-                VECTOR_BINARY_OP(kCompareLTU, fUInt, fUInt, <)
-                VECTOR_BINARY_OP(kCompareLTEQF, fFloat, fInt, <=)
-                VECTOR_BINARY_OP(kCompareLTEQS, fInt, fInt, <=)
-                VECTOR_BINARY_OP(kCompareLTEQU, fUInt, fUInt, <=)
+                BINARY_OP(kCompareEQF, fFloat, fInt, ==)
+                BINARY_OP(kCompareEQI, fInt, fInt, ==)
+                BINARY_OP(kCompareNEQF, fFloat, fInt, !=)
+                BINARY_OP(kCompareNEQI, fInt, fInt, !=)
+                BINARY_OP(kCompareGTF, fFloat, fInt, >)
+                BINARY_OP(kCompareGTS, fInt, fInt, >)
+                BINARY_OP(kCompareGTU, fUInt, fUInt, >)
+                BINARY_OP(kCompareGTEQF, fFloat, fInt, >=)
+                BINARY_OP(kCompareGTEQS, fInt, fInt, >=)
+                BINARY_OP(kCompareGTEQU, fUInt, fUInt, >=)
+                BINARY_OP(kCompareLTF, fFloat, fInt, <)
+                BINARY_OP(kCompareLTS, fInt, fInt, <)
+                BINARY_OP(kCompareLTU, fUInt, fUInt, <)
+                BINARY_OP(kCompareLTEQF, fFloat, fInt, <=)
+                BINARY_OP(kCompareLTEQS, fInt, fInt, <=)
+                BINARY_OP(kCompareLTEQU, fUInt, fUInt, <=)
                 VECTOR_BINARY_OP(kSubtractF, fFloat, fFloat, -)
                 VECTOR_BINARY_OP(kSubtractI, fInt, fInt, -)
                 VECTOR_BINARY_OP(kDivideF, fFloat, fFloat, /)
@@ -1513,28 +1469,14 @@
                 }
                 LABEL(kSelect) {
                     ByteCode::Register target = read<ByteCode::Register>(&ip);
-                    ByteCode::Register src2 = read<ByteCode::Register>(&ip);
-                    ByteCode::Register src1 = read<ByteCode::Register>(&ip);
                     ByteCode::Register test = read<ByteCode::Register>(&ip);
+                    ByteCode::Register src1 = read<ByteCode::Register>(&ip);
+                    ByteCode::Register src2 = read<ByteCode::Register>(&ip);
                     fRegisters[target.fIndex] = skvx::if_then_else(fRegisters[test.fIndex].fInt,
                                                                    fRegisters[src1.fIndex].fFloat,
                                                                    fRegisters[src2.fIndex].fFloat);
                     NEXT();
                 }
-                LABEL(kSelectN) {
-                    uint8_t count = read<uint8_t>(&ip);
-                    ByteCode::Register target = read<ByteCode::Register>(&ip);
-                    ByteCode::Register src2 = read<ByteCode::Register>(&ip);
-                    ByteCode::Register src1 = read<ByteCode::Register>(&ip);
-                    ByteCode::Register test = read<ByteCode::Register>(&ip);
-                    for (int i = 0; i < count; ++i) {
-                        fRegisters[target.fIndex + i] =
-                                skvx::if_then_else(fRegisters[test.fIndex + i].fInt,
-                                                   fRegisters[src1.fIndex + i].fFloat,
-                                                   fRegisters[src2.fIndex + i].fFloat);
-                    }
-                    NEXT();
-                }
                 LABEL(kShiftLeft) {
                     ByteCode::Register target = read<ByteCode::Register>(&ip);
                     ByteCode::Register src = read<ByteCode::Register>(&ip);
diff --git a/src/sksl/sksl_interp.inc b/src/sksl/sksl_interp.inc
index 140526f..e576f9f 100644
--- a/src/sksl/sksl_interp.inc
+++ b/src/sksl/sksl_interp.inc
@@ -4,6 +4,7 @@
 
 $genType cos($genType y);
 $genHType cos($genHType y);
+float dot($genType x, $genType y);
 float2x2 inverse(float2x2 m);
 float3x3 inverse(float3x3 m);
 float4x4 inverse(float4x4 m);
@@ -14,40 +15,41 @@
 $genType tan($genType x);
 $genHType tan($genHType x);
 
-$genType  mix($genType  x, $genType  y, $genBType a);
-$genHType mix($genHType x, $genHType y, $genBType a);
-$genIType mix($genIType x, $genIType y, $genBType a);
-$genBType mix($genBType x, $genBType y, $genBType a);
+float  degrees(float  rad) { return rad * 57.2957795; }
+float2 degrees(float2 rad) { return rad * 57.2957795; }
+float3 degrees(float3 rad) { return rad * 57.2957795; }
+float4 degrees(float4 rad) { return rad * 57.2957795; }
 
-$bvec lessThan($vec  x, $vec  y);
-$bvec lessThan($hvec x, $hvec y);
-$bvec lessThan($ivec x, $ivec y);
-$bvec lessThan($uvec x, $uvec y);
-$bvec lessThanEqual($vec  x, $vec  y);
-$bvec lessThanEqual($hvec x, $hvec y);
-$bvec lessThanEqual($ivec x, $ivec y);
-$bvec lessThanEqual($uvec x, $uvec y);
-$bvec greaterThan($vec  x, $vec  y);
-$bvec greaterThan($hvec x, $hvec y);
-$bvec greaterThan($ivec x, $ivec y);
-$bvec greaterThan($uvec x, $uvec y);
-$bvec greaterThanEqual($vec  x, $vec  y);
-$bvec greaterThanEqual($hvec x, $hvec y);
-$bvec greaterThanEqual($ivec x, $ivec y);
-$bvec greaterThanEqual($uvec x, $uvec y);
-$bvec equal($vec  x, $vec  y);
-$bvec equal($hvec x, $hvec y);
-$bvec equal($ivec x, $ivec y);
-$bvec equal($uvec x, $uvec y);
-$bvec equal($bvec x, $bvec y);
-$bvec notEqual($vec  x, $vec  y);
-$bvec notEqual($hvec x, $hvec y);
-$bvec notEqual($ivec x, $ivec y);
-$bvec notEqual($uvec x, $uvec y);
-$bvec notEqual($bvec x, $bvec y);
+float  radians(float  deg) { return deg * 0.0174532925; }
+float2 radians(float2 deg) { return deg * 0.0174532925; }
+float3 radians(float3 deg) { return deg * 0.0174532925; }
+float4 radians(float4 deg) { return deg * 0.0174532925; }
 
-bool  any($bvec x);
-bool  all($bvec x);
-$bvec not($bvec x);
+float length(float2 v) { return sqrt(dot(v, v)); }
+float length(float3 v) { return sqrt(dot(v, v)); }
+float length(float4 v) { return sqrt(dot(v, v)); }
+
+float distance(float2 a, float2 b) { return length(a - b); }
+float distance(float3 a, float3 b) { return length(a - b); }
+float distance(float4 a, float4 b) { return length(a - b); }
+
+float2 normalize(float2 v) { return v / length(v); }
+float3 normalize(float3 v) { return v / length(v); }
+float4 normalize(float4 v) { return v / length(v); }
+
+float  mix(float  x, float  y, float t) { return x * (1 - t) + y * t; }
+float2 mix(float2 x, float2 y, float t) { return x * (1 - t) + y * t; }
+float3 mix(float3 x, float3 y, float t) { return x * (1 - t) + y * t; }
+float4 mix(float4 x, float4 y, float t) { return x * (1 - t) + y * t; }
+
+float2 mix(float2 x, float2 y, float2 t) { return x * (1 - t) + y * t; }
+float3 mix(float3 x, float3 y, float3 t) { return x * (1 - t) + y * t; }
+float4 mix(float4 x, float4 y, float4 t) { return x * (1 - t) + y * t; }
+
+float3 cross(float3 a, float3 b) {
+    return float3(a.y * b.z - a.z * b.y,
+                  a.z * b.x - a.x * b.z,
+                  a.x * b.y - a.y * b.x);
+}
 
 )
diff --git a/src/sksl/sksl_interp_inline.inc b/src/sksl/sksl_interp_inline.inc
deleted file mode 100644
index e23a506..0000000
--- a/src/sksl/sksl_interp_inline.inc
+++ /dev/null
@@ -1,120 +0,0 @@
-STRINGIFY(
-
-float dot(float2 a, float2 b) { return a.x*b.x + a.y*b.y; }
-float dot(float3 a, float3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; }
-float dot(float4 a, float4 b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; }
-
-float  degrees(float  rad) { return rad * 57.2957795; }
-float2 degrees(float2 rad) { return rad * 57.2957795; }
-float3 degrees(float3 rad) { return rad * 57.2957795; }
-float4 degrees(float4 rad) { return rad * 57.2957795; }
-
-float  radians(float  deg) { return deg * 0.0174532925; }
-float2 radians(float2 deg) { return deg * 0.0174532925; }
-float3 radians(float3 deg) { return deg * 0.0174532925; }
-float4 radians(float4 deg) { return deg * 0.0174532925; }
-
-float length(float2 v) { return sqrt(dot(v, v)); }
-float length(float3 v) { return sqrt(dot(v, v)); }
-float length(float4 v) { return sqrt(dot(v, v)); }
-
-float distance(float2 a, float2 b) { return length(a - b); }
-float distance(float3 a, float3 b) { return length(a - b); }
-float distance(float4 a, float4 b) { return length(a - b); }
-
-float2 normalize(float2 v) { return v / length(v); }
-float3 normalize(float3 v) { return v / length(v); }
-float4 normalize(float4 v) { return v / length(v); }
-
-float  mix(float  x, float  y, float t) { return x * (1 - t) + y * t; }
-float2 mix(float2 x, float2 y, float t) { return x * (1 - t) + y * t; }
-float3 mix(float3 x, float3 y, float t) { return x * (1 - t) + y * t; }
-float4 mix(float4 x, float4 y, float t) { return x * (1 - t) + y * t; }
-
-float2 mix(float2 x, float2 y, float2 t) { return x * (1 - t) + y * t; }
-float3 mix(float3 x, float3 y, float3 t) { return x * (1 - t) + y * t; }
-float4 mix(float4 x, float4 y, float4 t) { return x * (1 - t) + y * t; }
-
-float3 cross(float3 a, float3 b) {
-    return float3(a.y * b.z - a.z * b.y,
-                  a.z * b.x - a.x * b.z,
-                  a.x * b.y - a.y * b.x);
-}
-
-float  min(float  x, float  y) { return mix(y, x, x < y); }
-float2 min(float2 x, float2 y) { return mix(y, x, lessThan(x, y)); }
-float3 min(float3 x, float3 y) { return mix(y, x, lessThan(x, y)); }
-float4 min(float4 x, float4 y) { return mix(y, x, lessThan(x, y)); }
-
-float2 min(float2 x, float  y) { return mix(float2(y), x, lessThan(x, float2(y))); }
-float3 min(float3 x, float  y) { return mix(float3(y), x, lessThan(x, float3(y))); }
-float4 min(float4 x, float  y) { return mix(float4(y), x, lessThan(x, float4(y))); }
-
-float  max(float  x, float  y) { return mix(y, x, x > y); }
-float2 max(float2 x, float2 y) { return mix(y, x, greaterThan(x, y)); }
-float3 max(float3 x, float3 y) { return mix(y, x, greaterThan(x, y)); }
-float4 max(float4 x, float4 y) { return mix(y, x, greaterThan(x, y)); }
-
-float2 max(float2 x, float  y) { return mix(float2(y), x, greaterThan(x, float2(y))); }
-float3 max(float3 x, float  y) { return mix(float3(y), x, greaterThan(x, float3(y))); }
-float4 max(float4 x, float  y) { return mix(float4(y), x, greaterThan(x, float4(y))); }
-
-float  clamp(float  x, float  minVal, float  maxVal) { return min(max(x, minVal), maxVal); }
-float2 clamp(float2 x, float2 minVal, float2 maxVal) { return min(max(x, minVal), maxVal); }
-float3 clamp(float3 x, float3 minVal, float3 maxVal) { return min(max(x, minVal), maxVal); }
-float4 clamp(float4 x, float4 minVal, float4 maxVal) { return min(max(x, minVal), maxVal); }
-
-float2 clamp(float2 x, float  minVal, float  maxVal) { return min(max(x, minVal), maxVal); }
-float3 clamp(float3 x, float  minVal, float  maxVal) { return min(max(x, minVal), maxVal); }
-float4 clamp(float4 x, float  minVal, float  maxVal) { return min(max(x, minVal), maxVal); }
-
-float  saturate(float  x) { return min(max(x, 0), 1); }
-float2 saturate(float2 x) { return min(max(x, 0), 1); }
-float3 saturate(float3 x) { return min(max(x, 0), 1); }
-float4 saturate(float4 x) { return min(max(x, 0), 1); }
-
-float  step(float  edge, float  x) { return mix(1, 0, x < edge); }
-float2 step(float2 edge, float2 x) { return mix(float2(1), float2(0), lessThan(x, edge)); }
-float3 step(float3 edge, float3 x) { return mix(float3(1), float3(0), lessThan(x, edge)); }
-float4 step(float4 edge, float4 x) { return mix(float4(1), float4(0), lessThan(x, edge)); }
-
-float2 step(float  edge, float2 x) { return mix(float2(1), float2(0), lessThan(x, float2(edge))); }
-float3 step(float  edge, float3 x) { return mix(float3(1), float3(0), lessThan(x, float3(edge))); }
-float4 step(float  edge, float4 x) { return mix(float4(1), float4(0), lessThan(x, float4(edge))); }
-
-float  smoothstep(float  edge0, float  edge1, float  x) {
-    float  t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-float2 smoothstep(float2 edge0, float2 edge1, float2 x) {
-    float2 t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-float3 smoothstep(float3 edge0, float3 edge1, float3 x) {
-    float3 t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-float4 smoothstep(float4 edge0, float4 edge1, float4 x) {
-    float4 t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-float2 smoothstep(float  edge0, float  edge1, float2 x) {
-    float2 t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-float3 smoothstep(float  edge0, float  edge1, float3 x) {
-    float3 t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-float4 smoothstep(float  edge0, float  edge1, float4 x) {
-    float4 t = saturate((x - edge0) / (edge1 - edge0));
-    return t * t * (3.0 - 2.0 * t);
-}
-
-)
diff --git a/tests/SkSLInterpreterTest.cpp b/tests/SkSLInterpreterTest.cpp
index 2bc3019..f4bf75c 100644
--- a/tests/SkSLInterpreterTest.cpp
+++ b/tests/SkSLInterpreterTest.cpp
@@ -796,6 +796,8 @@
         "float main(float x) { return sub(sqr(x), x); }\n"
 
         // Different signatures
+        "float dot(float2 a, float2 b) { return a.x*b.x + a.y*b.y; }\n"
+        "float dot(float3 a, float3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; }\n"
         "float dot3_test(float x) { return dot(float3(x, x + 1, x + 2), float3(1, -1, 2)); }\n"
         "float dot2_test(float x) { return dot(float2(x, x + 1), float2(1, -1)); }\n";
 
@@ -957,29 +959,6 @@
           expectedVector[] = { 3.0f, 4.0f, 5.0f, 6.0f };
     test(r, "float4 main(float4 x, float4 y) { return mix(x, y, 0.5); }", valueVectors,
          expectedVector);
-
-    auto expect = [&expectedVector](float a, float b, float c, float d) {
-        expectedVector[0] = a;
-        expectedVector[1] = b;
-        expectedVector[2] = c;
-        expectedVector[3] = d;
-    };
-
-    expect(1, 2, 7, 8);
-    test(r, "float4 main(float4 x, float4 y) { return mix(x, y, greaterThan(x, float4(2.5))); }",
-         valueVectors, expectedVector);
-
-    expect(5, 6, 3, 4);
-    test(r, "float4 main(float4 x, float4 y) { return mix(x, y, lessThan(x, float4(2.5))); }",
-         valueVectors, expectedVector);
-
-    expect(1, 2, 7, 8);
-    test(r, "float4 main(float4 x, float4 y) { return mix(x, y, greaterThanEqual(x, float4(3))); }",
-         valueVectors, expectedVector);
-
-    expect(5, 6, 3, 4);
-    test(r, "float4 main(float4 x, float4 y) { return mix(x, y, lessThanEqual(x, float4(2))); }",
-         valueVectors, expectedVector);
 }
 
 DEF_TEST(SkSLInterpreterCross, r) {