[ir][msl] Emit ir::UserCall

Add support for the ir user call instruction in the MSL printer.

Bug: tint:1967
Change-Id: Ibf91da5ef541d12a293440ab88727de2b29bbe7b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162300
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 0b4aa8c..436e88f 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -49,6 +49,7 @@
 #include "src/tint/lang/core/ir/multi_in_block.h"
 #include "src/tint/lang/core/ir/return.h"
 #include "src/tint/lang/core/ir/unreachable.h"
+#include "src/tint/lang/core/ir/user_call.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/core/ir/var.h"
 #include "src/tint/lang/core/type/array.h"
@@ -261,6 +262,7 @@
                 [&](core::ir::Load*) { MaybeEmitInstruction(inst); },       //
                 [&](core::ir::Construct*) { MaybeEmitInstruction(inst); },  //
                 [&](core::ir::Access*) { MaybeEmitInstruction(inst); },     //
+                [&](core::ir::UserCall*) { MaybeEmitInstruction(inst); },   //
                 TINT_ICE_ON_NO_MATCH);
         }
     }
@@ -299,6 +301,7 @@
                     [&](const core::ir::Var* var) { EmitVarName(out, var); },      //
                     [&](const core::ir::Bitcast* b) { EmitBitcast(out, b); },      //
                     [&](const core::ir::Access* a) { EmitAccess(out, a); },        //
+                    [&](const core::ir::UserCall* c) { EmitUserCall(out, c); },    //
                     TINT_ICE_ON_NO_MATCH);
             },  //
             TINT_ICE_ON_NO_MATCH);
@@ -520,6 +523,21 @@
         }
     }
 
+    /// Emits a user call instruction
+    void EmitUserCall(StringStream& out, const core::ir::UserCall* c) {
+        out << ir_.NameOf(c->Target()).Name() << "(";
+        size_t i = 0;
+        for (const auto* arg : c->Args()) {
+            if (i > 0) {
+                out << ", ";
+            }
+            ++i;
+
+            EmitValue(out, arg);
+        }
+        out << ")";
+    }
+
     /// Emit a constructor
     void EmitConstruct(StringStream& out, const core::ir::Construct* c) {
         Switch(
diff --git a/test/tint/expressions/splat/call/bool.wgsl.expected.ir.msl b/test/tint/expressions/splat/call/bool.wgsl.expected.ir.msl
index 792ab03..e328b8c 100644
--- a/test/tint/expressions/splat/call/bool.wgsl.expected.ir.msl
+++ b/test/tint/expressions/splat/call/bool.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::UserCall
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+bool get_bool() {
+  return true;
+}
+void f() {
+  bool2 v2 = bool2(get_bool());
+  bool3 v3 = bool3(get_bool());
+  bool4 v4 = bool4(get_bool());
+}
diff --git a/test/tint/expressions/splat/call/f16.wgsl.expected.ir.msl b/test/tint/expressions/splat/call/f16.wgsl.expected.ir.msl
index 792ab03..6525595 100644
--- a/test/tint/expressions/splat/call/f16.wgsl.expected.ir.msl
+++ b/test/tint/expressions/splat/call/f16.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::UserCall
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+half get_f16() {
+  return 1.0h;
+}
+void f() {
+  half2 v2 = half2(get_f16());
+  half3 v3 = half3(get_f16());
+  half4 v4 = half4(get_f16());
+}
diff --git a/test/tint/expressions/splat/call/f32.wgsl.expected.ir.msl b/test/tint/expressions/splat/call/f32.wgsl.expected.ir.msl
index 792ab03..67f1153 100644
--- a/test/tint/expressions/splat/call/f32.wgsl.expected.ir.msl
+++ b/test/tint/expressions/splat/call/f32.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::UserCall
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+float get_f32() {
+  return 1.0f;
+}
+void f() {
+  float2 v2 = float2(get_f32());
+  float3 v3 = float3(get_f32());
+  float4 v4 = float4(get_f32());
+}
diff --git a/test/tint/expressions/splat/call/i32.wgsl.expected.ir.msl b/test/tint/expressions/splat/call/i32.wgsl.expected.ir.msl
index 792ab03..2d30e4e 100644
--- a/test/tint/expressions/splat/call/i32.wgsl.expected.ir.msl
+++ b/test/tint/expressions/splat/call/i32.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::UserCall
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+int get_i32() {
+  return 1;
+}
+void f() {
+  int2 v2 = int2(get_i32());
+  int3 v3 = int3(get_i32());
+  int4 v4 = int4(get_i32());
+}
diff --git a/test/tint/expressions/splat/call/u32.wgsl.expected.ir.msl b/test/tint/expressions/splat/call/u32.wgsl.expected.ir.msl
index 792ab03..4bab740 100644
--- a/test/tint/expressions/splat/call/u32.wgsl.expected.ir.msl
+++ b/test/tint/expressions/splat/call/u32.wgsl.expected.ir.msl
@@ -1,9 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::UserCall
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+uint get_u32() {
+  return 1u;
+}
+void f() {
+  uint2 v2 = uint2(get_u32());
+  uint3 v3 = uint3(get_u32());
+  uint4 v4 = uint4(get_u32());
+}