[tint][hlsl] Only polyfill trunc on FXC

The HLSL polyfill for trunc was added in:
https://dawn-review.googlesource.com/c/dawn/+/125420
to work around an FXC bug, but causes issues on newer Intel devices
using DXC, which have different flushing to zero behavior for subnormals
(see https://crbug.com/42251226), which then affects the polyfill of
remainder causing incorrect values for some f16 cases.

We can avoid this affecting remainder on Intel by limiting the polyfill
of trunc to FXC where it's actually needed.

As a follow up we should confirm whether there is a driver issue on
Intel that still needs to be covered by a new CTS test for use of
floor/ceil directly in WGSL.

Bug: 390458364
Change-Id: I79aec18393afa19f3c9047dd3ecaed0d6a6a6964
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/302655
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Natalie Chouinard <chouinard@google.com>
diff --git a/src/tint/lang/hlsl/writer/binary_test.cc b/src/tint/lang/hlsl/writer/binary_test.cc
index 3271f04..d600f6c 100644
--- a/src/tint/lang/hlsl/writer/binary_test.cc
+++ b/src/tint/lang/hlsl/writer/binary_test.cc
@@ -242,7 +242,7 @@
   float v = left;
   float v_1 = right;
   float v_2 = (v / v_1);
-  float val = (v - ((((v_2 < 0.0f)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float val = (v - (trunc(v_2) * v_1));
 }
 
 )");
@@ -272,7 +272,7 @@
   float16_t v = left;
   float16_t v_1 = right;
   float16_t v_2 = (v / v_1);
-  float16_t val = (v - ((((v_2 < float16_t(0.0h))) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float16_t val = (v - (trunc(v_2) * v_1));
 }
 
 )");
@@ -302,7 +302,7 @@
   float3 v = left;
   float3 v_1 = right;
   float3 v_2 = (v / v_1);
-  float3 val = (v - ((((v_2 < (0.0f).xxx)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float3 val = (v - (trunc(v_2) * v_1));
 }
 
 )");
@@ -332,7 +332,7 @@
   vector<float16_t, 3> v = left;
   vector<float16_t, 3> v_1 = right;
   vector<float16_t, 3> v_2 = (v / v_1);
-  vector<float16_t, 3> val = (v - ((((v_2 < (float16_t(0.0h)).xxx)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  vector<float16_t, 3> val = (v - (trunc(v_2) * v_1));
 }
 
 )");
diff --git a/src/tint/lang/hlsl/writer/builtin_test.cc b/src/tint/lang/hlsl/writer/builtin_test.cc
index 33d542c..6b08d26 100644
--- a/src/tint/lang/hlsl/writer/builtin_test.cc
+++ b/src/tint/lang/hlsl/writer/builtin_test.cc
@@ -93,7 +93,7 @@
 )");
 }
 
-TEST_F(HlslWriterTest, BuiltinTrunc) {
+TEST_F(HlslWriterTest, BuiltinTruncFxc) {
     auto* func = b.Function("main", ty.void_(), core::ir::Function::PipelineStage::kFragment);
     b.Append(func->Block(), [&] {
         auto* val = b.Var("v", b.Zero(ty.f32()));
@@ -105,7 +105,9 @@
         b.Return(func);
     });
 
-    auto result = Generate();
+    Options opts;
+    opts.compiler = Options::Compiler::kFXC;
+    auto result = Generate(opts);
     ASSERT_EQ(result, Success) << result.Failure().reason << output_.hlsl;
     EXPECT_EQ(output_.hlsl, R"(
 void main() {
@@ -117,7 +119,32 @@
 )");
 }
 
-TEST_F(HlslWriterTest, BuiltinTruncVec) {
+TEST_F(HlslWriterTest, BuiltinTruncDxc) {
+    auto* func = b.Function("main", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+    b.Append(func->Block(), [&] {
+        auto* val = b.Var("v", b.Zero(ty.f32()));
+
+        auto* v = b.Load(val);
+        auto* t = b.Call(ty.f32(), core::BuiltinFn::kTrunc, v);
+
+        b.Let("val", t);
+        b.Return(func);
+    });
+
+    Options opts;
+    opts.compiler = Options::Compiler::kDXC;
+    auto result = Generate(opts);
+    ASSERT_EQ(result, Success) << result.Failure().reason << output_.hlsl;
+    EXPECT_EQ(output_.hlsl, R"(
+void main() {
+  float v = 0.0f;
+  float val = trunc(v);
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, BuiltinTruncVecFxc) {
     auto* func = b.Function("main", ty.void_(), core::ir::Function::PipelineStage::kFragment);
     b.Append(func->Block(), [&] {
         auto* val = b.Var("v", b.Splat(ty.vec3f(), 2_f));
@@ -129,7 +156,9 @@
         b.Return(func);
     });
 
-    auto result = Generate();
+    Options opts;
+    opts.compiler = Options::Compiler::kFXC;
+    auto result = Generate(opts);
     ASSERT_EQ(result, Success) << result.Failure().reason << output_.hlsl;
     EXPECT_EQ(output_.hlsl, R"(
 void main() {
@@ -141,7 +170,7 @@
 )");
 }
 
-TEST_F(HlslWriterTest, BuiltinTruncF16) {
+TEST_F(HlslWriterTest, BuiltinTruncF16Fxc) {
     auto* func = b.Function("main", ty.void_(), core::ir::Function::PipelineStage::kFragment);
     b.Append(func->Block(), [&] {
         auto* val = b.Var("v", b.Zero(ty.f16()));
@@ -153,7 +182,9 @@
         b.Return(func);
     });
 
-    auto result = Generate();
+    Options opts;
+    opts.compiler = Options::Compiler::kFXC;
+    auto result = Generate(opts);
     ASSERT_EQ(result, Success) << result.Failure().reason << output_.hlsl;
     EXPECT_EQ(output_.hlsl, R"(
 void main() {
diff --git a/src/tint/lang/hlsl/writer/printer/printer.cc b/src/tint/lang/hlsl/writer/printer/printer.cc
index cb34f8f..6a45512 100644
--- a/src/tint/lang/hlsl/writer/printer/printer.cc
+++ b/src/tint/lang/hlsl/writer/printer/printer.cc
@@ -1070,6 +1070,7 @@
             case core::BuiltinFn::kTan:
             case core::BuiltinFn::kTanh:
             case core::BuiltinFn::kTranspose:
+            case core::BuiltinFn::kTrunc:
                 out << func;
                 break;
             case core::BuiltinFn::kCountOneBits:  // uint
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
index e275a1a..ea0050d 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
@@ -65,6 +65,9 @@
     /// The IR module.
     core::ir::Module& ir;
 
+    /// The configuration for the transform.
+    const BuiltinPolyfillConfig& config;
+
     /// The IR builder.
     core::ir::Builder b{ir};
 
@@ -142,7 +145,6 @@
                     case core::BuiltinFn::kTextureSampleGrad:
                     case core::BuiltinFn::kTextureSampleLevel:
                     case core::BuiltinFn::kTextureStore:
-                    case core::BuiltinFn::kTrunc:
                     case core::BuiltinFn::kUnpack2X16Float:
                     case core::BuiltinFn::kUnpack2X16Snorm:
                     case core::BuiltinFn::kUnpack2X16Unorm:
@@ -152,6 +154,11 @@
                     case core::BuiltinFn::kUnpack4XU8:
                         call_worklist.Push(call);
                         break;
+                    case core::BuiltinFn::kTrunc:
+                        if (config.polyfill_trunc) {
+                            call_worklist.Push(call);
+                        }
+                        break;
                     default:
                         break;
                 }
@@ -534,7 +541,7 @@
         call->Destroy();
     }
 
-    // HLSL's trunc is broken for very large/small float values.
+    // FXC's trunc is broken for very large/small float values.
     // See crbug.com/tint/1883
     //
     // Replace with:
@@ -1990,7 +1997,7 @@
 
 }  // namespace
 
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
+Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir, const BuiltinPolyfillConfig& config) {
     AssertValid(ir,
                 core::ir::Capabilities{
                     core::ir::Capability::kAllow16BitIntegers,
@@ -2000,7 +2007,7 @@
                 },
                 "before hlsl.BuiltinPolyfill");
 
-    State{ir}.Process();
+    State{ir, config}.Process();
     return Success;
 }
 
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h
index 86f8726..96b3d5d 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h
@@ -37,11 +37,19 @@
 
 namespace tint::hlsl::writer::raise {
 
+/// BuiltinPolyfillConfig describes the set of configuration options for the hlsl BuiltinPolyfill
+/// transform.
+struct BuiltinPolyfillConfig {
+    /// Set to `true` to polyfill `trunc()`.
+    bool polyfill_trunc = false;
+};
+
 /// BuiltinPolyfill is a transform that replaces calls to builtins with polyfills and calls to
 /// HLSL polyfilled or backend intrinsic functions.
 /// @param module the module to transform
+/// @param config the configuration for the transform
 /// @returns success or failure
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
+Result<SuccessType> BuiltinPolyfill(core::ir::Module& module, const BuiltinPolyfillConfig& config);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
index 77af9ac..dd56a32 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
@@ -74,7 +74,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -103,7 +103,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -132,7 +132,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -161,7 +161,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -190,7 +190,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -234,7 +234,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -280,7 +280,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -335,7 +335,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -399,7 +399,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -430,7 +430,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -461,7 +461,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -491,7 +491,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -536,7 +536,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -583,7 +583,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -616,7 +616,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -649,7 +649,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -687,7 +687,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -727,7 +727,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -768,7 +768,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -804,7 +804,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -844,7 +844,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -883,7 +883,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -921,7 +921,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -962,7 +962,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1001,7 +1001,7 @@
 )";
 
     capabilities = core::ir::Capabilities{core::ir::Capability::kAllowVectorElementPointer};
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1038,7 +1038,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1074,7 +1074,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1111,7 +1111,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1148,7 +1148,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1186,7 +1186,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1226,7 +1226,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1264,7 +1264,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1313,7 +1313,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1362,7 +1362,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1413,7 +1413,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1478,7 +1478,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1544,7 +1544,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1612,7 +1612,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1681,7 +1681,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1745,7 +1745,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1809,7 +1809,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1876,7 +1876,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -1945,7 +1945,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -2008,7 +2008,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -2071,7 +2071,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -2136,7 +2136,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -2203,7 +2203,7 @@
 }
 )";
 
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -2264,7 +2264,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2326,7 +2326,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2389,7 +2389,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2454,7 +2454,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2521,7 +2521,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2583,7 +2583,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2646,7 +2646,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2708,7 +2708,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2773,7 +2773,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2835,7 +2835,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2898,7 +2898,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -2963,7 +2963,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3029,7 +3029,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3094,7 +3094,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3156,7 +3156,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3220,7 +3220,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3286,7 +3286,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3353,7 +3353,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3415,7 +3415,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3479,7 +3479,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3541,7 +3541,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3607,7 +3607,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3668,7 +3668,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3730,7 +3730,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3795,7 +3795,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3861,7 +3861,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3922,7 +3922,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -3987,7 +3987,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4048,7 +4048,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4111,7 +4111,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4176,7 +4176,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4242,7 +4242,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4303,7 +4303,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4368,7 +4368,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4436,7 +4436,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4506,7 +4506,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4578,7 +4578,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4651,7 +4651,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4719,7 +4719,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4789,7 +4789,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4857,7 +4857,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4929,7 +4929,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -4989,7 +4989,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5051,7 +5051,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5115,7 +5115,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5181,7 +5181,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5248,7 +5248,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5310,7 +5310,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5374,7 +5374,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5436,7 +5436,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5502,7 +5502,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5565,7 +5565,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5629,7 +5629,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5695,7 +5695,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5763,7 +5763,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5829,7 +5829,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5866,7 +5866,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5923,7 +5923,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -5997,7 +5997,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -6062,7 +6062,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -6139,7 +6139,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -6218,7 +6218,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6259,7 +6259,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -6298,7 +6298,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6344,7 +6344,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6387,7 +6387,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6431,7 +6431,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6472,7 +6472,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6524,7 +6524,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6569,7 +6569,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6619,7 +6619,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6664,7 +6664,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6706,7 +6706,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6748,7 +6748,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6790,7 +6790,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6832,7 +6832,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -6869,7 +6869,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6907,7 +6907,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
 
     EXPECT_EQ(expect, str());
 }
@@ -6949,7 +6949,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -6989,7 +6989,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7029,7 +7029,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7069,7 +7069,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7107,7 +7107,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7145,7 +7145,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7180,7 +7180,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7213,7 +7213,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7249,7 +7249,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7285,7 +7285,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7318,7 +7318,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7351,7 +7351,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7403,7 +7403,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7455,7 +7455,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7511,7 +7511,7 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
     EXPECT_EQ(expect, str());
 }
 
@@ -7567,7 +7567,68 @@
   }
 }
 )";
-    Run(BuiltinPolyfill);
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{});
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Trunc) {
+    auto* a = b.FunctionParam<f32>("a");
+    auto* func = b.Function("foo", ty.f32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] { b.Return(func, b.Call(ty.f32(), core::BuiltinFn::kTrunc, a)); });
+
+    auto* src = R"(
+%foo = func(%a:f32):f32 {
+  $B1: {
+    %3:f32 = trunc %a
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:f32):f32 {
+  $B1: {
+    %3:f32 = floor %a
+    %4:f32 = ceil %a
+    %5:bool = lt %a, 0.0f
+    %6:f32 = hlsl.ternary %3, %4, %5
+    ret %6
+  }
+}
+)";
+
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{.polyfill_trunc = true});
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(HlslWriter_BuiltinPolyfillTest, Trunc_NoPolyfill) {
+    auto* a = b.FunctionParam<f32>("a");
+    auto* func = b.Function("foo", ty.f32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] { b.Return(func, b.Call(ty.f32(), core::BuiltinFn::kTrunc, a)); });
+
+    auto* src = R"(
+%foo = func(%a:f32):f32 {
+  $B1: {
+    %3:f32 = trunc %a
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:f32):f32 {
+  $B1: {
+    %3:f32 = trunc %a
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill, BuiltinPolyfillConfig{.polyfill_trunc = false});
     EXPECT_EQ(expect, str());
 }
 
diff --git a/src/tint/lang/hlsl/writer/raise/raise.cc b/src/tint/lang/hlsl/writer/raise/raise.cc
index 4f93488..9466aca 100644
--- a/src/tint/lang/hlsl/writer/raise/raise.cc
+++ b/src/tint/lang/hlsl/writer/raise/raise.cc
@@ -359,7 +359,11 @@
 
     // BuiltinPolyfill must come after BinaryPolyfill and DecomposeStorageAccess as they add
     // builtins
-    TINT_CHECK_RESULT(raise::BuiltinPolyfill(module));
+    {
+        raise::BuiltinPolyfillConfig config;
+        config.polyfill_trunc = (options.compiler == Options::Compiler::kFXC);
+        TINT_CHECK_RESULT(raise::BuiltinPolyfill(module, config));
+    }
     TINT_CHECK_RESULT(core::ir::transform::VectorizeScalarMatrixConstructors(module));
     TINT_CHECK_RESULT(core::ir::transform::RemoveContinueInSwitch(module));
 
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl
index cea7edd..b8b77c8 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl
@@ -191,9 +191,8 @@
     float sum = dot(float4(a, b, c, d), (1.0f).xxxx);
     uint v_5 = 0u;
     buf_out.GetDimensions(v_5);
-    uint v_6 = (min(dst_offset, ((v_5 / 4u) - 1u)) * 4u);
-    float v_7 = (sum / 4.0f);
-    buf_out.Store((0u + v_6), asuint((sum - ((((v_7 < 0.0f)) ? (ceil(v_7)) : (floor(v_7))) * 4.0f))));
+    float v_6 = (sum / 4.0f);
+    buf_out.Store((0u + (min(dst_offset, ((v_5 / 4u) - 1u)) * 4u)), asuint((sum - (trunc(v_6) * 4.0f))));
     float4 probabilities = (float4(a, (a * b), ((a / b) + c), sum) + max(sum, 0.0f));
     tex_out[int2(coord.xy)] = probabilities;
   }
diff --git a/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
index 90cb711..80c3fe2 100644
--- a/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
@@ -128,7 +128,7 @@
         float x_181 = asfloat(x_20[0u].x);
         float x_184 = animationData.z;
         float v_2 = ((x_181 * x_184) / 1.0f);
-        mt = ((x_181 * x_184) - ((((v_2 < 0.0f)) ? (ceil(v_2)) : (floor(v_2))) * 1.0f));
+        mt = ((x_181 * x_184) - (trunc(v_2) * 1.0f));
         f = 0.0f;
         {
           uint2 tint_loop_idx_1 = (4294967295u).xx;
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 69719d1..efc1231 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 vector<float16_t, 3> trunc_103ab8() {
   vector<float16_t, 3> arg_0 = (float16_t(1.5h)).xxx;
-  vector<float16_t, 3> v = arg_0;
-  vector<float16_t, 3> res = (((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 3> res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 vector<float16_t, 3> trunc_103ab8() {
   vector<float16_t, 3> arg_0 = (float16_t(1.5h)).xxx;
-  vector<float16_t, 3> v = arg_0;
-  vector<float16_t, 3> res = (((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 3> res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 vector<float16_t, 3> trunc_103ab8() {
   vector<float16_t, 3> arg_0 = (float16_t(1.5h)).xxx;
-  vector<float16_t, 3> v = arg_0;
-  vector<float16_t, 3> res = (((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 3> res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_103ab8();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_103ab8();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 ab1e6ef..a0d29be 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float3 trunc_562d05() {
   float3 arg_0 = (1.5f).xxx;
-  float3 v = arg_0;
-  float3 res = (((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v)));
+  float3 res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float3 trunc_562d05() {
   float3 arg_0 = (1.5f).xxx;
-  float3 v = arg_0;
-  float3 res = (((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v)));
+  float3 res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 float3 trunc_562d05() {
   float3 arg_0 = (1.5f).xxx;
-  float3 v = arg_0;
-  float3 res = (((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v)));
+  float3 res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_562d05();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_562d05();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 adcd3a8..5044168 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 vector<float16_t, 2> trunc_a56109() {
   vector<float16_t, 2> arg_0 = (float16_t(1.5h)).xx;
-  vector<float16_t, 2> v = arg_0;
-  vector<float16_t, 2> res = (((v < (float16_t(0.0h)).xx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 2> res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 vector<float16_t, 2> trunc_a56109() {
   vector<float16_t, 2> arg_0 = (float16_t(1.5h)).xx;
-  vector<float16_t, 2> v = arg_0;
-  vector<float16_t, 2> res = (((v < (float16_t(0.0h)).xx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 2> res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 vector<float16_t, 2> trunc_a56109() {
   vector<float16_t, 2> arg_0 = (float16_t(1.5h)).xx;
-  vector<float16_t, 2> v = arg_0;
-  vector<float16_t, 2> res = (((v < (float16_t(0.0h)).xx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 2> res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_a56109();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_a56109();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 518af78..a9deb0f 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float16_t trunc_cc2b0d() {
   float16_t arg_0 = float16_t(1.5h);
-  float16_t v = arg_0;
-  float16_t res = (((v < float16_t(0.0h))) ? (ceil(v)) : (floor(v)));
+  float16_t res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float16_t trunc_cc2b0d() {
   float16_t arg_0 = float16_t(1.5h);
-  float16_t v = arg_0;
-  float16_t res = (((v < float16_t(0.0h))) ? (ceil(v)) : (floor(v)));
+  float16_t res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 float16_t trunc_cc2b0d() {
   float16_t arg_0 = float16_t(1.5h);
-  float16_t v = arg_0;
-  float16_t res = (((v < float16_t(0.0h))) ? (ceil(v)) : (floor(v)));
+  float16_t res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_cc2b0d();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_cc2b0d();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 4577933..3693a12 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 vector<float16_t, 4> trunc_ce7c17() {
   vector<float16_t, 4> arg_0 = (float16_t(1.5h)).xxxx;
-  vector<float16_t, 4> v = arg_0;
-  vector<float16_t, 4> res = (((v < (float16_t(0.0h)).xxxx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 4> res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 vector<float16_t, 4> trunc_ce7c17() {
   vector<float16_t, 4> arg_0 = (float16_t(1.5h)).xxxx;
-  vector<float16_t, 4> v = arg_0;
-  vector<float16_t, 4> res = (((v < (float16_t(0.0h)).xxxx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 4> res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 vector<float16_t, 4> trunc_ce7c17() {
   vector<float16_t, 4> arg_0 = (float16_t(1.5h)).xxxx;
-  vector<float16_t, 4> v = arg_0;
-  vector<float16_t, 4> res = (((v < (float16_t(0.0h)).xxxx)) ? (ceil(v)) : (floor(v)));
+  vector<float16_t, 4> res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_ce7c17();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_ce7c17();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 d0e48df..b71d261 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float4 trunc_e183aa() {
   float4 arg_0 = (1.5f).xxxx;
-  float4 v = arg_0;
-  float4 res = (((v < (0.0f).xxxx)) ? (ceil(v)) : (floor(v)));
+  float4 res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float4 trunc_e183aa() {
   float4 arg_0 = (1.5f).xxxx;
-  float4 v = arg_0;
-  float4 res = (((v < (0.0f).xxxx)) ? (ceil(v)) : (floor(v)));
+  float4 res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 float4 trunc_e183aa() {
   float4 arg_0 = (1.5f).xxxx;
-  float4 v = arg_0;
-  float4 res = (((v < (0.0f).xxxx)) ? (ceil(v)) : (floor(v)));
+  float4 res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_e183aa();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_e183aa();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 df01189..4461198 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float trunc_eb83df() {
   float arg_0 = 1.5f;
-  float v = arg_0;
-  float res = (((v < 0.0f)) ? (ceil(v)) : (floor(v)));
+  float res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float trunc_eb83df() {
   float arg_0 = 1.5f;
-  float v = arg_0;
-  float res = (((v < 0.0f)) ? (ceil(v)) : (floor(v)));
+  float res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 float trunc_eb83df() {
   float arg_0 = 1.5f;
-  float v = arg_0;
-  float res = (((v < 0.0f)) ? (ceil(v)) : (floor(v)));
+  float res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_eb83df();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_eb83df();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 8933c21..f20fe28 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
@@ -5,8 +5,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float2 trunc_f370d3() {
   float2 arg_0 = (1.5f).xx;
-  float2 v = arg_0;
-  float2 res = (((v < (0.0f).xx)) ? (ceil(v)) : (floor(v)));
+  float2 res = trunc(arg_0);
   return res;
 }
 
@@ -21,8 +20,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 float2 trunc_f370d3() {
   float2 arg_0 = (1.5f).xx;
-  float2 v = arg_0;
-  float2 res = (((v < (0.0f).xx)) ? (ceil(v)) : (floor(v)));
+  float2 res = trunc(arg_0);
   return res;
 }
 
@@ -47,22 +45,21 @@
 
 float2 trunc_f370d3() {
   float2 arg_0 = (1.5f).xx;
-  float2 v = arg_0;
-  float2 res = (((v < (0.0f).xx)) ? (ceil(v)) : (floor(v)));
+  float2 res = trunc(arg_0);
   return res;
 }
 
 VertexOutput vertex_main_inner() {
-  VertexOutput v_1 = (VertexOutput)0;
-  v_1.pos = (0.0f).xxxx;
-  v_1.prevent_dce = trunc_f370d3();
-  VertexOutput v_2 = v_1;
-  return v_2;
+  VertexOutput v = (VertexOutput)0;
+  v.pos = (0.0f).xxxx;
+  v.prevent_dce = trunc_f370d3();
+  VertexOutput v_1 = v;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
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 0375cc8..3f1c083 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
@@ -4,6 +4,6 @@
   float16_t a = float16_t(1.0h);
   float16_t b = float16_t(2.0h);
   float16_t v = (a / b);
-  float16_t r = (a - ((((v < float16_t(0.0h))) ? (ceil(v)) : (floor(v))) * b));
+  float16_t r = (a - (trunc(v) * b));
 }
 
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 1be3b5d..dc7ec1d 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
@@ -4,6 +4,6 @@
   float a = 1.0f;
   float b = 2.0f;
   float v = (a / b);
-  float r = (a - ((((v < 0.0f)) ? (ceil(v)) : (floor(v))) * b));
+  float r = (a - (trunc(v) * b));
 }
 
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 f4f9781..57c9b99 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
@@ -4,6 +4,6 @@
   float16_t a = float16_t(4.0h);
   vector<float16_t, 3> b = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
   vector<float16_t, 3> v = (a / b);
-  vector<float16_t, 3> r = (a - ((((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  vector<float16_t, 3> r = (a - (trunc(v) * b));
 }
 
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 0a76ed1..2de5827 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
@@ -4,6 +4,6 @@
   float a = 4.0f;
   float3 b = float3(1.0f, 2.0f, 3.0f);
   float3 v = (a / b);
-  float3 r = (a - ((((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  float3 r = (a - (trunc(v) * b));
 }
 
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 df64e59..0cb1af9 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
@@ -4,6 +4,6 @@
   vector<float16_t, 3> a = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
   float16_t b = float16_t(4.0h);
   vector<float16_t, 3> v = (a / b);
-  vector<float16_t, 3> r = (a - ((((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  vector<float16_t, 3> r = (a - (trunc(v) * b));
 }
 
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 1a144aac..1af8956 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
@@ -4,6 +4,6 @@
   float3 a = float3(1.0f, 2.0f, 3.0f);
   float b = 4.0f;
   float3 v = (a / b);
-  float3 r = (a - ((((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  float3 r = (a - (trunc(v) * b));
 }
 
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 d6cc966..0111e8f 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
@@ -4,6 +4,6 @@
   vector<float16_t, 3> a = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
   vector<float16_t, 3> b = vector<float16_t, 3>(float16_t(4.0h), float16_t(5.0h), float16_t(6.0h));
   vector<float16_t, 3> v = (a / b);
-  vector<float16_t, 3> r = (a - ((((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  vector<float16_t, 3> r = (a - (trunc(v) * b));
 }
 
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 cea9617..b9b9201 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
@@ -4,6 +4,6 @@
   float3 a = float3(1.0f, 2.0f, 3.0f);
   float3 b = float3(4.0f, 5.0f, 6.0f);
   float3 v = (a / b);
-  float3 r = (a - ((((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  float3 r = (a - (trunc(v) * b));
 }
 
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 8d3a714..19af3f9 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
@@ -4,6 +4,6 @@
   float16_t a = float16_t(1.0h);
   float16_t b = float16_t(0.0h);
   float16_t v = (a / b);
-  float16_t r = (a - ((((v < float16_t(0.0h))) ? (ceil(v)) : (floor(v))) * b));
+  float16_t r = (a - (trunc(v) * b));
 }
 
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 50356c0..0c74815 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
@@ -4,6 +4,6 @@
   float a = 1.0f;
   float b = 0.0f;
   float v = (a / b);
-  float r = (a - ((((v < 0.0f)) ? (ceil(v)) : (floor(v))) * b));
+  float r = (a - (trunc(v) * b));
 }
 
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 4e12273..a9ed3c0 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
@@ -4,6 +4,6 @@
   vector<float16_t, 3> a = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
   vector<float16_t, 3> b = vector<float16_t, 3>(float16_t(0.0h), float16_t(5.0h), float16_t(0.0h));
   vector<float16_t, 3> v = (a / b);
-  vector<float16_t, 3> r = (a - ((((v < (float16_t(0.0h)).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  vector<float16_t, 3> r = (a - (trunc(v) * b));
 }
 
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 b2b1c4a..3c95d08 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
@@ -4,6 +4,6 @@
   float3 a = float3(1.0f, 2.0f, 3.0f);
   float3 b = float3(0.0f, 5.0f, 0.0f);
   float3 v = (a / b);
-  float3 r = (a - ((((v < (0.0f).xxx)) ? (ceil(v)) : (floor(v))) * b));
+  float3 r = (a - (trunc(v) * b));
 }
 
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 65b5ad2..494848c 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
@@ -6,6 +6,6 @@
   float16_t v = a;
   float16_t v_1 = (b + b);
   float16_t v_2 = (v / v_1);
-  float16_t r = (v - ((((v_2 < float16_t(0.0h))) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float16_t r = (v - (trunc(v_2) * v_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 1293614..a99475a 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
@@ -6,6 +6,6 @@
   float v = a;
   float v_1 = (b + b);
   float v_2 = (v / v_1);
-  float r = (v - ((((v_2 < 0.0f)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float r = (v - (trunc(v_2) * v_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 7a16bc0..c6753bc 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
@@ -6,6 +6,6 @@
   vector<float16_t, 3> v = a;
   vector<float16_t, 3> v_1 = (b + b);
   vector<float16_t, 3> v_2 = (v / v_1);
-  vector<float16_t, 3> r = (v - ((((v_2 < (float16_t(0.0h)).xxx)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  vector<float16_t, 3> r = (v - (trunc(v_2) * v_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 b27930c..76efd31 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
@@ -6,6 +6,6 @@
   float3 v = a;
   float3 v_1 = (b + b);
   float3 v_2 = (v / v_1);
-  float3 r = (v - ((((v_2 < (0.0f).xxx)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float3 r = (v - (trunc(v_2) * v_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 42ad066..f31694c 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
@@ -6,6 +6,6 @@
   float16_t v = a;
   float16_t v_1 = b;
   float16_t v_2 = (v / v_1);
-  float16_t r = (v - ((((v_2 < float16_t(0.0h))) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float16_t r = (v - (trunc(v_2) * v_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 f1c6c21..e7d0cbf 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
@@ -6,6 +6,6 @@
   float v = a;
   float v_1 = b;
   float v_2 = (v / v_1);
-  float r = (v - ((((v_2 < 0.0f)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float r = (v - (trunc(v_2) * v_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 6ef55ee..1c10a01 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
@@ -6,6 +6,6 @@
   vector<float16_t, 3> v = a;
   vector<float16_t, 3> v_1 = b;
   vector<float16_t, 3> v_2 = (v / v_1);
-  vector<float16_t, 3> r = (v - ((((v_2 < (float16_t(0.0h)).xxx)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  vector<float16_t, 3> r = (v - (trunc(v_2) * v_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 9f88092..d6e71b0 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
@@ -6,6 +6,6 @@
   float3 v = a;
   float3 v_1 = b;
   float3 v_2 = (v / v_1);
-  float3 r = (v - ((((v_2 < (0.0f).xxx)) ? (ceil(v_2)) : (floor(v_2))) * v_1));
+  float3 r = (v - (trunc(v_2) * v_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 4995ab1..6d23355 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
@@ -16,13 +16,13 @@
   b = (b / 0.0f);
   float v_1 = b;
   float v_2 = (v_1 / 0.0f);
-  b = (v_1 - ((((v_2 < 0.0f)) ? (ceil(v_2)) : (floor(v_2))) * 0.0f));
+  b = (v_1 - (trunc(v_2) * 0.0f));
   float v_3 = b;
   b = (v_3 / float(maybe_zero));
   float v_4 = b;
   float v_5 = float(maybe_zero);
   float v_6 = (v_4 / v_5);
-  b = (v_4 - ((((v_6 < 0.0f)) ? (ceil(v_6)) : (floor(v_6))) * v_5));
+  b = (v_4 - (trunc(v_6) * v_5));
 }
 
 [numthreads(1, 1, 1)]