SkSL: Only allow bitwise ops on integral types

We were allowing these ops on floating point types. The resulting GLSL
would fail to compile. We also allowed >>= and <<= on vectors (but not
any of the other bitwise ops).

The newly added unit tests were failing (eg, not catching errors). New
results are correct.

Bug: skia:10707
Change-Id: I97b769f1ce59261361109a71061b42dc8ef3c74b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317393
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 5349a2c..1107adf 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -1545,6 +1545,7 @@
                                   const Type** outRightType,
                                   const Type** outResultType) {
     bool isLogical = false;
+    bool isBitwise = false;
     bool validMatrixOrVectorOp = false;
     bool isAssignment = Compiler::IsAssignment(op);
 
@@ -1636,12 +1637,23 @@
             }
             validMatrixOrVectorOp = true;
             break;
+        case Token::Kind::TK_SHLEQ:
+        case Token::Kind::TK_SHREQ:
+        case Token::Kind::TK_BITWISEANDEQ:
+        case Token::Kind::TK_BITWISEOREQ:
+        case Token::Kind::TK_BITWISEXOREQ:
+        case Token::Kind::TK_SHL:
+        case Token::Kind::TK_SHR:
+        case Token::Kind::TK_BITWISEAND:
+        case Token::Kind::TK_BITWISEOR:
+        case Token::Kind::TK_BITWISEXOR:
+            isBitwise = true;
+            validMatrixOrVectorOp = true;
+            break;
         case Token::Kind::TK_PLUSEQ:
         case Token::Kind::TK_MINUSEQ:
         case Token::Kind::TK_SLASHEQ:
         case Token::Kind::TK_PERCENTEQ:
-        case Token::Kind::TK_SHLEQ:
-        case Token::Kind::TK_SHREQ:
         case Token::Kind::TK_PLUS:
         case Token::Kind::TK_MINUS:
         case Token::Kind::TK_SLASH:
@@ -1697,6 +1709,13 @@
     if ((left.typeKind() == Type::TypeKind::kScalar &&
          right.typeKind() == Type::TypeKind::kScalar) ||
         (leftIsVectorOrMatrix && validMatrixOrVectorOp)) {
+        if (isBitwise) {
+            const Type& leftNumberType(leftIsVectorOrMatrix ? left.componentType() : left);
+            const Type& rightNumberType(rightIsVectorOrMatrix ? right.componentType() : right);
+            if (!leftNumberType.isInteger() || !rightNumberType.isInteger()) {
+                return false;
+            }
+        }
         if (rightToLeftCost.isPossible(allowNarrowing) && rightToLeftCost < leftToRightCost) {
             // Right-to-Left conversion is possible and cheaper
             *outLeftType = &left;