[ir] Add a SPIRV BuiltinCall instruction

This CL adds a `BuiltinCall` instruction to SPIR-V IR and moves
`VectorTimesScalar` over to the builtin.

Bug: tint:1718
Change-Id: I4fd92aab01d32897c5bdb4add97e22b698ded377
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/150100
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/builder.h b/src/tint/lang/core/ir/builder.h
index ae5ae69..ffa0347 100644
--- a/src/tint/lang/core/ir/builder.h
+++ b/src/tint/lang/core/ir/builder.h
@@ -620,13 +620,26 @@
             InstructionResult(type), func, Values(std::forward<ARGS>(args)...)));
     }
 
+    /// Creates a core builtin call instruction
+    /// @param type the return type of the call
+    /// @param func the builtin function to call
+    /// @param args the call arguments
+    /// @returns the instruction
+    template <typename KLASS, typename FUNC, typename... ARGS>
+    tint::traits::EnableIf<tint::traits::IsTypeOrDerived<KLASS, ir::BuiltinCall>, KLASS*>
+    Call(const core::type::Type* type, FUNC func, ARGS&&... args) {
+        return Append(ir.instructions.Create<KLASS>(InstructionResult(type), func,
+                                                    Values(std::forward<ARGS>(args)...)));
+    }
+
     /// Creates an intrinsic call instruction
     /// @param type the return type of the call
     /// @param kind the intrinsic function to call
     /// @param args the call arguments
     /// @returns the intrinsic call instruction
     template <typename KLASS, typename KIND, typename... ARGS>
-    ir::IntrinsicCall* Call(const core::type::Type* type, KIND kind, ARGS&&... args) {
+    tint::traits::EnableIf<tint::traits::IsTypeOrDerived<KLASS, ir::IntrinsicCall>, KLASS*>
+    Call(const core::type::Type* type, KIND kind, ARGS&&... args) {
         return Append(ir.instructions.Create<KLASS>(InstructionResult(type), kind,
                                                     Values(std::forward<ARGS>(args)...)));
     }
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index d712e65..182c035 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -527,7 +527,9 @@
         [&](Convert*) {},                                      //
         [&](Discard*) {},                                      //
         [&](UserCall*) {},                                     //
-        [&](Default) { AddError(call, InstError(call, "missing validation")); });
+        [&](Default) {
+            // Validation of custom IR instructions
+        });
 }
 
 void Validator::CheckCoreBuiltinCall(CoreBuiltinCall* call) {