Add user call tests
This CL adds end-to-end tests for user calls.
Bug: tint:1718
Change-Id: I076d64ffa5097d6184027f0fa3c868a1dd3b9507
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162261
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 436e88f..cbb92ed 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -262,7 +262,15 @@
[&](core::ir::Load*) { MaybeEmitInstruction(inst); }, //
[&](core::ir::Construct*) { MaybeEmitInstruction(inst); }, //
[&](core::ir::Access*) { MaybeEmitInstruction(inst); }, //
- [&](core::ir::UserCall*) { MaybeEmitInstruction(inst); }, //
+ [&](core::ir::UserCall* c) {
+ if (c->Result()->Type()->Is<core::type::Void>()) {
+ auto out = Line();
+ EmitValue(out, c->Result());
+ out << ";";
+ } else {
+ MaybeEmitInstruction(inst);
+ }
+ }, //
TINT_ICE_ON_NO_MATCH);
}
}
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl b/test/tint/expressions/user_call/call_with_call_param.wgsl
new file mode 100644
index 0000000..d321f7e
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl
@@ -0,0 +1,11 @@
+fn b(i: i32) -> f32 {
+ return 2.3f;
+}
+
+fn c(u: u32) -> i32 {
+ return 1;
+}
+
+fn a() {
+ var a = b(c(2));
+}
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..1379922
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.dxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+float b(int i) {
+ return 2.29999995231628417969f;
+}
+
+int c(uint u) {
+ return 1;
+}
+
+void a() {
+ const int tint_symbol = c(2u);
+ float a_1 = b(tint_symbol);
+}
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..1379922
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.fxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+float b(int i) {
+ return 2.29999995231628417969f;
+}
+
+int c(uint u) {
+ return 1;
+}
+
+void a() {
+ const int tint_symbol = c(2u);
+ float a_1 = b(tint_symbol);
+}
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.glsl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.glsl
new file mode 100644
index 0000000..d94bb1a
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.glsl
@@ -0,0 +1,19 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+float b(int i) {
+ return 2.29999995231628417969f;
+}
+
+int c(uint u) {
+ return 1;
+}
+
+void a() {
+ int tint_symbol = c(2u);
+ float a_1 = b(tint_symbol);
+}
+
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl
new file mode 100644
index 0000000..2454f50
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.ir.msl
@@ -0,0 +1,27 @@
+SKIP: FAILED
+
+#include <metal_stdlib>
+using namespace metal;
+
+float b() {
+ return 2.29999995231628417969f;
+}
+int c() {
+ return 1;
+}
+void a() {
+ float a = b(c(2u));
+}
+program_source:11:15: error: no matching function for call to 'c'
+ float a = b(c(2u));
+ ^
+program_source:7:5: note: candidate function not viable: requires 0 arguments, but 1 was provided
+int c() {
+ ^
+program_source:11:13: error: no matching function for call to 'b'
+ float a = b(c(2u));
+ ^
+program_source:4:7: note: candidate function not viable: requires 0 arguments, but 1 was provided
+float b() {
+ ^
+
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.msl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.msl
new file mode 100644
index 0000000..2c2d9f6
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.msl
@@ -0,0 +1,16 @@
+#include <metal_stdlib>
+
+using namespace metal;
+float b(int i) {
+ return 2.29999995231628417969f;
+}
+
+int c(uint u) {
+ return 1;
+}
+
+void a() {
+ int const tint_symbol = c(2u);
+ float a_1 = b(tint_symbol);
+}
+
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.spvasm b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.spvasm
new file mode 100644
index 0000000..808124e
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.spvasm
@@ -0,0 +1,50 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 26
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %b "b"
+ OpName %i "i"
+ OpName %c "c"
+ OpName %u "u"
+ OpName %a "a"
+ OpName %a_1 "a_1"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %int = OpTypeInt 32 1
+ %5 = OpTypeFunction %float %int
+%float_2_29999995 = OpConstant %float 2.29999995
+ %uint = OpTypeInt 32 0
+ %12 = OpTypeFunction %int %uint
+ %int_1 = OpConstant %int 1
+ %uint_2 = OpConstant %uint 2
+%_ptr_Function_float = OpTypePointer Function %float
+ %25 = OpConstantNull %float
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %b = OpFunction %float None %5
+ %i = OpFunctionParameter %int
+ %10 = OpLabel
+ OpReturnValue %float_2_29999995
+ OpFunctionEnd
+ %c = OpFunction %int None %12
+ %u = OpFunctionParameter %uint
+ %16 = OpLabel
+ OpReturnValue %int_1
+ OpFunctionEnd
+ %a = OpFunction %void None %1
+ %19 = OpLabel
+ %a_1 = OpVariable %_ptr_Function_float Function %25
+ %20 = OpFunctionCall %int %c %uint_2
+ %22 = OpFunctionCall %float %b %20
+ OpStore %a_1 %22
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.wgsl b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.wgsl
new file mode 100644
index 0000000..8d46d7d
--- /dev/null
+++ b/test/tint/expressions/user_call/call_with_call_param.wgsl.expected.wgsl
@@ -0,0 +1,11 @@
+fn b(i : i32) -> f32 {
+ return 2.29999995231628417969f;
+}
+
+fn c(u : u32) -> i32 {
+ return 1;
+}
+
+fn a() {
+ var a = b(c(2));
+}
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl b/test/tint/expressions/user_call/multi_param_no_return.wgsl
new file mode 100644
index 0000000..d645f8c
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl
@@ -0,0 +1,9 @@
+fn c(x: i32, y: i32, z: i32) {
+ var a = 1 + x + y + z;
+ a = a + 2;
+}
+
+fn b() {
+ c(1, 2, 3);
+ c(4, 5, 6);
+}
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b0b3b00
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.dxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void c(int x, int y, int z) {
+ int a = (((1 + x) + y) + z);
+ a = (a + 2);
+}
+
+void b() {
+ c(1, 2, 3);
+ c(4, 5, 6);
+}
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b0b3b00
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.fxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void c(int x, int y, int z) {
+ int a = (((1 + x) + y) + z);
+ a = (a + 2);
+}
+
+void b() {
+ c(1, 2, 3);
+ c(4, 5, 6);
+}
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.glsl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.glsl
new file mode 100644
index 0000000..a562693
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.glsl
@@ -0,0 +1,16 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+void c(int x, int y, int z) {
+ int a = (((1 + x) + y) + z);
+ a = (a + 2);
+}
+
+void b() {
+ c(1, 2, 3);
+ c(4, 5, 6);
+}
+
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl
new file mode 100644
index 0000000..03d2607
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.ir.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
+********************************************************************
+* 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. *
+********************************************************************
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.msl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.msl
new file mode 100644
index 0000000..92d7d2d
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.msl
@@ -0,0 +1,13 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void c(int x, int y, int z) {
+ int a = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(1) + as_type<uint>(x)))) + as_type<uint>(y)))) + as_type<uint>(z)));
+ a = as_type<int>((as_type<uint>(a) + as_type<uint>(2)));
+}
+
+void b() {
+ c(1, 2, 3);
+ c(4, 5, 6);
+}
+
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.spvasm b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.spvasm
new file mode 100644
index 0000000..9a14a1d
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.spvasm
@@ -0,0 +1,53 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %c "c"
+ OpName %x "x"
+ OpName %y "y"
+ OpName %z "z"
+ OpName %a "a"
+ OpName %b "b"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %5 = OpTypeFunction %void %int %int %int
+ %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %18 = OpConstantNull %int
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %int_4 = OpConstant %int 4
+ %int_5 = OpConstant %int 5
+ %int_6 = OpConstant %int 6
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %void None %5
+ %x = OpFunctionParameter %int
+ %y = OpFunctionParameter %int
+ %z = OpFunctionParameter %int
+ %11 = OpLabel
+ %a = OpVariable %_ptr_Function_int Function %18
+ %13 = OpIAdd %int %int_1 %x
+ %14 = OpIAdd %int %13 %y
+ %15 = OpIAdd %int %14 %z
+ OpStore %a %15
+ %19 = OpLoad %int %a
+ %21 = OpIAdd %int %19 %int_2
+ OpStore %a %21
+ OpReturn
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %23 = OpLabel
+ %24 = OpFunctionCall %void %c %int_1 %int_2 %int_3
+ %26 = OpFunctionCall %void %c %int_4 %int_5 %int_6
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.wgsl b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.wgsl
new file mode 100644
index 0000000..0a306fe
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_no_return.wgsl.expected.wgsl
@@ -0,0 +1,9 @@
+fn c(x : i32, y : i32, z : i32) {
+ var a = (((1 + x) + y) + z);
+ a = (a + 2);
+}
+
+fn b() {
+ c(1, 2, 3);
+ c(4, 5, 6);
+}
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl b/test/tint/expressions/user_call/multi_param_return.wgsl
new file mode 100644
index 0000000..d19250f
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl
@@ -0,0 +1,10 @@
+fn c(x: i32, y: i32, z: i32) -> i32 {
+ var a = 1 + x + y + z;
+ a = a + 2;
+ return a;
+}
+
+fn b() {
+ var b = c(2, 3, 4);
+ b += c(3, 4, 5);
+}
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..0fef91f
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.dxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+int c(int x, int y, int z) {
+ int a = (((1 + x) + y) + z);
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c(2, 3, 4);
+ const int tint_symbol = b_1;
+ const int tint_symbol_1 = c(3, 4, 5);
+ b_1 = (tint_symbol + tint_symbol_1);
+}
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..0fef91f
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.fxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+int c(int x, int y, int z) {
+ int a = (((1 + x) + y) + z);
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c(2, 3, 4);
+ const int tint_symbol = b_1;
+ const int tint_symbol_1 = c(3, 4, 5);
+ b_1 = (tint_symbol + tint_symbol_1);
+}
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.glsl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.glsl
new file mode 100644
index 0000000..76eca0b
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.glsl
@@ -0,0 +1,19 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+int c(int x, int y, int z) {
+ int a = (((1 + x) + y) + z);
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c(2, 3, 4);
+ int tint_symbol = b_1;
+ int tint_symbol_1 = c(3, 4, 5);
+ b_1 = (tint_symbol + tint_symbol_1);
+}
+
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl
new file mode 100644
index 0000000..03d2607
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.ir.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
+********************************************************************
+* 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. *
+********************************************************************
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.msl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.msl
new file mode 100644
index 0000000..9fa6f40
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.msl
@@ -0,0 +1,16 @@
+#include <metal_stdlib>
+
+using namespace metal;
+int c(int x, int y, int z) {
+ int a = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(1) + as_type<uint>(x)))) + as_type<uint>(y)))) + as_type<uint>(z)));
+ a = as_type<int>((as_type<uint>(a) + as_type<uint>(2)));
+ return a;
+}
+
+void b() {
+ int b_1 = c(2, 3, 4);
+ int const tint_symbol = b_1;
+ int const tint_symbol_1 = c(3, 4, 5);
+ b_1 = as_type<int>((as_type<uint>(tint_symbol) + as_type<uint>(tint_symbol_1)));
+}
+
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.spvasm b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.spvasm
new file mode 100644
index 0000000..e5e4eed
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.spvasm
@@ -0,0 +1,59 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 33
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %c "c"
+ OpName %x "x"
+ OpName %y "y"
+ OpName %z "z"
+ OpName %a "a"
+ OpName %b "b"
+ OpName %b_1 "b_1"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %5 = OpTypeFunction %int %int %int %int
+ %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %18 = OpConstantNull %int
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+ %int_4 = OpConstant %int 4
+ %int_5 = OpConstant %int 5
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %int None %5
+ %x = OpFunctionParameter %int
+ %y = OpFunctionParameter %int
+ %z = OpFunctionParameter %int
+ %11 = OpLabel
+ %a = OpVariable %_ptr_Function_int Function %18
+ %13 = OpIAdd %int %int_1 %x
+ %14 = OpIAdd %int %13 %y
+ %15 = OpIAdd %int %14 %z
+ OpStore %a %15
+ %19 = OpLoad %int %a
+ %21 = OpIAdd %int %19 %int_2
+ OpStore %a %21
+ %22 = OpLoad %int %a
+ OpReturnValue %22
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %24 = OpLabel
+ %b_1 = OpVariable %_ptr_Function_int Function %18
+ %25 = OpFunctionCall %int %c %int_2 %int_3 %int_4
+ OpStore %b_1 %25
+ %29 = OpLoad %int %b_1
+ %30 = OpFunctionCall %int %c %int_3 %int_4 %int_5
+ %32 = OpIAdd %int %29 %30
+ OpStore %b_1 %32
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/multi_param_return.wgsl.expected.wgsl b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.wgsl
new file mode 100644
index 0000000..adc6f92
--- /dev/null
+++ b/test/tint/expressions/user_call/multi_param_return.wgsl.expected.wgsl
@@ -0,0 +1,10 @@
+fn c(x : i32, y : i32, z : i32) -> i32 {
+ var a = (((1 + x) + y) + z);
+ a = (a + 2);
+ return a;
+}
+
+fn b() {
+ var b = c(2, 3, 4);
+ b += c(3, 4, 5);
+}
diff --git a/test/tint/expressions/user_call/nested.wgsl b/test/tint/expressions/user_call/nested.wgsl
new file mode 100644
index 0000000..2c86186
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl
@@ -0,0 +1,13 @@
+fn a() {
+ b();
+}
+
+fn b() {
+ c();
+}
+
+fn c() {
+ d();
+}
+
+fn d() {}
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/nested.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..dcc36ce
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.dxc.hlsl
@@ -0,0 +1,19 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void d() {
+}
+
+void c() {
+ d();
+}
+
+void b() {
+ c();
+}
+
+void a() {
+ b();
+}
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/nested.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..dcc36ce
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.fxc.hlsl
@@ -0,0 +1,19 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void d() {
+}
+
+void c() {
+ d();
+}
+
+void b() {
+ c();
+}
+
+void a() {
+ b();
+}
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.glsl b/test/tint/expressions/user_call/nested.wgsl.expected.glsl
new file mode 100644
index 0000000..811774e
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.glsl
@@ -0,0 +1,21 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+void d() {
+}
+
+void c() {
+ d();
+}
+
+void b() {
+ c();
+}
+
+void a() {
+ b();
+}
+
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.ir.msl b/test/tint/expressions/user_call/nested.wgsl.expected.ir.msl
new file mode 100644
index 0000000..16f9ef8
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.ir.msl
@@ -0,0 +1,14 @@
+#include <metal_stdlib>
+using namespace metal;
+
+void d() {
+}
+void c() {
+ d();
+}
+void b() {
+ c();
+}
+void a() {
+ b();
+}
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.msl b/test/tint/expressions/user_call/nested.wgsl.expected.msl
new file mode 100644
index 0000000..ff536f1
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.msl
@@ -0,0 +1,18 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void d() {
+}
+
+void c() {
+ d();
+}
+
+void b() {
+ c();
+}
+
+void a() {
+ b();
+}
+
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.spvasm b/test/tint/expressions/user_call/nested.wgsl.expected.spvasm
new file mode 100644
index 0000000..047ecf4
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.spvasm
@@ -0,0 +1,39 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 16
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %d "d"
+ OpName %c "c"
+ OpName %b "b"
+ OpName %a "a"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %d = OpFunction %void None %1
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %void None %1
+ %8 = OpLabel
+ %9 = OpFunctionCall %void %d
+ OpReturn
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %11 = OpLabel
+ %12 = OpFunctionCall %void %c
+ OpReturn
+ OpFunctionEnd
+ %a = OpFunction %void None %1
+ %14 = OpLabel
+ %15 = OpFunctionCall %void %b
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/nested.wgsl.expected.wgsl b/test/tint/expressions/user_call/nested.wgsl.expected.wgsl
new file mode 100644
index 0000000..2b7f165
--- /dev/null
+++ b/test/tint/expressions/user_call/nested.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+fn a() {
+ b();
+}
+
+fn b() {
+ c();
+}
+
+fn c() {
+ d();
+}
+
+fn d() {
+}
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl b/test/tint/expressions/user_call/no_params_no_return.wgsl
new file mode 100644
index 0000000..716949c
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl
@@ -0,0 +1,9 @@
+fn c() {
+ var a = 1;
+ a = a + 2;
+}
+
+fn b() {
+ c();
+ c();
+}
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..17aec4b
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.dxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void c() {
+ int a = 1;
+ a = (a + 2);
+}
+
+void b() {
+ c();
+ c();
+}
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..17aec4b
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.fxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void c() {
+ int a = 1;
+ a = (a + 2);
+}
+
+void b() {
+ c();
+ c();
+}
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.glsl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.glsl
new file mode 100644
index 0000000..e6fcda4
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.glsl
@@ -0,0 +1,16 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+void c() {
+ int a = 1;
+ a = (a + 2);
+}
+
+void b() {
+ c();
+ c();
+}
+
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl
new file mode 100644
index 0000000..1e88c74
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.ir.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+<dawn>/src/tint/lang/msl/writer/printer/printer.cc:274 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Store
+********************************************************************
+* 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. *
+********************************************************************
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.msl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.msl
new file mode 100644
index 0000000..1c3993d
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.msl
@@ -0,0 +1,13 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void c() {
+ int a = 1;
+ a = as_type<int>((as_type<uint>(a) + as_type<uint>(2)));
+}
+
+void b() {
+ c();
+ c();
+}
+
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.spvasm b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.spvasm
new file mode 100644
index 0000000..a27d3e0
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.spvasm
@@ -0,0 +1,39 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 19
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %c "c"
+ OpName %a "a"
+ OpName %b "b"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %11 = OpConstantNull %int
+ %int_2 = OpConstant %int 2
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %void None %1
+ %6 = OpLabel
+ %a = OpVariable %_ptr_Function_int Function %11
+ OpStore %a %int_1
+ %12 = OpLoad %int %a
+ %14 = OpIAdd %int %12 %int_2
+ OpStore %a %14
+ OpReturn
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %16 = OpLabel
+ %17 = OpFunctionCall %void %c
+ %18 = OpFunctionCall %void %c
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.wgsl b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.wgsl
new file mode 100644
index 0000000..3dd9256
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_no_return.wgsl.expected.wgsl
@@ -0,0 +1,9 @@
+fn c() {
+ var a = 1;
+ a = (a + 2);
+}
+
+fn b() {
+ c();
+ c();
+}
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl b/test/tint/expressions/user_call/no_params_return.wgsl
new file mode 100644
index 0000000..42424f9
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl
@@ -0,0 +1,10 @@
+fn c() -> i32 {
+ var a = 1;
+ a = a + 2;
+ return a;
+}
+
+fn b() {
+ var b = c();
+ b += c();
+}
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..411c9f3
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.dxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+int c() {
+ int a = 1;
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c();
+ const int tint_symbol = b_1;
+ const int tint_symbol_1 = c();
+ b_1 = (tint_symbol + tint_symbol_1);
+}
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..411c9f3
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.fxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+int c() {
+ int a = 1;
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c();
+ const int tint_symbol = b_1;
+ const int tint_symbol_1 = c();
+ b_1 = (tint_symbol + tint_symbol_1);
+}
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.glsl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.glsl
new file mode 100644
index 0000000..dc7ed0f
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.glsl
@@ -0,0 +1,19 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+int c() {
+ int a = 1;
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c();
+ int tint_symbol = b_1;
+ int tint_symbol_1 = c();
+ b_1 = (tint_symbol + tint_symbol_1);
+}
+
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl
new file mode 100644
index 0000000..1e88c74
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.ir.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+<dawn>/src/tint/lang/msl/writer/printer/printer.cc:274 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Store
+********************************************************************
+* 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. *
+********************************************************************
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.msl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.msl
new file mode 100644
index 0000000..4bce79f
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.msl
@@ -0,0 +1,16 @@
+#include <metal_stdlib>
+
+using namespace metal;
+int c() {
+ int a = 1;
+ a = as_type<int>((as_type<uint>(a) + as_type<uint>(2)));
+ return a;
+}
+
+void b() {
+ int b_1 = c();
+ int const tint_symbol = b_1;
+ int const tint_symbol_1 = c();
+ b_1 = as_type<int>((as_type<uint>(tint_symbol) + as_type<uint>(tint_symbol_1)));
+}
+
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.spvasm b/test/tint/expressions/user_call/no_params_return.wgsl.expected.spvasm
new file mode 100644
index 0000000..c2e8fea
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.spvasm
@@ -0,0 +1,47 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 24
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %c "c"
+ OpName %a "a"
+ OpName %b "b"
+ OpName %b_1 "b_1"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %5 = OpTypeFunction %int
+ %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %12 = OpConstantNull %int
+ %int_2 = OpConstant %int 2
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %int None %5
+ %8 = OpLabel
+ %a = OpVariable %_ptr_Function_int Function %12
+ OpStore %a %int_1
+ %13 = OpLoad %int %a
+ %15 = OpIAdd %int %13 %int_2
+ OpStore %a %15
+ %16 = OpLoad %int %a
+ OpReturnValue %16
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %18 = OpLabel
+ %b_1 = OpVariable %_ptr_Function_int Function %12
+ %19 = OpFunctionCall %int %c
+ OpStore %b_1 %19
+ %21 = OpLoad %int %b_1
+ %22 = OpFunctionCall %int %c
+ %23 = OpIAdd %int %21 %22
+ OpStore %b_1 %23
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/no_params_return.wgsl.expected.wgsl b/test/tint/expressions/user_call/no_params_return.wgsl.expected.wgsl
new file mode 100644
index 0000000..58fd09c
--- /dev/null
+++ b/test/tint/expressions/user_call/no_params_return.wgsl.expected.wgsl
@@ -0,0 +1,10 @@
+fn c() -> i32 {
+ var a = 1;
+ a = (a + 2);
+ return a;
+}
+
+fn b() {
+ var b = c();
+ b += c();
+}
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl b/test/tint/expressions/user_call/one_param_no_return.wgsl
new file mode 100644
index 0000000..f6d2cb9
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl
@@ -0,0 +1,9 @@
+fn c(z: i32) {
+ var a = 1 + z;
+ a = a + 2;
+}
+
+fn b() {
+ c(2);
+ c(3);
+}
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..33eec45
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.dxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void c(int z) {
+ int a = (1 + z);
+ a = (a + 2);
+}
+
+void b() {
+ c(2);
+ c(3);
+}
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..33eec45
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.fxc.hlsl
@@ -0,0 +1,14 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+void c(int z) {
+ int a = (1 + z);
+ a = (a + 2);
+}
+
+void b() {
+ c(2);
+ c(3);
+}
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.glsl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.glsl
new file mode 100644
index 0000000..12d1a71
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.glsl
@@ -0,0 +1,16 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+void c(int z) {
+ int a = (1 + z);
+ a = (a + 2);
+}
+
+void b() {
+ c(2);
+ c(3);
+}
+
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl
new file mode 100644
index 0000000..03d2607
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.ir.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
+********************************************************************
+* 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. *
+********************************************************************
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.msl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.msl
new file mode 100644
index 0000000..cd4a68d
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.msl
@@ -0,0 +1,13 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void c(int z) {
+ int a = as_type<int>((as_type<uint>(1) + as_type<uint>(z)));
+ a = as_type<int>((as_type<uint>(a) + as_type<uint>(2)));
+}
+
+void b() {
+ c(2);
+ c(3);
+}
+
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.spvasm b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.spvasm
new file mode 100644
index 0000000..96fdb24
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.spvasm
@@ -0,0 +1,44 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 23
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %c "c"
+ OpName %z "z"
+ OpName %a "a"
+ OpName %b "b"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %5 = OpTypeFunction %void %int
+ %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %14 = OpConstantNull %int
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %void None %5
+ %z = OpFunctionParameter %int
+ %9 = OpLabel
+ %a = OpVariable %_ptr_Function_int Function %14
+ %11 = OpIAdd %int %int_1 %z
+ OpStore %a %11
+ %15 = OpLoad %int %a
+ %17 = OpIAdd %int %15 %int_2
+ OpStore %a %17
+ OpReturn
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %19 = OpLabel
+ %20 = OpFunctionCall %void %c %int_2
+ %21 = OpFunctionCall %void %c %int_3
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.wgsl b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.wgsl
new file mode 100644
index 0000000..104ad3b
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_no_return.wgsl.expected.wgsl
@@ -0,0 +1,9 @@
+fn c(z : i32) {
+ var a = (1 + z);
+ a = (a + 2);
+}
+
+fn b() {
+ c(2);
+ c(3);
+}
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl b/test/tint/expressions/user_call/one_param_return.wgsl
new file mode 100644
index 0000000..c657dac
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl
@@ -0,0 +1,10 @@
+fn c(z: i32) -> i32 {
+ var a = 1 + z;
+ a = a + 2;
+ return a;
+}
+
+fn b() {
+ var b = c(2);
+ b += c(3);
+}
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.dxc.hlsl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..d11dfc8
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.dxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+int c(int z) {
+ int a = (1 + z);
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c(2);
+ const int tint_symbol = b_1;
+ const int tint_symbol_1 = c(3);
+ b_1 = (tint_symbol + tint_symbol_1);
+}
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.fxc.hlsl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..d11dfc8
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.fxc.hlsl
@@ -0,0 +1,17 @@
+[numthreads(1, 1, 1)]
+void unused_entry_point() {
+ return;
+}
+
+int c(int z) {
+ int a = (1 + z);
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c(2);
+ const int tint_symbol = b_1;
+ const int tint_symbol_1 = c(3);
+ b_1 = (tint_symbol + tint_symbol_1);
+}
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.glsl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.glsl
new file mode 100644
index 0000000..b9e7dfb
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.glsl
@@ -0,0 +1,19 @@
+#version 310 es
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+ return;
+}
+int c(int z) {
+ int a = (1 + z);
+ a = (a + 2);
+ return a;
+}
+
+void b() {
+ int b_1 = c(2);
+ int tint_symbol = b_1;
+ int tint_symbol_1 = c(3);
+ b_1 = (tint_symbol + tint_symbol_1);
+}
+
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl
new file mode 100644
index 0000000..03d2607
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.ir.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+<dawn>/src/tint/lang/msl/writer/printer/printer.cc:315 internal compiler error: Switch() matched no cases. Type: tint::core::ir::FunctionParam
+********************************************************************
+* 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. *
+********************************************************************
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.msl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.msl
new file mode 100644
index 0000000..ac77cee
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.msl
@@ -0,0 +1,16 @@
+#include <metal_stdlib>
+
+using namespace metal;
+int c(int z) {
+ int a = as_type<int>((as_type<uint>(1) + as_type<uint>(z)));
+ a = as_type<int>((as_type<uint>(a) + as_type<uint>(2)));
+ return a;
+}
+
+void b() {
+ int b_1 = c(2);
+ int const tint_symbol = b_1;
+ int const tint_symbol_1 = c(3);
+ b_1 = as_type<int>((as_type<uint>(tint_symbol) + as_type<uint>(tint_symbol_1)));
+}
+
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.spvasm b/test/tint/expressions/user_call/one_param_return.wgsl.expected.spvasm
new file mode 100644
index 0000000..84085d1
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.spvasm
@@ -0,0 +1,51 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 27
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
+ OpExecutionMode %unused_entry_point LocalSize 1 1 1
+ OpName %unused_entry_point "unused_entry_point"
+ OpName %c "c"
+ OpName %z "z"
+ OpName %a "a"
+ OpName %b "b"
+ OpName %b_1 "b_1"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %5 = OpTypeFunction %int %int
+ %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %14 = OpConstantNull %int
+ %int_2 = OpConstant %int 2
+ %int_3 = OpConstant %int 3
+%unused_entry_point = OpFunction %void None %1
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %c = OpFunction %int None %5
+ %z = OpFunctionParameter %int
+ %9 = OpLabel
+ %a = OpVariable %_ptr_Function_int Function %14
+ %11 = OpIAdd %int %int_1 %z
+ OpStore %a %11
+ %15 = OpLoad %int %a
+ %17 = OpIAdd %int %15 %int_2
+ OpStore %a %17
+ %18 = OpLoad %int %a
+ OpReturnValue %18
+ OpFunctionEnd
+ %b = OpFunction %void None %1
+ %20 = OpLabel
+ %b_1 = OpVariable %_ptr_Function_int Function %14
+ %21 = OpFunctionCall %int %c %int_2
+ OpStore %b_1 %21
+ %23 = OpLoad %int %b_1
+ %24 = OpFunctionCall %int %c %int_3
+ %26 = OpIAdd %int %23 %24
+ OpStore %b_1 %26
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/expressions/user_call/one_param_return.wgsl.expected.wgsl b/test/tint/expressions/user_call/one_param_return.wgsl.expected.wgsl
new file mode 100644
index 0000000..458039a
--- /dev/null
+++ b/test/tint/expressions/user_call/one_param_return.wgsl.expected.wgsl
@@ -0,0 +1,10 @@
+fn c(z : i32) -> i32 {
+ var a = (1 + z);
+ a = (a + 2);
+ return a;
+}
+
+fn b() {
+ var b = c(2);
+ b += c(3);
+}