[msl] Add polyfill for modf
MSL's modf returns `fract` and outputs `whole` as an output
parameter. Polyfill it by declaring the result struct and then setting
the values.
Bug: 42251016
Change-Id: I20b1b44e5384948b4236cca8f563320d7e0f5b0d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196359
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/msl/builtin_fn.cc b/src/tint/lang/msl/builtin_fn.cc
index e23f008..c522933 100644
--- a/src/tint/lang/msl/builtin_fn.cc
+++ b/src/tint/lang/msl/builtin_fn.cc
@@ -98,6 +98,8 @@
return "fmod";
case BuiltinFn::kLength:
return "length";
+ case BuiltinFn::kModf:
+ return "modf";
case BuiltinFn::kSign:
return "sign";
case BuiltinFn::kThreadgroupBarrier:
diff --git a/src/tint/lang/msl/builtin_fn.h b/src/tint/lang/msl/builtin_fn.h
index d28064f..8da3f08 100644
--- a/src/tint/lang/msl/builtin_fn.h
+++ b/src/tint/lang/msl/builtin_fn.h
@@ -75,6 +75,7 @@
kDot,
kFmod,
kLength,
+ kModf,
kSign,
kThreadgroupBarrier,
kNone,
diff --git a/src/tint/lang/msl/intrinsic/data.cc b/src/tint/lang/msl/intrinsic/data.cc
index b73cce94..b60151f 100644
--- a/src/tint/lang/msl/intrinsic/data.cc
+++ b/src/tint/lang/msl/intrinsic/data.cc
@@ -4870,13 +4870,20 @@
},
{
/* [28] */
+ /* fn modf[T : f32_f16](T, T) -> T */
+ /* fn modf[N : num, T : f32_f16](vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ OverloadIndex(156),
+ },
+ {
+ /* [29] */
/* fn sign[T : f32_f16](T) -> T */
/* fn sign[N : num, T : f32_f16](vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
/* overloads */ OverloadIndex(158),
},
{
- /* [29] */
+ /* [30] */
/* fn threadgroup_barrier(u32) */
/* num overloads */ 1,
/* overloads */ OverloadIndex(166),
diff --git a/src/tint/lang/msl/msl.def b/src/tint/lang/msl/msl.def
index 01ec90f..d2e8264 100644
--- a/src/tint/lang/msl/msl.def
+++ b/src/tint/lang/msl/msl.def
@@ -326,6 +326,8 @@
fn fmod[T: f32_f16](T, T) -> T
fn fmod[N: num, T: f32_f16](vec<N, T>, vec<N, T>) -> vec<N, T>
fn length[N: num, T: f32_f16](vec<N, T>) -> T
+fn modf[T: f32_f16](T, T) -> T
+fn modf[N: num, T: f32_f16](vec<N, T>, vec<N, T>) -> vec<N, T>
fn sign[T: f32_f16](T) -> T
fn sign[N: num, T: f32_f16](vec<N, T>) -> vec<N, T>
@stage("compute") fn threadgroup_barrier(u32)
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
index a2426b8..0b7ce2b 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
@@ -100,6 +100,7 @@
case core::BuiltinFn::kDistance:
case core::BuiltinFn::kDot:
case core::BuiltinFn::kLength:
+ case core::BuiltinFn::kModf:
case core::BuiltinFn::kQuantizeToF16:
case core::BuiltinFn::kSign:
case core::BuiltinFn::kTextureDimensions:
@@ -181,6 +182,9 @@
case core::BuiltinFn::kLength:
Length(builtin);
break;
+ case core::BuiltinFn::kModf:
+ Modf(builtin);
+ break;
case core::BuiltinFn::kQuantizeToF16:
QuantizeToF16(builtin);
break;
@@ -386,6 +390,33 @@
builtin->Destroy();
}
+ /// Polyfill a modf call.
+ /// @param builtin the builtin call instruction
+ void Modf(core::ir::CoreBuiltinCall* builtin) {
+ b.InsertBefore(builtin, [&] {
+ // MSL's modf returns `fract` and outputs `whole` as an output parameter.
+ // Polyfill it by declaring the result struct and then setting the values:
+ // __modf_result result = {};
+ // result.fract = modf(arg, result.whole);
+ //
+ // Note: We need to use a `load` instruction to pass `result.whole`, as the intrinsic
+ // definition expects a value type (as we do not have reference types in the IR). The
+ // printer will just fold away the load, which achieves the pass-by-reference semantics
+ // that we want.
+ //
+ auto* result_type = builtin->Result(0)->Type();
+ auto* element_type = result_type->Element(0);
+ auto* result = b.Var(ty.ptr(function, result_type));
+ auto* whole = b.Access(ty.ptr(function, element_type), result, u32(1));
+ auto args = Vector<core::ir::Value*, 2>{builtin->Args()[0], b.Load(whole)->Result(0)};
+ auto* call =
+ b.Call<msl::ir::BuiltinCall>(element_type, msl::BuiltinFn::kModf, std::move(args));
+ b.Store(b.Access(ty.ptr(function, element_type), result, u32(0)), call);
+ builtin->Result(0)->ReplaceAllUsesWith(b.Load(result)->Result(0));
+ });
+ 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 41ca478..6537676 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
@@ -1088,6 +1088,122 @@
EXPECT_EQ(expect, str());
}
+TEST_F(MslWriter_BuiltinPolyfillTest, Modf_Scalar) {
+ auto* value = b.FunctionParam<f32>("value");
+ auto* func = b.Function("foo", ty.f32());
+ func->SetParams({value});
+ b.Append(func->Block(), [&] {
+ auto* result = b.Call(core::type::CreateModfResult(ty, mod.symbols, ty.f32()),
+ core::BuiltinFn::kModf, value);
+ auto* fract = b.Access<f32>(result, 0_u);
+ auto* whole = b.Access<f32>(result, 1_u);
+ b.Return(func, b.Add<f32>(fract, whole));
+ });
+
+ auto* src = R"(
+__modf_result_f32 = struct @align(4) {
+ fract:f32 @offset(0)
+ whole:f32 @offset(4)
+}
+
+%foo = func(%value:f32):f32 {
+ $B1: {
+ %3:__modf_result_f32 = modf %value
+ %4:f32 = access %3, 0u
+ %5:f32 = access %3, 1u
+ %6:f32 = add %4, %5
+ ret %6
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+__modf_result_f32 = struct @align(4) {
+ fract:f32 @offset(0)
+ whole:f32 @offset(4)
+}
+
+%foo = func(%value:f32):f32 {
+ $B1: {
+ %3:ptr<function, __modf_result_f32, read_write> = var
+ %4:ptr<function, f32, read_write> = access %3, 1u
+ %5:f32 = load %4
+ %6:f32 = msl.modf %value, %5
+ %7:ptr<function, f32, read_write> = access %3, 0u
+ store %7, %6
+ %8:__modf_result_f32 = load %3
+ %9:f32 = access %8, 0u
+ %10:f32 = access %8, 1u
+ %11:f32 = add %9, %10
+ ret %11
+ }
+}
+)";
+
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, Modf_Vector) {
+ auto* value = b.FunctionParam<vec4<f32>>("value");
+ auto* func = b.Function("foo", ty.vec4<f32>());
+ func->SetParams({value});
+ b.Append(func->Block(), [&] {
+ auto* result = b.Call(core::type::CreateModfResult(ty, mod.symbols, ty.vec4<f32>()),
+ core::BuiltinFn::kModf, value);
+ auto* fract = b.Access<vec4<f32>>(result, 0_u);
+ auto* whole = b.Access<vec4<f32>>(result, 1_u);
+ b.Return(func, b.Add<vec4<f32>>(fract, whole));
+ });
+
+ auto* src = R"(
+__modf_result_vec4_f32 = struct @align(16) {
+ fract:vec4<f32> @offset(0)
+ whole:vec4<f32> @offset(16)
+}
+
+%foo = func(%value:vec4<f32>):vec4<f32> {
+ $B1: {
+ %3:__modf_result_vec4_f32 = modf %value
+ %4:vec4<f32> = access %3, 0u
+ %5:vec4<f32> = access %3, 1u
+ %6:vec4<f32> = add %4, %5
+ ret %6
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+__modf_result_vec4_f32 = struct @align(16) {
+ fract:vec4<f32> @offset(0)
+ whole:vec4<f32> @offset(16)
+}
+
+%foo = func(%value:vec4<f32>):vec4<f32> {
+ $B1: {
+ %3:ptr<function, __modf_result_vec4_f32, read_write> = var
+ %4:ptr<function, vec4<f32>, read_write> = access %3, 1u
+ %5:vec4<f32> = load %4
+ %6:vec4<f32> = msl.modf %value, %5
+ %7:ptr<function, vec4<f32>, read_write> = access %3, 0u
+ store %7, %6
+ %8:__modf_result_vec4_f32 = load %3
+ %9:vec4<f32> = access %8, 0u
+ %10:vec4<f32> = access %8, 1u
+ %11:vec4<f32> = add %9, %10
+ ret %11
+ }
+}
+)";
+
+ Run(BuiltinPolyfill);
+
+ EXPECT_EQ(expect, str());
+}
+
TEST_F(MslWriter_BuiltinPolyfillTest, QuantizeToF16_Scalar) {
auto* value = b.FunctionParam<f32>("value");
auto* func = b.Function("foo", ty.f32());
diff --git a/test/tint/builtins/gen/var/modf/2d50da.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/2d50da.wgsl.expected.ir.msl
index 9a4469c..6e9881b 100644
--- a/test/tint/builtins/gen/var/modf/2d50da.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/2d50da.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec2_f32 {
+ float2 fract;
+ float2 whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_2d50da() {
+ float2 arg_0 = float2(-1.5f);
+ modf_result_vec2_f32 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_vec2_f32 res = v;
+}
+
+fragment void fragment_main() {
+ modf_2d50da();
+}
+
+kernel void compute_main() {
+ modf_2d50da();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_2d50da();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/45005f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/45005f.wgsl.expected.ir.msl
index 9a4469c..e8d3a98 100644
--- a/test/tint/builtins/gen/var/modf/45005f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/45005f.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec3_f16 {
+ half3 fract;
+ half3 whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_45005f() {
+ half3 arg_0 = half3(-1.5h);
+ modf_result_vec3_f16 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_vec3_f16 res = v;
+}
+
+fragment void fragment_main() {
+ modf_45005f();
+}
+
+kernel void compute_main() {
+ modf_45005f();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_45005f();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/4bfced.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/4bfced.wgsl.expected.ir.msl
index 9a4469c..dfa275f 100644
--- a/test/tint/builtins/gen/var/modf/4bfced.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/4bfced.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec4_f32 {
+ float4 fract;
+ float4 whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_4bfced() {
+ float4 arg_0 = float4(-1.5f);
+ modf_result_vec4_f32 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_vec4_f32 res = v;
+}
+
+fragment void fragment_main() {
+ modf_4bfced();
+}
+
+kernel void compute_main() {
+ modf_4bfced();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_4bfced();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/5ea256.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/5ea256.wgsl.expected.ir.msl
index 9a4469c..4e3a867 100644
--- a/test/tint/builtins/gen/var/modf/5ea256.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/5ea256.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec3_f32 {
+ float3 fract;
+ float3 whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_5ea256() {
+ float3 arg_0 = float3(-1.5f);
+ modf_result_vec3_f32 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_vec3_f32 res = v;
+}
+
+fragment void fragment_main() {
+ modf_5ea256();
+}
+
+kernel void compute_main() {
+ modf_5ea256();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_5ea256();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/8dbbbf.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/8dbbbf.wgsl.expected.ir.msl
index 9a4469c..bb92f98 100644
--- a/test/tint/builtins/gen/var/modf/8dbbbf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/8dbbbf.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_f16 {
+ half fract;
+ half whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_8dbbbf() {
+ half arg_0 = -1.5h;
+ modf_result_f16 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_f16 res = v;
+}
+
+fragment void fragment_main() {
+ modf_8dbbbf();
+}
+
+kernel void compute_main() {
+ modf_8dbbbf();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_8dbbbf();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/995934.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/995934.wgsl.expected.ir.msl
index 9a4469c..3f1f8a3 100644
--- a/test/tint/builtins/gen/var/modf/995934.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/995934.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec4_f16 {
+ half4 fract;
+ half4 whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_995934() {
+ half4 arg_0 = half4(-1.5h);
+ modf_result_vec4_f16 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_vec4_f16 res = v;
+}
+
+fragment void fragment_main() {
+ modf_995934();
+}
+
+kernel void compute_main() {
+ modf_995934();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_995934();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/a545b9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/a545b9.wgsl.expected.ir.msl
index 9a4469c..8095cbc 100644
--- a/test/tint/builtins/gen/var/modf/a545b9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/a545b9.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec2_f16 {
+ half2 fract;
+ half2 whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_a545b9() {
+ half2 arg_0 = half2(-1.5h);
+ modf_result_vec2_f16 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_vec2_f16 res = v;
+}
+
+fragment void fragment_main() {
+ modf_a545b9();
+}
+
+kernel void compute_main() {
+ modf_a545b9();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_a545b9();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/gen/var/modf/bbf7f7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/modf/bbf7f7.wgsl.expected.ir.msl
index 9a4469c..68035c9 100644
--- a/test/tint/builtins/gen/var/modf/bbf7f7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/modf/bbf7f7.wgsl.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_f32 {
+ float fract;
+ float whole;
+};
+
+struct VertexOutput {
+ float4 pos;
+};
+
+struct vertex_main_outputs {
+ float4 VertexOutput_pos [[position]];
+};
+
+void modf_bbf7f7() {
+ float arg_0 = -1.5f;
+ modf_result_f32 v = {};
+ v.fract = modf(arg_0, v.whole);
+ modf_result_f32 res = v;
+}
+
+fragment void fragment_main() {
+ modf_bbf7f7();
+}
+
+kernel void compute_main() {
+ modf_bbf7f7();
+}
+
+VertexOutput vertex_main_inner() {
+ VertexOutput out = {};
+ out.pos = float4(0.0f);
+ modf_bbf7f7();
+ return out;
+}
+
+vertex vertex_main_outputs vertex_main() {
+ return vertex_main_outputs{.VertexOutput_pos=vertex_main_inner().pos};
+}
diff --git a/test/tint/builtins/modf/scalar/mixed.wgsl.expected.ir.msl b/test/tint/builtins/modf/scalar/mixed.wgsl.expected.ir.msl
index 9a4469c..e51943a 100644
--- a/test/tint/builtins/modf/scalar/mixed.wgsl.expected.ir.msl
+++ b/test/tint/builtins/modf/scalar/mixed.wgsl.expected.ir.msl
@@ -1,9 +1,18 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_f32 {
+ float fract;
+ float whole;
+};
+
+kernel void tint_symbol() {
+ float const runtime_in = 1.25f;
+ modf_result_f32 res = modf_result_f32{.fract=0.25f, .whole=1.0f};
+ modf_result_f32 v = {};
+ v.fract = modf(runtime_in, v.whole);
+ res = v;
+ res = modf_result_f32{.fract=0.25f, .whole=1.0f};
+ float const fract = res.fract;
+ float const whole = res.whole;
+}
diff --git a/test/tint/builtins/modf/scalar/runtime.wgsl.expected.ir.msl b/test/tint/builtins/modf/scalar/runtime.wgsl.expected.ir.msl
index 9a4469c..fb2b667 100644
--- a/test/tint/builtins/modf/scalar/runtime.wgsl.expected.ir.msl
+++ b/test/tint/builtins/modf/scalar/runtime.wgsl.expected.ir.msl
@@ -1,9 +1,16 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_f32 {
+ float fract;
+ float whole;
+};
+
+kernel void tint_symbol() {
+ float const in = 1.25f;
+ modf_result_f32 v = {};
+ v.fract = modf(in, v.whole);
+ modf_result_f32 const res = v;
+ float const fract = res.fract;
+ float const whole = res.whole;
+}
diff --git a/test/tint/builtins/modf/vector/mixed.wgsl.expected.ir.msl b/test/tint/builtins/modf/vector/mixed.wgsl.expected.ir.msl
index 9a4469c..33408f9 100644
--- a/test/tint/builtins/modf/vector/mixed.wgsl.expected.ir.msl
+++ b/test/tint/builtins/modf/vector/mixed.wgsl.expected.ir.msl
@@ -1,9 +1,18 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec2_f32 {
+ float2 fract;
+ float2 whole;
+};
+
+kernel void tint_symbol() {
+ float2 const runtime_in = float2(1.25f, 3.75f);
+ modf_result_vec2_f32 res = modf_result_vec2_f32{.fract=float2(0.25f, 0.75f), .whole=float2(1.0f, 3.0f)};
+ modf_result_vec2_f32 v = {};
+ v.fract = modf(runtime_in, v.whole);
+ res = v;
+ res = modf_result_vec2_f32{.fract=float2(0.25f, 0.75f), .whole=float2(1.0f, 3.0f)};
+ float2 const fract = res.fract;
+ float2 const whole = res.whole;
+}
diff --git a/test/tint/builtins/modf/vector/runtime.wgsl.expected.ir.msl b/test/tint/builtins/modf/vector/runtime.wgsl.expected.ir.msl
index 9a4469c..9cb2a79 100644
--- a/test/tint/builtins/modf/vector/runtime.wgsl.expected.ir.msl
+++ b/test/tint/builtins/modf/vector/runtime.wgsl.expected.ir.msl
@@ -1,9 +1,16 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-../../src/tint/lang/msl/writer/printer/printer.cc:989 internal compiler error: TINT_UNREACHABLE unhandled: modf
-********************************************************************
-* 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 modf_result_vec2_f32 {
+ float2 fract;
+ float2 whole;
+};
+
+kernel void tint_symbol() {
+ float2 const in = float2(1.25f, 3.75f);
+ modf_result_vec2_f32 v = {};
+ v.fract = modf(in, v.whole);
+ modf_result_vec2_f32 const res = v;
+ float2 const fract = res.fract;
+ float2 const whole = res.whole;
+}