[msl] Polyfill pack2x16float
Also add unit test for unpack2x16float which was missed when that
polyfill was added.
Bug: 42251016
Change-Id: Ifea9f38185d629395b11ade214625e661cda9c5d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/199897
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Natalie Chouinard <chouinard@google.com>
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
index 5fda95e..b4c0759 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
@@ -101,6 +101,7 @@
case core::BuiltinFn::kFrexp:
case core::BuiltinFn::kLength:
case core::BuiltinFn::kModf:
+ case core::BuiltinFn::kPack2X16Float:
case core::BuiltinFn::kQuantizeToF16:
case core::BuiltinFn::kSign:
case core::BuiltinFn::kTextureDimensions:
@@ -246,6 +247,9 @@
break;
// Pack/unpack builtins.
+ case core::BuiltinFn::kPack2X16Float:
+ Pack2x16Float(builtin);
+ break;
case core::BuiltinFn::kUnpack2X16Float:
Unpack2x16Float(builtin);
break;
@@ -438,6 +442,18 @@
builtin->Destroy();
}
+ /// Polyfill an Pack2x16Float call.
+ /// @param builtin the builtin call instruction
+ void Pack2x16Float(core::ir::CoreBuiltinCall* builtin) {
+ // Replace the call with `as_type<uint>(half2(value))`.
+ b.InsertBefore(builtin, [&] {
+ auto* convert = b.Convert<vec2<f16>>(builtin->Args()[0]);
+ auto* bitcast = b.Bitcast(ty.u32(), convert);
+ bitcast->SetResults(Vector{builtin->DetachResult()});
+ });
+ builtin->Destroy();
+ }
+
/// Polyfill a quantizeToF16 call.
/// @param builtin the builtin call instruction
void QuantizeToF16(core::ir::CoreBuiltinCall* builtin) {
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
index 496f342..5c1a409 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
@@ -3213,5 +3213,73 @@
EXPECT_EQ(expect, str());
}
+TEST_F(MslWriter_BuiltinPolyfillTest, Pack2x16Float) {
+ auto* func = b.Function("foo", ty.u32());
+ auto* input = b.FunctionParam("input", ty.vec2<f32>());
+ func->SetParams(Vector{input});
+ b.Append(func->Block(), [&] {
+ auto* result = b.Call<u32>(core::BuiltinFn::kPack2X16Float, input);
+ b.Return(func, result);
+ });
+
+ auto* src = R"(
+%foo = func(%input:vec2<f32>):u32 {
+ $B1: {
+ %3:u32 = pack2x16float %input
+ ret %3
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = func(%input:vec2<f32>):u32 {
+ $B1: {
+ %3:vec2<f16> = convert %input
+ %4:u32 = bitcast %3
+ ret %4
+ }
+}
+)";
+
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, Unpack2x16Float) {
+ auto* func = b.Function("foo", ty.vec2<f32>());
+ auto* input = b.FunctionParam("input", ty.u32());
+ func->SetParams(Vector{input});
+ b.Append(func->Block(), [&] {
+ auto* result = b.Call<vec2<f32>>(core::BuiltinFn::kUnpack2X16Float, input);
+ b.Return(func, result);
+ });
+
+ auto* src = R"(
+%foo = func(%input:u32):vec2<f32> {
+ $B1: {
+ %3:vec2<f32> = unpack2x16float %input
+ ret %3
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = func(%input:u32):vec2<f32> {
+ $B1: {
+ %3:vec2<f16> = bitcast %input
+ %4:vec2<f32> = convert %3
+ ret %4
+ }
+}
+)";
+
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
} // namespace
} // namespace tint::msl::writer::raise
diff --git a/test/tint/builtins/gen/var/pack2x16float/0e97b3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/pack2x16float/0e97b3.wgsl.expected.ir.msl
index 88b650d..b99130b0 100644
--- a/test/tint/builtins/gen/var/pack2x16float/0e97b3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/pack2x16float/0e97b3.wgsl.expected.ir.msl
@@ -1,9 +1,44 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: pack2x16float
-********************************************************************
-* 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. *
-********************************************************************
+struct tint_module_vars_struct {
+ device uint* prevent_dce;
+};
+
+struct VertexOutput {
+ float4 pos;
+ uint prevent_dce;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+ uint VertexOutput_prevent_dce [[user(locn0)]] [[flat]];
+};
+
+uint pack2x16float_0e97b3() {
+ float2 arg_0 = float2(1.0f);
+ uint res = as_type<uint>(half2(arg_0));
+ return res;
+}
+
+fragment void fragment_main(device uint* prevent_dce [[buffer(0)]]) {
+ tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce};
+ (*tint_module_vars.prevent_dce) = pack2x16float_0e97b3();
+}
+
+kernel void compute_main(device uint* prevent_dce [[buffer(0)]]) {
+ tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce};
+ (*tint_module_vars.prevent_dce) = pack2x16float_0e97b3();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ out.prevent_dce = pack2x16float_0e97b3();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ VertexOutput const v = vertex_main_inner();
+ return vertex_main_outputs{.VertexOutput_pos=v.pos, .VertexOutput_prevent_dce=v.prevent_dce};
+}