[ir] Builder::Return takes single Value

Return instructions have at most one value, so we don't need to pass
in a whole utils::Vector to the builder method.

Bug: tint:1718
Change-Id: I61a4edc3ee2a50fc805b65f3e5fdc7538e7383a8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/136781
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index b1c9597..4288954 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -211,8 +211,8 @@
     return ir.values.Create<ir::Var>(type);
 }
 
-ir::Return* Builder::Return(Function* func, utils::VectorRef<Value*> args /* = utils::Empty */) {
-    return ir.values.Create<ir::Return>(func, std::move(args));
+ir::Return* Builder::Return(Function* func, Value* value /* = nullptr */) {
+    return ir.values.Create<ir::Return>(func, value ? utils::Vector{value} : utils::Empty);
 }
 
 ir::NextIteration* Builder::NextIteration(Loop* loop,
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index 57144a8..7c87272 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -343,9 +343,9 @@
 
     /// Creates a return instruction
     /// @param func the function being returned
-    /// @param args the return arguments
+    /// @param value the return value
     /// @returns the instruction
-    ir::Return* Return(Function* func, utils::VectorRef<Value*> args = utils::Empty);
+    ir::Return* Return(Function* func, Value* value = nullptr);
 
     /// Creates a loop next iteration instruction
     /// @param loop the loop being iterated
diff --git a/src/tint/ir/from_program.cc b/src/tint/ir/from_program.cc
index b5b8f25..338c6d0 100644
--- a/src/tint/ir/from_program.cc
+++ b/src/tint/ir/from_program.cc
@@ -824,15 +824,15 @@
     }
 
     void EmitReturn(const ast::ReturnStatement* stmt) {
-        utils::Vector<Value*, 1> ret_value;
+        Value* ret_value = nullptr;
         if (stmt->value) {
             auto ret = EmitExpression(stmt->value);
             if (!ret) {
                 return;
             }
-            ret_value.Push(ret.Get());
+            ret_value = ret.Get();
         }
-        SetBranch(builder_.Return(current_function_, std::move(ret_value)));
+        SetBranch(builder_.Return(current_function_, ret_value));
     }
 
     void EmitBreak(const ast::BreakStatement*) {
diff --git a/src/tint/ir/return_test.cc b/src/tint/ir/return_test.cc
index e7a032e..3d18a39 100644
--- a/src/tint/ir/return_test.cc
+++ b/src/tint/ir/return_test.cc
@@ -13,6 +13,8 @@
 // limitations under the License.
 
 #include "src/tint/ir/return.h"
+
+#include "gmock/gmock.h"
 #include "gtest/gtest-spi.h"
 #include "src/tint/ir/ir_test_helper.h"
 
@@ -37,11 +39,29 @@
         {
             Module mod;
             Builder b{mod};
-            b.Return(b.CreateFunction("myfunc", mod.Types().void_()),
-                     utils::Vector<Value*, 1>{nullptr});
+            mod.values.Create<Return>(b.CreateFunction("myfunc", mod.Types().void_()),
+                                      utils::Vector<Value*, 1>{nullptr});
         },
         "");
 }
 
+TEST_F(IR_ReturnTest, ImplicitNoValue) {
+    auto* ret = b.Return(b.CreateFunction("myfunc", ty.void_()));
+    EXPECT_TRUE(ret->Args().IsEmpty());
+}
+
+TEST_F(IR_ReturnTest, ExplicitNoValue) {
+    auto* ret = b.Return(b.CreateFunction("myfunc", ty.void_()), nullptr);
+    EXPECT_TRUE(ret->Args().IsEmpty());
+}
+
+TEST_F(IR_ReturnTest, WithValue) {
+    auto* val = b.Constant(42_i);
+    auto* ret = b.Return(b.CreateFunction("myfunc", ty.i32()), val);
+    ASSERT_EQ(ret->Args().Length(), 1u);
+    EXPECT_EQ(ret->Args()[0], val);
+    EXPECT_THAT(val->Usages(), testing::UnorderedElementsAre(Usage{ret, 0u}));
+}
+
 }  // namespace
 }  // namespace tint::ir
diff --git a/src/tint/ir/transform/block_decorated_structs_test.cc b/src/tint/ir/transform/block_decorated_structs_test.cc
index f68d5c1..ce20fc1 100644
--- a/src/tint/ir/transform/block_decorated_structs_test.cc
+++ b/src/tint/ir/transform/block_decorated_structs_test.cc
@@ -55,7 +55,7 @@
     auto* func = b.CreateFunction("foo", ty.i32());
     auto* block = func->StartTarget();
     auto* load = block->Append(b.Load(buffer));
-    block->Append(b.Return(func, utils::Vector{load}));
+    block->Append(b.Return(func, load));
     mod.functions.Push(func);
 
     auto* expect = R"(
