tint/hlsl: implement trunc in terms of floor/ceil to work around FXC bug

Bug: tint:1883
Change-Id: If6c160da0684353a873428a08063aa91ee7a01c4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/125420
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 4910f81..2c4279c 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -997,6 +997,9 @@
     if (type == builtin::Function::kQuantizeToF16) {
         return EmitQuantizeToF16Call(out, expr, builtin);
     }
+    if (type == builtin::Function::kTrunc) {
+        return EmitTruncCall(out, expr, builtin);
+    }
     if (builtin->IsDataPacking()) {
         return EmitDataPackingCall(out, expr, builtin);
     }
@@ -2116,6 +2119,20 @@
     return true;
 }
 
+bool GeneratorImpl::EmitTruncCall(utils::StringStream& out,
+                                  const ast::CallExpression* expr,
+                                  const sem::Builtin* builtin) {
+    // HLSL's trunc is broken for very large/small float values.
+    // See crbug.com/tint/1883
+    return CallBuiltinHelper(  //
+        out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) {
+            // value < 0 ? ceil(value) : floor(value)
+            line(b) << "return " << params[0] << " < 0 ? ceil(" << params[0] << ") : floor("
+                    << params[0] << ");";
+            return true;
+        });
+}
+
 bool GeneratorImpl::EmitDataPackingCall(utils::StringStream& out,
                                         const ast::CallExpression* expr,
                                         const sem::Builtin* builtin) {
@@ -2704,7 +2721,6 @@
         case builtin::Function::kTan:
         case builtin::Function::kTanh:
         case builtin::Function::kTranspose:
-        case builtin::Function::kTrunc:
             return builtin->str();
         case builtin::Function::kCountOneBits:  // uint
             return "countbits";
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index f7adc9f..103e355 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -281,6 +281,14 @@
     bool EmitQuantizeToF16Call(utils::StringStream& out,
                                const ast::CallExpression* expr,
                                const sem::Builtin* builtin);
+    /// Handles generating a call to the `trunc()` intrinsic
+    /// @param out the output of the expression stream
+    /// @param expr the call expression
+    /// @param builtin the semantic information for the builtin
+    /// @returns true if the call expression is emitted
+    bool EmitTruncCall(utils::StringStream& out,
+                       const ast::CallExpression* expr,
+                       const sem::Builtin* builtin);
     /// Handles generating a call to DP4a builtins (dot4I8Packed and dot4U8Packed)
     /// @param out the output of the expression stream
     /// @param expr the call expression
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index d552671..75fd463 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -97,7 +97,6 @@
         case builtin::Function::kSqrt:
         case builtin::Function::kTan:
         case builtin::Function::kTanh:
-        case builtin::Function::kTrunc:
             if (type == CallParamType::kF16) {
                 return builder->Call(str.str(), "h2");
             } else {
@@ -309,8 +308,6 @@
                     BuiltinData{builtin::Function::kTan, CallParamType::kF16, "tan"},
                     BuiltinData{builtin::Function::kTanh, CallParamType::kF32, "tanh"},
                     BuiltinData{builtin::Function::kTanh, CallParamType::kF16, "tanh"},
-                    BuiltinData{builtin::Function::kTrunc, CallParamType::kF32, "trunc"},
-                    BuiltinData{builtin::Function::kTrunc, CallParamType::kF16, "trunc"},
                     /* Integer built-in */
                     BuiltinData{builtin::Function::kAbs, CallParamType::kU32, "abs"},
                     BuiltinData{builtin::Function::kClamp, CallParamType::kU32, "clamp"},
@@ -1089,6 +1086,94 @@
 )");
 }
 
