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>
This commit is contained in:
Antonio Maiorano 2023-02-14 16:12:59 +00:00 committed by Dawn LUCI CQ
parent b31e0e2aca
commit ee665a4240
38 changed files with 477 additions and 37 deletions

View File

@ -808,6 +808,58 @@ struct BuiltinPolyfill::State {
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 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
}
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 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src,
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:

View File

@ -68,6 +68,8 @@ class BuiltinPolyfill final : public Castable<BuiltinPolyfill, Transform> {
/// 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?

View File

@ -2004,6 +2004,232 @@ fn f() {
EXPECT_EQ(expect, str(got));
}
////////////////////////////////////////////////////////////////////////////////
// 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
////////////////////////////////////////////////////////////////////////////////

View File

@ -180,6 +180,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
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);

View File

@ -33,6 +33,10 @@ float4x4 getFrameData_f1_(inout float frameID) {
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 @@ void main_1() {
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;

View File

@ -33,6 +33,10 @@ float4x4 getFrameData_f1_(inout float frameID) {
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 @@ void main_1() {
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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -19,13 +19,17 @@ int tint_mod(int lhs, int rhs) {
}
}
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));
}

View File

@ -19,13 +19,17 @@ int tint_mod(int lhs, int rhs) {
}
}
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));
}