diff --git a/src/tint/ir/transform/var_for_dynamic_index_test.cc b/src/tint/ir/transform/var_for_dynamic_index_test.cc
index aaa4991..9850f3f 100644
--- a/src/tint/ir/transform/var_for_dynamic_index_test.cc
+++ b/src/tint/ir/transform/var_for_dynamic_index_test.cc
@@ -40,7 +40,7 @@
 
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ty.i32(), arr, utils::Vector{b.Constant(1_i)}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -65,7 +65,7 @@
     auto* block = func->StartTarget();
     auto* access =
         block->Append(b.Access(ty.f32(), mat, utils::Vector{b.Constant(1_i), b.Constant(0_i)}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -91,7 +91,7 @@
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ptr(ty.i32()), arr, utils::Vector{idx}));
     auto* load = block->Append(b.Load(access));
-    block->Append(b.Return(func, utils::Vector{load}));
+    block->Append(b.Return(func, load));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -118,7 +118,7 @@
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ptr(ty.f32()), mat, utils::Vector{idx, idx}));
     auto* load = block->Append(b.Load(access));
-    block->Append(b.Return(func, utils::Vector{load}));
+    block->Append(b.Return(func, load));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -144,7 +144,7 @@
 
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ty.f32(), vec, utils::Vector{idx}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -169,7 +169,7 @@
 
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ty.i32(), arr, utils::Vector{idx}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -196,7 +196,7 @@
 
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ty.f32(), arr, utils::Vector{idx}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -223,7 +223,7 @@
 
     auto* block = func->StartTarget();
     auto* access = block->Append(b.Access(ty.i32(), arr, utils::Vector{idx, b.Constant(1_u), idx}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -251,7 +251,7 @@
     auto* block = func->StartTarget();
     auto* access = block->Append(
         b.Access(ty.i32(), arr, utils::Vector{b.Constant(1_u), b.Constant(2_u), idx}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -280,7 +280,7 @@
     auto* block = func->StartTarget();
     auto* access = block->Append(
         b.Access(ty.i32(), arr, utils::Vector{b.Constant(1_u), idx, b.Constant(2_u), idx}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -320,7 +320,7 @@
     auto* block = func->StartTarget();
     auto* access = block->Append(
         b.Access(ty.f32(), str_val, utils::Vector{b.Constant(1_u), idx, b.Constant(0_u)}));
-    block->Append(b.Return(func, utils::Vector{access}));
+    block->Append(b.Return(func, access));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -358,7 +358,7 @@
     block->Append(b.Access(ty.i32(), arr, utils::Vector{idx_a}));
     block->Append(b.Access(ty.i32(), arr, utils::Vector{idx_b}));
     auto* access_c = block->Append(b.Access(ty.i32(), arr, utils::Vector{idx_c}));
-    block->Append(b.Return(func, utils::Vector{access_c}));
+    block->Append(b.Return(func, access_c));
     mod.functions.Push(func);
 
     auto* expect = R"(
@@ -394,7 +394,7 @@
     block->Append(b.Access(ty.i32(), arr, utils::Vector{b.Constant(1_u), b.Constant(2_u), idx_b}));
     auto* access_c = block->Append(
         b.Access(ty.i32(), arr, utils::Vector{b.Constant(1_u), b.Constant(2_u), idx_c}));
-    block->Append(b.Return(func, utils::Vector{access_c}));
+    block->Append(b.Return(func, access_c));
     mod.functions.Push(func);
 
     auto* expect = R"(
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
index 04d89fd..65a06c1 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
@@ -73,8 +73,7 @@
     auto* result = b.Builtin(MakeScalarType(kU32), builtin::Function::kAbs,
                              utils::Vector{MakeScalarValue(kU32)});
     auto* func = b.CreateFunction("foo", MakeScalarType(kU32));
-    func->StartTarget()->SetInstructions(
-        utils::Vector{result, b.Return(func, utils::Vector{result})});
+    func->StartTarget()->SetInstructions(utils::Vector{result, b.Return(func, result)});
 
     ASSERT_TRUE(IRIsValid()) << Error();
 
@@ -93,8 +92,7 @@
     auto* result = b.Builtin(MakeVectorType(kU32), builtin::Function::kAbs,
                              utils::Vector{MakeVectorValue(kU32)});
     auto* func = b.CreateFunction("foo", MakeVectorType(kU32));
-    func->StartTarget()->SetInstructions(
-        utils::Vector{result, b.Return(func, utils::Vector{result})});
+    func->StartTarget()->SetInstructions(utils::Vector{result, b.Return(func, result)});
 
     ASSERT_TRUE(IRIsValid()) << Error();
 
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_function_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_function_test.cc
index 0879e58..ba71dd4 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_function_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_function_test.cc
@@ -151,8 +151,7 @@
 
 TEST_F(SpvGeneratorImplTest, Function_ReturnValue) {
     auto* func = b.CreateFunction("foo", ty.i32());
-    func->StartTarget()->SetInstructions(
-        utils::Vector{b.Return(func, utils::Vector{b.Constant(i32(42))})});
+    func->StartTarget()->SetInstructions(utils::Vector{b.Return(func, b.Constant(i32(42)))});
 
     ASSERT_TRUE(IRIsValid()) << Error();
 
@@ -175,8 +174,7 @@
     auto* result = b.Add(i32, x, y);
     auto* func = b.CreateFunction("foo", i32);
     func->SetParams(utils::Vector{x, y});
-    func->StartTarget()->SetInstructions(
-        utils::Vector{result, b.Return(func, utils::Vector{result})});
+    func->StartTarget()->SetInstructions(utils::Vector{result, b.Return(func, result)});
     mod.SetName(x, "x");
     mod.SetName(y, "y");
 
@@ -205,8 +203,7 @@
     auto* result = b.Add(i32_ty, x, y);
     auto* foo = b.CreateFunction("foo", i32_ty);
     foo->SetParams(utils::Vector{x, y});
-    foo->StartTarget()->SetInstructions(
-        utils::Vector{result, b.Return(foo, utils::Vector{result})});
+    foo->StartTarget()->SetInstructions(utils::Vector{result, b.Return(foo, result)});
 
     auto* bar = b.CreateFunction("bar", ty.void_());
     bar->StartTarget()->SetInstructions(utils::Vector{
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_if_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_if_test.cc
index 4c4e5c3..7db8ccd 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_if_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_if_test.cc
@@ -159,7 +159,7 @@
     i->True()->SetInstructions(utils::Vector{b.ExitIf(i, utils::Vector{b.Constant(10_i)})});
     i->False()->SetInstructions(utils::Vector{b.ExitIf(i, utils::Vector{b.Constant(20_i)})});
     i->Merge()->SetParams(utils::Vector{merge_param});
-    i->Merge()->SetInstructions(utils::Vector{b.Return(func, utils::Vector{merge_param})});
+    i->Merge()->SetInstructions(utils::Vector{b.Return(func, merge_param)});
 
     func->StartTarget()->SetInstructions(utils::Vector{i});
 
@@ -195,10 +195,10 @@
     auto* merge_param = b.BlockParam(b.ir.Types().i32());
 
     auto* i = b.CreateIf(b.Constant(true));
-    i->True()->SetInstructions(utils::Vector{b.Return(func, utils::Vector{b.Constant(42_i)})});
+    i->True()->SetInstructions(utils::Vector{b.Return(func, b.Constant(42_i))});
     i->False()->SetInstructions(utils::Vector{b.ExitIf(i, utils::Vector{b.Constant(20_i)})});
     i->Merge()->SetParams(utils::Vector{merge_param});
-    i->Merge()->SetInstructions(utils::Vector{b.Return(func, utils::Vector{merge_param})});
+    i->Merge()->SetInstructions(utils::Vector{b.Return(func, merge_param)});
 
     func->StartTarget()->SetInstructions(utils::Vector{i});
 
@@ -235,9 +235,9 @@
 
     auto* i = b.CreateIf(b.Constant(true));
     i->True()->SetInstructions(utils::Vector{b.ExitIf(i, utils::Vector{b.Constant(10_i)})});
-    i->False()->SetInstructions(utils::Vector{b.Return(func, utils::Vector{b.Constant(42_i)})});
+    i->False()->SetInstructions(utils::Vector{b.Return(func, b.Constant(42_i))});
     i->Merge()->SetParams(utils::Vector{merge_param});
-    i->Merge()->SetInstructions(utils::Vector{b.Return(func, utils::Vector{merge_param})});
+    i->Merge()->SetInstructions(utils::Vector{b.Return(func, merge_param)});
 
     func->StartTarget()->SetInstructions(utils::Vector{i});
 
@@ -279,9 +279,7 @@
     i->False()->SetInstructions(
         utils::Vector{b.ExitIf(i, utils::Vector{b.Constant(20_i), b.Constant(false)})});
     i->Merge()->SetParams(utils::Vector{merge_param_0, merge_param_1});
-    i->Merge()->SetInstructions(utils::Vector{
-        b.Return(func, utils::Vector{merge_param_0}),
-    });
+    i->Merge()->SetInstructions(utils::Vector{b.Return(func, merge_param_0)});
 
     func->StartTarget()->SetInstructions(utils::Vector{i});
 
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_switch_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_switch_test.cc
index 64e9491..165a942 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_switch_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_switch_test.cc
@@ -276,7 +276,7 @@
     auto* s = b.CreateSwitch(b.Constant(42_i));
     auto* case_a = b.CreateCase(s, utils::Vector{ir::Switch::CaseSelector{b.Constant(1_i)},
                                                  ir::Switch::CaseSelector{nullptr}});
-    case_a->Append(b.Return(func, utils::Vector{b.Constant(10_i)}));
+    case_a->Append(b.Return(func, b.Constant(10_i)));
 
     auto* case_b = b.CreateCase(s, utils::Vector{ir::Switch::CaseSelector{b.Constant(2_i)}});
     case_b->Append(b.ExitSwitch(s, utils::Vector{b.Constant(20_i)}));
@@ -326,7 +326,7 @@
     case_b->Append(b.ExitSwitch(s, utils::Vector{b.Constant(20_i), b.Constant(false)}));
 
     s->Merge()->SetParams(utils::Vector{merge_param_0, merge_param_1});
-    s->Merge()->Append(b.Return(func, utils::Vector{merge_param_0}));
+    s->Merge()->Append(b.Return(func, merge_param_0));
 
     func->StartTarget()->SetInstructions(utils::Vector{s});