[ir][spirv-writer] Add support for return values
Bug: tint:1906
Change-Id: I73eb7ed2479c0f8051939163416c660c2f4faf05
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/134200
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir.cc b/src/tint/writer/spirv/ir/generator_impl_ir.cc
index 44bead9..9446cb0 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir.cc
@@ -332,11 +332,14 @@
b->To(),
[&](const ir::Block* blk) { current_function_.push_inst(spv::Op::OpBranch, {Label(blk)}); },
[&](const ir::FunctionTerminator*) {
- // TODO(jrprice): Handle the return value, which will be a branch argument.
if (!b->Args().IsEmpty()) {
- TINT_ICE(Writer, diagnostics_) << "unimplemented return value";
+ TINT_ASSERT(Writer, b->Args().Length() == 1u);
+ OperandList operands;
+ operands.push_back(Value(b->Args()[0]));
+ current_function_.push_inst(spv::Op::OpReturnValue, operands);
+ } else {
+ current_function_.push_inst(spv::Op::OpReturn, {});
}
- current_function_.push_inst(spv::Op::OpReturn, {});
},
[&](Default) {
// A block may not have an outward branch (e.g. an unreachable merge
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 80f8c06..6d7756d 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
@@ -138,5 +138,22 @@
)");
}
+TEST_F(SpvGeneratorImplTest, Function_ReturnValue) {
+ auto* func = b.CreateFunction("foo", mod.types.i32());
+ func->StartTarget()->SetInstructions(
+ utils::Vector{b.Branch(func->EndTarget(), utils::Vector{b.Constant(i32(42))})});
+
+ generator_.EmitFunction(func);
+ EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
+%2 = OpTypeInt 32 1
+%3 = OpTypeFunction %2
+%5 = OpConstant %2 42
+%1 = OpFunction %2 None %3
+%4 = OpLabel
+OpReturnValue %5
+OpFunctionEnd
+)");
+}
+
} // namespace
} // namespace tint::writer::spirv