+TEST_F(HlslGeneratorImplTest_Builtin, Trunc_Scalar_f32) {
+    auto* val = Var("val", ty.f32());
+    auto* call = Call("trunc", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  float val = 0.0f;
+  const float tint_symbol = tint_trunc(val);
+  return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Trunc_Vector_f32) {
+    auto* val = Var("val", ty.vec3<f32>());
+    auto* call = Call("trunc", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  float3 val = float3(0.0f, 0.0f, 0.0f);
+  const float3 tint_symbol = tint_trunc(val);
+  return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Trunc_Scalar_f16) {
+    Enable(builtin::Extension::kF16);
+
+    auto* val = Var("val", ty.f16());
+    auto* call = Call("trunc", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(float16_t tint_trunc(float16_t param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  float16_t val = float16_t(0.0h);
+  const float16_t tint_symbol = tint_trunc(val);
+  return;
+}
+)");
+}
+
+TEST_F(HlslGeneratorImplTest_Builtin, Trunc_Vector_f16) {
+    Enable(builtin::Extension::kF16);
+
+    auto* val = Var("val", ty.vec3<f16>());
+    auto* call = Call("trunc", val);
+    WrapInFunction(val, call);
+
+    GeneratorImpl& gen = SanitizeAndBuild();
+
+    ASSERT_TRUE(gen.Generate()) << gen.error();
+    EXPECT_EQ(gen.result(), R"(vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
+[numthreads(1, 1, 1)]
+void test_function() {
+  vector<float16_t, 3> val = vector<float16_t, 3>(float16_t(0.0h), float16_t(0.0h), float16_t(0.0h));
+  const vector<float16_t, 3> tint_symbol = tint_trunc(val);
+  return;
+}
+)");
+}
+
 TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
     auto* call = Call("pack4x8snorm", "p1");
     GlobalVar("p1", ty.vec4<f32>(), builtin::AddressSpace::kPrivate);
diff --git a/src/tint/writer/hlsl/generator_impl_import_test.cc b/src/tint/writer/hlsl/generator_impl_import_test.cc
index 133774a..3fbad50 100644
--- a/src/tint/writer/hlsl/generator_impl_import_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_import_test.cc
@@ -66,8 +66,7 @@
                                          HlslImportData{"sinh", "sinh"},
                                          HlslImportData{"sqrt", "sqrt"},
                                          HlslImportData{"tan", "tan"},
-                                         HlslImportData{"tanh", "tanh"},
-                                         HlslImportData{"trunc", "trunc"}));
+                                         HlslImportData{"tanh", "tanh"}));
 
 using HlslImportData_SingleIntParamTest = TestParamHelper<HlslImportData>;
 TEST_P(HlslImportData_SingleIntParamTest, IntScalar) {
@@ -125,8 +124,7 @@
                                          HlslImportData{"sinh", "sinh"},
                                          HlslImportData{"sqrt", "sqrt"},
                                          HlslImportData{"tan", "tan"},
-                                         HlslImportData{"tanh", "tanh"},
-                                         HlslImportData{"trunc", "trunc"}));
+                                         HlslImportData{"tanh", "tanh"}));
 
 using HlslImportData_DualParam_ScalarTest = TestParamHelper<HlslImportData>;
 TEST_P(HlslImportData_DualParam_ScalarTest, Float) {
diff --git a/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
index 22b7bcf..7d2dc12 100644
--- a/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
@@ -1,3 +1,7 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 cbuffer cbuffer_x_20 : register(b9, space2) {
   uint4 x_20[8];
 };
@@ -34,7 +38,7 @@
 }
 
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 void main_1() {
diff --git a/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl
index 22b7bcf..7d2dc12 100644
--- a/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl
@@ -1,3 +1,7 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 cbuffer cbuffer_x_20 : register(b9, space2) {
   uint4 x_20[8];
 };
@@ -34,7 +38,7 @@
 }
 
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 void main_1() {
diff --git a/test/tint/builtins/gen/var/trunc/103ab8.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/103ab8.wgsl.expected.dxc.hlsl
index 7325653..297fe1e 100644
--- a/test/tint/builtins/gen/var/trunc/103ab8.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/103ab8.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_103ab8() {
   vector<float16_t, 3> arg_0 = (float16_t(1.5h)).xxx;
-  vector<float16_t, 3> res = trunc(arg_0);
+  vector<float16_t, 3> res = tint_trunc(arg_0);
   prevent_dce.Store<vector<float16_t, 3> >(0u, res);
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.dxc.hlsl
index 45ad5a7..6da9949 100644
--- a/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_562d05() {
   float3 arg_0 = (1.5f).xxx;
-  float3 res = trunc(arg_0);
+  float3 res = tint_trunc(arg_0);
   prevent_dce.Store3(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.fxc.hlsl
index 45ad5a7..6da9949 100644
--- a/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/562d05.wgsl.expected.fxc.hlsl
@@ -1,8 +1,12 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_562d05() {
   float3 arg_0 = (1.5f).xxx;
-  float3 res = trunc(arg_0);
+  float3 res = tint_trunc(arg_0);
   prevent_dce.Store3(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/a56109.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/a56109.wgsl.expected.dxc.hlsl
index 82724f5..cf4c0d9 100644
--- a/test/tint/builtins/gen/var/trunc/a56109.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/a56109.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+vector<float16_t, 2> tint_trunc(vector<float16_t, 2> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_a56109() {
   vector<float16_t, 2> arg_0 = (float16_t(1.5h)).xx;
-  vector<float16_t, 2> res = trunc(arg_0);
+  vector<float16_t, 2> res = tint_trunc(arg_0);
   prevent_dce.Store<vector<float16_t, 2> >(0u, res);
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/cc2b0d.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/cc2b0d.wgsl.expected.dxc.hlsl
index 9b26482..8731bf2 100644
--- a/test/tint/builtins/gen/var/trunc/cc2b0d.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/cc2b0d.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+float16_t tint_trunc(float16_t param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_cc2b0d() {
   float16_t arg_0 = float16_t(1.5h);
-  float16_t res = trunc(arg_0);
+  float16_t res = tint_trunc(arg_0);
   prevent_dce.Store<float16_t>(0u, res);
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/ce7c17.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/ce7c17.wgsl.expected.dxc.hlsl
index 9cda36f..4e8cb2b 100644
--- a/test/tint/builtins/gen/var/trunc/ce7c17.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/ce7c17.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+vector<float16_t, 4> tint_trunc(vector<float16_t, 4> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_ce7c17() {
   vector<float16_t, 4> arg_0 = (float16_t(1.5h)).xxxx;
-  vector<float16_t, 4> res = trunc(arg_0);
+  vector<float16_t, 4> res = tint_trunc(arg_0);
   prevent_dce.Store<vector<float16_t, 4> >(0u, res);
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.dxc.hlsl
index 4049c45..5d762df 100644
--- a/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+float4 tint_trunc(float4 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_e183aa() {
   float4 arg_0 = (1.5f).xxxx;
-  float4 res = trunc(arg_0);
+  float4 res = tint_trunc(arg_0);
   prevent_dce.Store4(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.fxc.hlsl
index 4049c45..5d762df 100644
--- a/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/e183aa.wgsl.expected.fxc.hlsl
@@ -1,8 +1,12 @@
+float4 tint_trunc(float4 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_e183aa() {
   float4 arg_0 = (1.5f).xxxx;
-  float4 res = trunc(arg_0);
+  float4 res = tint_trunc(arg_0);
   prevent_dce.Store4(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.dxc.hlsl
index 39e592a..7cf7811 100644
--- a/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_eb83df() {
   float arg_0 = 1.5f;
-  float res = trunc(arg_0);
+  float res = tint_trunc(arg_0);
   prevent_dce.Store(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.fxc.hlsl
index 39e592a..7cf7811 100644
--- a/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/eb83df.wgsl.expected.fxc.hlsl
@@ -1,8 +1,12 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_eb83df() {
   float arg_0 = 1.5f;
-  float res = trunc(arg_0);
+  float res = tint_trunc(arg_0);
   prevent_dce.Store(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.dxc.hlsl
index 6077e4d..715c2d6 100644
--- a/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.dxc.hlsl
@@ -1,8 +1,12 @@
+float2 tint_trunc(float2 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_f370d3() {
   float2 arg_0 = (1.5f).xx;
-  float2 res = trunc(arg_0);
+  float2 res = tint_trunc(arg_0);
   prevent_dce.Store2(0u, asuint(res));
 }
 
diff --git a/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.fxc.hlsl
index 6077e4d..715c2d6 100644
--- a/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/var/trunc/f370d3.wgsl.expected.fxc.hlsl
@@ -1,8 +1,12 @@
+float2 tint_trunc(float2 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 RWByteAddressBuffer prevent_dce : register(u0, space2);
 
 void trunc_f370d3() {
   float2 arg_0 = (1.5f).xx;
-  float2 res = trunc(arg_0);
+  float2 res = tint_trunc(arg_0);
   prevent_dce.Store2(0u, asuint(res));
 }
 
diff --git a/test/tint/expressions/binary/mod/scalar-scalar/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/f16.wgsl.expected.dxc.hlsl
index ad0a421..ca63e83 100644
--- a/test/tint/expressions/binary/mod/scalar-scalar/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/scalar-scalar/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float16_t tint_trunc(float16_t param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.dxc.hlsl
index 0c9eb2e..d877f62 100644
--- a/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.fxc.hlsl
index 0c9eb2e..d877f62 100644
--- a/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod/scalar-scalar/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/scalar-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/f16.wgsl.expected.dxc.hlsl
index 99ffb58..ac7ecfa 100644
--- a/test/tint/expressions/binary/mod/scalar-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/scalar-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,10 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 vector<float16_t, 3> tint_float_mod(float16_t lhs, vector<float16_t, 3> rhs) {
   const vector<float16_t, 3> l = vector<float16_t, 3>((lhs).xxx);
-  return (l - (trunc((l / rhs)) * rhs));
+  return (l - (tint_trunc((l / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.dxc.hlsl
index c864275..e157fd9 100644
--- a/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.dxc.hlsl
@@ -1,6 +1,10 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float lhs, float3 rhs) {
   const float3 l = float3((lhs).xxx);
-  return (l - (trunc((l / rhs)) * rhs));
+  return (l - (tint_trunc((l / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.fxc.hlsl
index c864275..e157fd9 100644
--- a/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod/scalar-vec3/f32.wgsl.expected.fxc.hlsl
@@ -1,6 +1,10 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float lhs, float3 rhs) {
   const float3 l = float3((lhs).xxx);
-  return (l - (trunc((l / rhs)) * rhs));
+  return (l - (tint_trunc((l / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/vec3-scalar/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/f16.wgsl.expected.dxc.hlsl
index a8976e9..674f37a 100644
--- a/test/tint/expressions/binary/mod/vec3-scalar/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/vec3-scalar/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,10 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, float16_t rhs) {
   const vector<float16_t, 3> r = vector<float16_t, 3>((rhs).xxx);
-  return (lhs - (trunc((lhs / r)) * r));
+  return (lhs - (tint_trunc((lhs / r)) * r));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.dxc.hlsl
index c61e266..9b1c9e8 100644
--- a/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.dxc.hlsl
@@ -1,6 +1,10 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float rhs) {
   const float3 r = float3((rhs).xxx);
-  return (lhs - (trunc((lhs / r)) * r));
+  return (lhs - (tint_trunc((lhs / r)) * r));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.fxc.hlsl
index c61e266..9b1c9e8 100644
--- a/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod/vec3-scalar/f32.wgsl.expected.fxc.hlsl
@@ -1,6 +1,10 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float rhs) {
   const float3 r = float3((rhs).xxx);
-  return (lhs - (trunc((lhs / r)) * r));
+  return (lhs - (tint_trunc((lhs / r)) * r));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/vec3-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/f16.wgsl.expected.dxc.hlsl
index 69ff97a..f155a84 100644
--- a/test/tint/expressions/binary/mod/vec3-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/vec3-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.dxc.hlsl
index b03e6c8..494f4ce 100644
--- a/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.fxc.hlsl
index b03e6c8..494f4ce 100644
--- a/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod/vec3-vec3/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f16.wgsl.expected.dxc.hlsl
index 45c8ee1..97fecd1 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float16_t tint_trunc(float16_t param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.dxc.hlsl
index 515bcfb..ae4c471 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.fxc.hlsl
index 515bcfb..ae4c471 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f16.wgsl.expected.dxc.hlsl
index 8e4d644..b0c681a 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.dxc.hlsl
index 0cd0191..286cf50 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.fxc.hlsl
index 0cd0191..286cf50 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f16.wgsl.expected.dxc.hlsl
index 649bbd2..375c800 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float16_t tint_trunc(float16_t param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.dxc.hlsl
index 6af8624..acdbe86 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.fxc.hlsl
index 6af8624..acdbe86 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f16.wgsl.expected.dxc.hlsl
index dfe3a63..eeaad40 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.dxc.hlsl
index ff6fdd4..c020660 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.fxc.hlsl
index ff6fdd4..c020660 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f16.wgsl.expected.dxc.hlsl
index 7ee2e0b..00842ca 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float16_t tint_trunc(float16_t param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.dxc.hlsl
index 0fc0aef..022984c 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.fxc.hlsl
index 0fc0aef..022984c 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f16.wgsl.expected.dxc.hlsl
index 4c47f3b..51ad062 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+vector<float16_t, 3> tint_trunc(vector<float16_t, 3> param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.dxc.hlsl
index f6fdd4c..65bfe56 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.dxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.fxc.hlsl
index f6fdd4c..65bfe56 100644
--- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/f32.wgsl.expected.fxc.hlsl
@@ -1,5 +1,9 @@
+float3 tint_trunc(float3 param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 float3 tint_float_mod(float3 lhs, float3 rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.dxc.hlsl
index 314a630..cd21f94 100644
--- a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.dxc.hlsl
@@ -1,3 +1,7 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 [numthreads(1, 1, 1)]
 void unused_entry_point() {
   return;
@@ -20,7 +24,7 @@
 }
 
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 void foo(int maybe_zero) {
diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl
index 314a630..cd21f94 100644
--- a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl
@@ -1,3 +1,7 @@
+float tint_trunc(float param_0) {
+  return param_0 < 0 ? ceil(param_0) : floor(param_0);
+}
+
 [numthreads(1, 1, 1)]
 void unused_entry_point() {
   return;
@@ -20,7 +24,7 @@
 }
 
 float tint_float_mod(float lhs, float rhs) {
-  return (lhs - (trunc((lhs / rhs)) * rhs));
+  return (lhs - (tint_trunc((lhs / rhs)) * rhs));
 }
 
 void foo(int maybe_zero) {
diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt
index 16acd40..c8ff226 100644
--- a/webgpu-cts/expectations.txt
+++ b/webgpu-cts/expectations.txt
@@ -718,19 +718,6 @@
 crbug.com/dawn/0000 [ amd-0x67ef dawn-backend-validation ventura ] webgpu:shader,execution,expression,binary,f32_arithmetic:addition:inputSource="uniform";vectorize="_undef_" [ Failure ]
 crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 ubuntu ] webgpu:shader,execution,expression,binary,f32_arithmetic:addition_compound:inputSource="const";vectorize=3 [ Slow ]
 crbug.com/dawn/0000 [ dawn-backend-validation intel-0x3e9b monterey ] webgpu:shader,execution,expression,binary,f32_arithmetic:addition_scalar_vector:inputSource="storage_rw";dim=2 [ Failure ]
-crbug.com/dawn/0000 [ dawn-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize="_undef_" [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize="_undef_" [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize="_undef_" [ Failure ]
-crbug.com/dawn/0000 [ dawn-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=2 [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=2 [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=2 [ Failure ]
-crbug.com/dawn/0000 [ dawn-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=3 [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=3 [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=3 [ Failure ]
-crbug.com/dawn/0000 [ dawn-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=4 [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 ubuntu ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=4 [ Slow ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=4 [ Failure ]
-crbug.com/dawn/0000 [ dawn-no-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_compound:inputSource="const";vectorize=4 [ Failure ]
 crbug.com/dawn/0000 [ dawn-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_vector_scalar_compound:inputSource="const";dim=2 [ Failure ]
 crbug.com/dawn/0000 [ dawn-no-backend-validation intel-0x9bc5 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_vector_scalar_compound:inputSource="const";dim=2 [ Failure ]
 crbug.com/dawn/0000 [ dawn-no-backend-validation nvidia-0x2184 win10 ] webgpu:shader,execution,expression,binary,f32_arithmetic:remainder_vector_scalar_compound:inputSource="const";dim=2 [ Failure ]