tint: add precise float mod polyfill and enable it for HLSL
HLSL's % operator results in less precise results than expected.
Bug: tint:1799
Change-Id: I1a9572288a0e536f0fc9c0748a25dcf58551e57b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/119760
Kokoro: Kokoro <noreply+kokoro@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index 5baef8a..e140fb3 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -808,6 +808,58 @@
return b.Call(fn, lhs, rhs);
}
+ /// Builds the polyfill inline expression for a precise float modulo, as defined in the spec.
+ /// @param bin_op the original BinaryExpression
+ /// @return the polyfill divide or modulo
+ const ast::Expression* PreciseFloatMod(const ast::BinaryExpression* bin_op) {
+ auto* lhs_ty = ctx.src->TypeOf(bin_op->lhs)->UnwrapRef();
+ auto* rhs_ty = ctx.src->TypeOf(bin_op->rhs)->UnwrapRef();
+ BinaryOpSignature sig{bin_op->op, lhs_ty, rhs_ty};
+ auto fn = binary_op_polyfills.GetOrCreate(sig, [&] {
+ uint32_t lhs_width = 1;
+ uint32_t rhs_width = 1;
+ const auto* lhs_el_ty = type::Type::ElementOf(lhs_ty, &lhs_width);
+ const auto* rhs_el_ty = type::Type::ElementOf(rhs_ty, &rhs_width);
+
+ const uint32_t width = std::max(lhs_width, rhs_width);
+
+ const char* lhs = "lhs";
+ const char* rhs = "rhs";
+
+ utils::Vector<const ast::Statement*, 4> body;
+
+ if (lhs_width < width) {
+ // lhs is scalar, rhs is vector. Convert lhs to vector.
+ body.Push(b.Decl(b.Let("l", b.vec(T(lhs_el_ty), width, b.Expr(lhs)))));
+ lhs = "l";
+ }
+ if (rhs_width < width) {
+ // lhs is vector, rhs is scalar. Convert rhs to vector.
+ body.Push(b.Decl(b.Let("r", b.vec(T(rhs_el_ty), width, b.Expr(rhs)))));
+ rhs = "r";
+ }
+
+ auto name = b.Symbols().New("tint_float_mod");
+
+ // lhs - trunc(lhs / rhs) * rhs
+ auto* precise_mod = b.Sub(lhs, b.Mul(b.Call("trunc", b.Div(lhs, rhs)), rhs));
+ body.Push(b.Return(precise_mod));
+
+ b.Func(name,
+ utils::Vector{
+ b.Param("lhs", T(lhs_ty)),
+ b.Param("rhs", T(rhs_ty)),
+ },
+ width == 1 ? T(lhs_ty) : b.ty.vec(T(lhs_el_ty), width), // return type
+ std::move(body));
+
+ return name;
+ });
+ auto* lhs = ctx.Clone(bin_op->lhs);
+ auto* rhs = ctx.Clone(bin_op->rhs);
+ return b.Call(fn, lhs, rhs);
+ }
+
private:
/// The clone context
CloneContext& ctx;
@@ -1052,7 +1104,16 @@
}
break;
}
- case ast::BinaryOp::kDivide:
+ case ast::BinaryOp::kDivide: {
+ if (polyfill.int_div_mod) {
+ auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
+ if (lhs_ty->is_integer_scalar_or_vector()) {
+ ctx.Replace(bin_op, [bin_op, &s] { return s.IntDivMod(bin_op); });
+ made_changes = true;
+ }
+ }
+ break;
+ }
case ast::BinaryOp::kModulo: {
if (polyfill.int_div_mod) {
auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
@@ -1061,6 +1122,14 @@
made_changes = true;
}
}
+ if (polyfill.precise_float_mod) {
+ auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
+ if (lhs_ty->is_float_scalar_or_vector()) {
+ ctx.Replace(bin_op,
+ [bin_op, &s] { return s.PreciseFloatMod(bin_op); });
+ made_changes = true;
+ }
+ }
break;
}
default:
diff --git a/src/tint/transform/builtin_polyfill.h b/src/tint/transform/builtin_polyfill.h
index ae5f588..521940c 100644
--- a/src/tint/transform/builtin_polyfill.h
+++ b/src/tint/transform/builtin_polyfill.h
@@ -68,6 +68,8 @@
/// Should integer scalar / vector divides and modulos be polyfilled to avoid DBZ and
/// integer overflows?
bool int_div_mod = false;
+ /// Should float modulos be polyfilled to emit a precise modulo operation as per the spec?
+ bool precise_float_mod = false;
/// Should `saturate()` be polyfilled?
bool saturate = false;
/// Should `sign()` be polyfilled for integer types?
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index 65365bb..688d95e5 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -2005,6 +2005,232 @@
}
////////////////////////////////////////////////////////////////////////////////
+// precise_float_mod
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillPreciseFloatMod() {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.precise_float_mod = true;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunPreciseFloatMod) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = 20f % v;
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillPreciseFloatMod()));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_af_f32) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = 20.0 % v;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : f32, rhs : f32) -> f32 {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
+fn f() {
+ let v = 10.0f;
+ let x = tint_float_mod(20.0, v);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_f32_af) {
+ auto* src = R"(
+fn f() {
+ let v = 10.0;
+ let x = 20f % v;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : f32, rhs : f32) -> f32 {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
+fn f() {
+ let v = 10.0;
+ let x = tint_float_mod(20.0f, v);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_f32_f32) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = 20f % v;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : f32, rhs : f32) -> f32 {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
+fn f() {
+ let v = 10.0f;
+ let x = tint_float_mod(20.0f, v);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_Overloads) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = 20f % v;
+ let w = 10i;
+ let y = 20i % w;
+ let u = 10u;
+ let z = 20u % u;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : f32, rhs : f32) -> f32 {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
+fn f() {
+ let v = 10.0f;
+ let x = tint_float_mod(20.0f, v);
+ let w = 10i;
+ let y = (20i % w);
+ let u = 10u;
+ let z = (20u % u);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_vec3_af_f32) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = vec3(20.0) % v;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : vec3<f32>, rhs : f32) -> vec3<f32> {
+ let r = vec3<f32>(rhs);
+ return (lhs - (trunc((lhs / r)) * r));
+}
+
+fn f() {
+ let v = 10.0f;
+ let x = tint_float_mod(vec3(20.0), v);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_vec3_f32_af) {
+ auto* src = R"(
+fn f() {
+ let v = 10.0;
+ let x = vec3(20f) % v;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : vec3<f32>, rhs : f32) -> vec3<f32> {
+ let r = vec3<f32>(rhs);
+ return (lhs - (trunc((lhs / r)) * r));
+}
+
+fn f() {
+ let v = 10.0;
+ let x = tint_float_mod(vec3(20.0f), v);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_vec3_f32_f32) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = vec3(20f) % v;
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : vec3<f32>, rhs : f32) -> vec3<f32> {
+ let r = vec3<f32>(rhs);
+ return (lhs - (trunc((lhs / r)) * r));
+}
+
+fn f() {
+ let v = 10.0f;
+ let x = tint_float_mod(vec3(20.0f), v);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, PreciseFloatMod_vec3_f32_vec3_f32) {
+ auto* src = R"(
+fn f() {
+ let v = 10f;
+ let x = vec3<f32>(20f) % vec3<f32>(v);
+}
+)";
+
+ auto* expect = R"(
+fn tint_float_mod(lhs : vec3<f32>, rhs : vec3<f32>) -> vec3<f32> {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
+fn f() {
+ let v = 10.0f;
+ let x = tint_float_mod(vec3<f32>(20.0f), vec3<f32>(v));
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillPreciseFloatMod());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+////////////////////////////////////////////////////////////////////////////////
// int_div_mod
////////////////////////////////////////////////////////////////////////////////
DataMap polyfillIntDivMod() {
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 0f8fdb1..4e37faa 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -180,6 +180,7 @@
polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kFull;
polyfills.int_div_mod = true;
+ polyfills.precise_float_mod = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
diff --git a/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
index c926578..306658c 100644
--- a/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.dxc.hlsl
@@ -33,6 +33,10 @@
return float4x4(float4(x_40.x, x_40.y, x_40.z, x_40.w), float4(x_47.x, x_47.y, x_47.z, x_47.w), float4(x_54.x, x_54.y, x_54.z, x_54.w), (0.0f).xxxx);
}
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
void main_1() {
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
float2 tileUV = float2(0.0f, 0.0f);
@@ -100,7 +104,7 @@
if ((x_174 > 0.0f)) {
const float x_181 = asfloat(x_20[0].x);
const float x_184 = animationData.z;
- mt = ((x_181 * x_184) % 1.0f);
+ mt = tint_float_mod((x_181 * x_184), 1.0f);
f = 0.0f;
while (true) {
const float x_193 = f;
diff --git a/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl
index c926578..306658c 100644
--- a/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.fxc.hlsl
@@ -33,6 +33,10 @@
return float4x4(float4(x_40.x, x_40.y, x_40.z, x_40.w), float4(x_47.x, x_47.y, x_47.z, x_47.w), float4(x_54.x, x_54.y, x_54.z, x_54.w), (0.0f).xxxx);
}
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
void main_1() {
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
float2 tileUV = float2(0.0f, 0.0f);
@@ -100,7 +104,7 @@
if ((x_174 > 0.0f)) {
const float x_181 = asfloat(x_20[0].x);
const float x_184 = animationData.z;
- mt = ((x_181 * x_184) % 1.0f);
+ mt = tint_float_mod((x_181 * x_184), 1.0f);
f = 0.0f;
while (true) {
const float x_193 = f;
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 9ce6ac8..ad0a421 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,7 +1,11 @@
+float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float16_t a = float16_t(1.0h);
const float16_t b = float16_t(2.0h);
- const float16_t r = (a % b);
+ const float16_t r = tint_float_mod(a, b);
return;
}
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 7e166b7..0c9eb2e 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float a = 1.0f;
const float b = 2.0f;
- const float r = (a % b);
+ const float r = tint_float_mod(a, b);
return;
}
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 7e166b7..0c9eb2e 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float a = 1.0f;
const float b = 2.0f;
- const float r = (a % b);
+ const float r = tint_float_mod(a, b);
return;
}
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 5b7fdbe..99ffb58 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,7 +1,12 @@
+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));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float16_t a = float16_t(4.0h);
const vector<float16_t, 3> b = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
- const vector<float16_t, 3> r = (a % b);
+ const vector<float16_t, 3> r = tint_float_mod(a, b);
return;
}
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 b2653df..c864275 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,7 +1,12 @@
+float3 tint_float_mod(float lhs, float3 rhs) {
+ const float3 l = float3((lhs).xxx);
+ return (l - (trunc((l / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float a = 4.0f;
const float3 b = float3(1.0f, 2.0f, 3.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 b2653df..c864275 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,7 +1,12 @@
+float3 tint_float_mod(float lhs, float3 rhs) {
+ const float3 l = float3((lhs).xxx);
+ return (l - (trunc((l / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float a = 4.0f;
const float3 b = float3(1.0f, 2.0f, 3.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 4c54522..a8976e9 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,7 +1,12 @@
+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));
+}
+
[numthreads(1, 1, 1)]
void f() {
const vector<float16_t, 3> a = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
const float16_t b = float16_t(4.0h);
- const vector<float16_t, 3> r = (a % b);
+ const vector<float16_t, 3> r = tint_float_mod(a, b);
return;
}
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 147b45c..c61e266 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,7 +1,12 @@
+float3 tint_float_mod(float3 lhs, float rhs) {
+ const float3 r = float3((rhs).xxx);
+ return (lhs - (trunc((lhs / r)) * r));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float3 a = float3(1.0f, 2.0f, 3.0f);
const float b = 4.0f;
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 147b45c..c61e266 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,7 +1,12 @@
+float3 tint_float_mod(float3 lhs, float rhs) {
+ const float3 r = float3((rhs).xxx);
+ return (lhs - (trunc((lhs / r)) * r));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float3 a = float3(1.0f, 2.0f, 3.0f);
const float b = 4.0f;
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 69def79..69ff97a 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,7 +1,11 @@
+vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const vector<float16_t, 3> a = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
const vector<float16_t, 3> b = vector<float16_t, 3>(float16_t(4.0h), float16_t(5.0h), float16_t(6.0h));
- const vector<float16_t, 3> r = (a % b);
+ const vector<float16_t, 3> r = tint_float_mod(a, b);
return;
}
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 87e4dd4..b03e6c8 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float3 a = float3(1.0f, 2.0f, 3.0f);
const float3 b = float3(4.0f, 5.0f, 6.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 87e4dd4..b03e6c8 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float3 a = float3(1.0f, 2.0f, 3.0f);
const float3 b = float3(4.0f, 5.0f, 6.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 87f2c8f..45c8ee1 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,7 +1,11 @@
+float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float16_t a = float16_t(1.0h);
const float16_t b = float16_t(0.0h);
- const float16_t r = (a % b);
+ const float16_t r = tint_float_mod(a, b);
return;
}
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 80448b1..515bcfb 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float a = 1.0f;
const float b = 0.0f;
- const float r = (a % b);
+ const float r = tint_float_mod(a, b);
return;
}
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 80448b1..515bcfb 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float a = 1.0f;
const float b = 0.0f;
- const float r = (a % b);
+ const float r = tint_float_mod(a, b);
return;
}
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 8c6cb4c..8e4d644 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,7 +1,11 @@
+vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const vector<float16_t, 3> a = vector<float16_t, 3>(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h));
const vector<float16_t, 3> b = vector<float16_t, 3>(float16_t(0.0h), float16_t(5.0h), float16_t(0.0h));
- const vector<float16_t, 3> r = (a % b);
+ const vector<float16_t, 3> r = tint_float_mod(a, b);
return;
}
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 5ea2fbd..0cd0191 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float3 a = float3(1.0f, 2.0f, 3.0f);
const float3 b = float3(0.0f, 5.0f, 0.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 5ea2fbd..0cd0191 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
const float3 a = float3(1.0f, 2.0f, 3.0f);
const float3 b = float3(0.0f, 5.0f, 0.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 9dd48b3..649bbd2 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,7 +1,11 @@
+float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float16_t a = float16_t(1.0h);
float16_t b = float16_t(0.0h);
- const float16_t r = (a % (b + b));
+ const float16_t r = tint_float_mod(a, (b + b));
return;
}
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 468c33d..6af8624 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float a = 1.0f;
float b = 0.0f;
- const float r = (a % (b + b));
+ const float r = tint_float_mod(a, (b + b));
return;
}
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 468c33d..6af8624 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float a = 1.0f;
float b = 0.0f;
- const float r = (a % (b + b));
+ const float r = tint_float_mod(a, (b + b));
return;
}
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 2f75bb3..dfe3a63 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,7 +1,11 @@
+vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
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));
- const vector<float16_t, 3> r = (a % (b + b));
+ const vector<float16_t, 3> r = tint_float_mod(a, (b + b));
return;
}
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 8d21550..ff6fdd4 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float3 a = float3(1.0f, 2.0f, 3.0f);
float3 b = float3(0.0f, 5.0f, 0.0f);
- const float3 r = (a % (b + b));
+ const float3 r = tint_float_mod(a, (b + b));
return;
}
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 8d21550..ff6fdd4 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float3 a = float3(1.0f, 2.0f, 3.0f);
float3 b = float3(0.0f, 5.0f, 0.0f);
- const float3 r = (a % (b + b));
+ const float3 r = tint_float_mod(a, (b + b));
return;
}
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 18770f0..7ee2e0b 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,7 +1,11 @@
+float16_t tint_float_mod(float16_t lhs, float16_t rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float16_t a = float16_t(1.0h);
float16_t b = float16_t(0.0h);
- const float16_t r = (a % b);
+ const float16_t r = tint_float_mod(a, b);
return;
}
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 3d43aff..0fc0aef 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float a = 1.0f;
float b = 0.0f;
- const float r = (a % b);
+ const float r = tint_float_mod(a, b);
return;
}
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 3d43aff..0fc0aef 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,7 +1,11 @@
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float a = 1.0f;
float b = 0.0f;
- const float r = (a % b);
+ const float r = tint_float_mod(a, b);
return;
}
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 d79d88c..4c47f3b 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,7 +1,11 @@
+vector<float16_t, 3> tint_float_mod(vector<float16_t, 3> lhs, vector<float16_t, 3> rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
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));
- const vector<float16_t, 3> r = (a % b);
+ const vector<float16_t, 3> r = tint_float_mod(a, b);
return;
}
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 636719b..f6fdd4c 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float3 a = float3(1.0f, 2.0f, 3.0f);
float3 b = float3(0.0f, 5.0f, 0.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 636719b..f6fdd4c 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,7 +1,11 @@
+float3 tint_float_mod(float3 lhs, float3 rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
[numthreads(1, 1, 1)]
void f() {
float3 a = float3(1.0f, 2.0f, 3.0f);
float3 b = float3(0.0f, 5.0f, 0.0f);
- const float3 r = (a % b);
+ const float3 r = tint_float_mod(a, b);
return;
}
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 ab7448d..314a630 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
@@ -19,13 +19,17 @@
}
}
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
void foo(int maybe_zero) {
a = tint_div(a, 0);
a = tint_mod(a, 0);
a = tint_div(a, maybe_zero);
a = tint_mod(a, maybe_zero);
b = (b / 0.0f);
- b = (b % 0.0f);
+ b = tint_float_mod(b, 0.0f);
b = (b / float(maybe_zero));
- b = (b % float(maybe_zero));
+ b = tint_float_mod(b, float(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 ab7448d..314a630 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
@@ -19,13 +19,17 @@
}
}
+float tint_float_mod(float lhs, float rhs) {
+ return (lhs - (trunc((lhs / rhs)) * rhs));
+}
+
void foo(int maybe_zero) {
a = tint_div(a, 0);
a = tint_mod(a, 0);
a = tint_div(a, maybe_zero);
a = tint_mod(a, maybe_zero);
b = (b / 0.0f);
- b = (b % 0.0f);
+ b = tint_float_mod(b, 0.0f);
b = (b / float(maybe_zero));
- b = (b % float(maybe_zero));
+ b = tint_float_mod(b, float(maybe_zero));
}